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.  *      https://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. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */
  21. package org.hipparchus.stat.descriptive.vector;

  22. import java.io.Serializable;
  23. import java.util.Arrays;

  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.linear.MatrixUtils;
  26. import org.hipparchus.linear.RealMatrix;
  27. import org.hipparchus.util.MathArrays;

  28. /**
  29.  * Returns the covariance matrix of the available vectors.
  30.  */
  31. public class VectorialCovariance implements Serializable {

  32.     /** Serializable version identifier */
  33.     private static final long serialVersionUID = 4118372414238930270L;

  34.     /** Sums for each component. */
  35.     private final double[] sums;

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

  38.     /** Indicator for bias correction. */
  39.     private final boolean isBiasCorrected;

  40.     /** Number of vectors in the sample. */
  41.     private long n;

  42.     /** Constructs a VectorialCovariance.
  43.      * @param dimension vectors dimension
  44.      * @param isBiasCorrected if true, computed the unbiased sample covariance,
  45.      * otherwise computes the biased population covariance
  46.      */
  47.     public VectorialCovariance(int dimension, boolean isBiasCorrected) {
  48.         sums         = new double[dimension];
  49.         productsSums = new double[dimension * (dimension + 1) / 2];
  50.         n            = 0;
  51.         this.isBiasCorrected = isBiasCorrected;
  52.     }

  53.     /**
  54.      * Add a new vector to the sample.
  55.      * @param v vector to add
  56.      * @throws MathIllegalArgumentException if the vector does not have the right dimension
  57.      */
  58.     public void increment(double[] v) throws MathIllegalArgumentException {
  59.         MathArrays.checkEqualLength(v, sums);
  60.         int k = 0;
  61.         for (int i = 0; i < v.length; ++i) {
  62.             sums[i] += v[i];
  63.             for (int j = 0; j <= i; ++j) {
  64.                 productsSums[k++] += v[i] * v[j];
  65.             }
  66.         }
  67.         n++;
  68.     }

  69.     /**
  70.      * Get the covariance matrix.
  71.      * @return covariance matrix
  72.      */
  73.     public RealMatrix getResult() {

  74.         int dimension = sums.length;
  75.         RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension);

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

  87.         return result;

  88.     }

  89.     /**
  90.      * Get the number of vectors in the sample.
  91.      * @return number of vectors in the sample
  92.      */
  93.     public long getN() {
  94.         return n;
  95.     }

  96.     /**
  97.      * Clears the internal state of the Statistic
  98.      */
  99.     public void clear() {
  100.         n = 0;
  101.         Arrays.fill(sums, 0.0);
  102.         Arrays.fill(productsSums, 0.0);
  103.     }

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

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

  139. }