Home | History | Annotate | Download | only in moment
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package org.apache.commons.math.stat.descriptive.moment;
     18 
     19 import java.io.Serializable;
     20 import java.util.Arrays;
     21 
     22 import org.apache.commons.math.DimensionMismatchException;
     23 import org.apache.commons.math.linear.MatrixUtils;
     24 import org.apache.commons.math.linear.RealMatrix;
     25 
     26 /**
     27  * Returns the covariance matrix of the available vectors.
     28  * @since 1.2
     29  * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $
     30  */
     31 public class VectorialCovariance implements Serializable {
     32 
     33     /** Serializable version identifier */
     34     private static final long serialVersionUID = 4118372414238930270L;
     35 
     36     /** Sums for each component. */
     37     private final double[] sums;
     38 
     39     /** Sums of products for each component. */
     40     private final double[] productsSums;
     41 
     42     /** Indicator for bias correction. */
     43     private final boolean isBiasCorrected;
     44 
     45     /** Number of vectors in the sample. */
     46     private long n;
     47 
     48     /** Constructs a VectorialCovariance.
     49      * @param dimension vectors dimension
     50      * @param isBiasCorrected if true, computed the unbiased sample covariance,
     51      * otherwise computes the biased population covariance
     52      */
     53     public VectorialCovariance(int dimension, boolean isBiasCorrected) {
     54         sums         = new double[dimension];
     55         productsSums = new double[dimension * (dimension + 1) / 2];
     56         n            = 0;
     57         this.isBiasCorrected = isBiasCorrected;
     58     }
     59 
     60     /**
     61      * Add a new vector to the sample.
     62      * @param v vector to add
     63      * @exception DimensionMismatchException if the vector does not have the right dimension
     64      */
     65     public void increment(double[] v) throws DimensionMismatchException {
     66         if (v.length != sums.length) {
     67             throw new DimensionMismatchException(v.length, sums.length);
     68         }
     69         int k = 0;
     70         for (int i = 0; i < v.length; ++i) {
     71             sums[i] += v[i];
     72             for (int j = 0; j <= i; ++j) {
     73                 productsSums[k++] += v[i] * v[j];
     74             }
     75         }
     76         n++;
     77     }
     78 
     79     /**
     80      * Get the covariance matrix.
     81      * @return covariance matrix
     82      */
     83     public RealMatrix getResult() {
     84 
     85         int dimension = sums.length;
     86         RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension);
     87 
     88         if (n > 1) {
     89             double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n));
     90             int k = 0;
     91             for (int i = 0; i < dimension; ++i) {
     92                 for (int j = 0; j <= i; ++j) {
     93                     double e = c * (n * productsSums[k++] - sums[i] * sums[j]);
     94                     result.setEntry(i, j, e);
     95                     result.setEntry(j, i, e);
     96                 }
     97             }
     98         }
     99 
    100         return result;
    101 
    102     }
    103 
    104     /**
    105      * Get the number of vectors in the sample.
    106      * @return number of vectors in the sample
    107      */
    108     public long getN() {
    109         return n;
    110     }
    111 
    112     /**
    113      * Clears the internal state of the Statistic
    114      */
    115     public void clear() {
    116         n = 0;
    117         Arrays.fill(sums, 0.0);
    118         Arrays.fill(productsSums, 0.0);
    119     }
    120 
    121     /** {@inheritDoc} */
    122     @Override
    123     public int hashCode() {
    124         final int prime = 31;
    125         int result = 1;
    126         result = prime * result + (isBiasCorrected ? 1231 : 1237);
    127         result = prime * result + (int) (n ^ (n >>> 32));
    128         result = prime * result + Arrays.hashCode(productsSums);
    129         result = prime * result + Arrays.hashCode(sums);
    130         return result;
    131     }
    132 
    133     /** {@inheritDoc} */
    134     @Override
    135     public boolean equals(Object obj) {
    136         if (this == obj)
    137             return true;
    138         if (!(obj instanceof VectorialCovariance))
    139             return false;
    140         VectorialCovariance other = (VectorialCovariance) obj;
    141         if (isBiasCorrected != other.isBiasCorrected)
    142             return false;
    143         if (n != other.n)
    144             return false;
    145         if (!Arrays.equals(productsSums, other.productsSums))
    146             return false;
    147         if (!Arrays.equals(sums, other.sums))
    148             return false;
    149         return true;
    150     }
    151 
    152 }
    153