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    
018    package org.apache.commons.math.random;
019    
020    import java.util.Arrays;
021    
022    import org.apache.commons.math.MathRuntimeException;
023    
024    /** 
025     * A {@link RandomVectorGenerator} that generates vectors with uncorrelated
026     * components. Components of generated vectors follow (independent) Gaussian
027     * distributions, with parameters supplied in the constructor.
028     * 
029     * @version $Revision: 780933 $ $Date: 2009-06-02 00:39:12 -0400 (Tue, 02 Jun 2009) $
030     * @since 1.2
031     */
032    
033    public class UncorrelatedRandomVectorGenerator
034      implements RandomVectorGenerator {
035    
036      /** Simple constructor.
037       * <p>Build an uncorrelated random vector generator from
038       * its mean and standard deviation vectors.</p>
039       * @param mean expected mean values for each component
040       * @param standardDeviation standard deviation for each component
041       * @param generator underlying generator for uncorrelated normalized
042       * components
043       */
044      public UncorrelatedRandomVectorGenerator(double[] mean,
045                                               double[] standardDeviation,
046                                               NormalizedRandomGenerator generator) {
047        if (mean.length != standardDeviation.length) {
048          throw MathRuntimeException.createIllegalArgumentException(
049                "dimension mismatch {0} != {1}",
050                mean.length, standardDeviation.length);
051        }
052        this.mean              = mean.clone();
053        this.standardDeviation = standardDeviation.clone();
054        this.generator = generator;
055      }
056    
057      /** Simple constructor.
058       * <p>Build a null mean random and unit standard deviation
059       * uncorrelated vector generator</p>
060       * @param dimension dimension of the vectors to generate
061       * @param generator underlying generator for uncorrelated normalized
062       * components
063       */
064      public UncorrelatedRandomVectorGenerator(int dimension,
065                                               NormalizedRandomGenerator generator) {
066        mean              = new double[dimension];
067        standardDeviation = new double[dimension];
068        Arrays.fill(standardDeviation, 1.0);
069        this.generator = generator;
070      }
071    
072      /** Generate an uncorrelated random vector.
073       * @return a random vector as a newly built array of double
074       */
075      public double[] nextVector() {
076    
077        double[] random = new double[mean.length]; 
078        for (int i = 0; i < random.length; ++i) {
079          random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble();
080        }
081    
082        return random;
083    
084      }
085    
086      /** Mean vector. */
087      private double[] mean;
088    
089      /** Standard deviation vector. */
090      private double[] standardDeviation;
091    
092      /** Underlying scalar generator. */
093      private NormalizedRandomGenerator generator;
094    
095    }