001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.stat.descriptive.moment;
018
019 import java.io.Serializable;
020 import java.util.Arrays;
021
022 import org.apache.commons.math.DimensionMismatchException;
023 import org.apache.commons.math.linear.MatrixUtils;
024 import org.apache.commons.math.linear.RealMatrix;
025
026 /**
027 * Returns the covariance matrix of the available vectors.
028 * @since 1.2
029 * @version $Revision: 922714 $ $Date: 2010-03-14 02:35:14 +0100 (dim. 14 mars 2010) $
030 */
031 public class VectorialCovariance implements Serializable {
032
033 /** Serializable version identifier */
034 private static final long serialVersionUID = 4118372414238930270L;
035
036 /** Sums for each component. */
037 private final double[] sums;
038
039 /** Sums of products for each component. */
040 private final double[] productsSums;
041
042 /** Indicator for bias correction. */
043 private final boolean isBiasCorrected;
044
045 /** Number of vectors in the sample. */
046 private long n;
047
048 /** Constructs a VectorialCovariance.
049 * @param dimension vectors dimension
050 * @param isBiasCorrected if true, computed the unbiased sample covariance,
051 * otherwise computes the biased population covariance
052 */
053 public VectorialCovariance(int dimension, boolean isBiasCorrected) {
054 sums = new double[dimension];
055 productsSums = new double[dimension * (dimension + 1) / 2];
056 n = 0;
057 this.isBiasCorrected = isBiasCorrected;
058 }
059
060 /**
061 * Add a new vector to the sample.
062 * @param v vector to add
063 * @exception DimensionMismatchException if the vector does not have the right dimension
064 */
065 public void increment(double[] v) throws DimensionMismatchException {
066 if (v.length != sums.length) {
067 throw new DimensionMismatchException(v.length, sums.length);
068 }
069 int k = 0;
070 for (int i = 0; i < v.length; ++i) {
071 sums[i] += v[i];
072 for (int j = 0; j <= i; ++j) {
073 productsSums[k++] += v[i] * v[j];
074 }
075 }
076 n++;
077 }
078
079 /**
080 * Get the covariance matrix.
081 * @return covariance matrix
082 */
083 public RealMatrix getResult() {
084
085 int dimension = sums.length;
086 RealMatrix result = MatrixUtils.createRealMatrix(dimension, dimension);
087
088 if (n > 1) {
089 double c = 1.0 / (n * (isBiasCorrected ? (n - 1) : n));
090 int k = 0;
091 for (int i = 0; i < dimension; ++i) {
092 for (int j = 0; j <= i; ++j) {
093 double e = c * (n * productsSums[k++] - sums[i] * sums[j]);
094 result.setEntry(i, j, e);
095 result.setEntry(j, i, e);
096 }
097 }
098 }
099
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 }