VectorialCovariance.java

  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.math4.legacy.stat.descriptive.moment;

  18. import java.util.Arrays;

  19. import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
  20. import org.apache.commons.math4.legacy.linear.MatrixUtils;
  21. import org.apache.commons.math4.legacy.linear.RealMatrix;

  22. /**
  23.  * Returns the covariance matrix of the available vectors.
  24.  * @since 1.2
  25.  */
  26. public class VectorialCovariance {
  27.     /** Sums for each component. */
  28.     private final double[] sums;

  29.     /** Sums of products for each component. */
  30.     private final double[] productsSums;

  31.     /** Indicator for bias correction. */
  32.     private final boolean isBiasCorrected;

  33.     /** Number of vectors in the sample. */
  34.     private long n;

  35.     /** Constructs a VectorialCovariance.
  36.      * @param dimension vectors dimension
  37.      * @param isBiasCorrected if true, computed the unbiased sample covariance,
  38.      * otherwise computes the biased population covariance
  39.      */
  40.     public VectorialCovariance(int dimension, boolean isBiasCorrected) {
  41.         sums         = new double[dimension];
  42.         productsSums = new double[dimension * (dimension + 1) / 2];
  43.         n            = 0;
  44.         this.isBiasCorrected = isBiasCorrected;
  45.     }

  46.     /**
  47.      * Add a new vector to the sample.
  48.      * @param v vector to add
  49.      * @throws DimensionMismatchException if the vector does not have the right dimension
  50.      */
  51.     public void increment(double[] v) throws DimensionMismatchException {
  52.         if (v.length != sums.length) {
  53.             throw new DimensionMismatchException(v.length, sums.length);
  54.         }
  55.         int k = 0;
  56.         for (int i = 0; i < v.length; ++i) {
  57.             sums[i] += v[i];
  58.             for (int j = 0; j <= i; ++j) {
  59.                 productsSums[k++] += v[i] * v[j];
  60.             }
  61.         }
  62.         n++;
  63.     }

  64.     /**
  65.      * Get the covariance matrix.
  66.      * @return covariance matrix
  67.      */
  68.     public RealMatrix getResult() {

  69.         int dimension = sums.length;
  70.         RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension);

  71.         if (n > 1) {
  72.             double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n));
  73.             int k = 0;
  74.             for (int i = 0; i < dimension; ++i) {
  75.                 for (int j = 0; j <= i; ++j) {
  76.                     double e = c * (n * productsSums[k++] - sums[i] * sums[j]);
  77.                     result.setEntry(i, j, e);
  78.                     result.setEntry(j, i, e);
  79.                 }
  80.             }
  81.         }

  82.         return result;
  83.     }

  84.     /**
  85.      * Get the number of vectors in the sample.
  86.      * @return number of vectors in the sample
  87.      */
  88.     public long getN() {
  89.         return n;
  90.     }

  91.     /**
  92.      * Clears the internal state of the Statistic.
  93.      */
  94.     public void clear() {
  95.         n = 0;
  96.         Arrays.fill(sums, 0.0);
  97.         Arrays.fill(productsSums, 0.0);
  98.     }

  99.     /** {@inheritDoc} */
  100.     @Override
  101.     public int hashCode() {
  102.         final int prime = 31;
  103.         int result = 1;
  104.         result = prime * result + (isBiasCorrected ? 1231 : 1237);
  105.         result = prime * result + (int) (n ^ (n >>> 32));
  106.         result = prime * result + Arrays.hashCode(productsSums);
  107.         result = prime * result + Arrays.hashCode(sums);
  108.         return result;
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public boolean equals(Object obj) {
  113.         if (this == obj) {
  114.             return true;
  115.         }
  116.         if (!(obj instanceof VectorialCovariance)) {
  117.             return false;
  118.         }
  119.         VectorialCovariance other = (VectorialCovariance) obj;
  120.         if (isBiasCorrected != other.isBiasCorrected) {
  121.             return false;
  122.         }
  123.         if (n != other.n) {
  124.             return false;
  125.         }
  126.         if (!Arrays.equals(productsSums, other.productsSums)) {
  127.             return false;
  128.         }
  129.         return Arrays.equals(sums, other.sums);
  130.     }
  131. }