    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.math3.random;
    019
    020    import java.util.Arrays;
    021
    022    import org.apache.commons.math3.exception.DimensionMismatchException;
    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 $Id: UncorrelatedRandomVectorGenerator.java 1416643 2012-12-03 19:37:14Z tn $
    030     * @since 1.2
    031     */
    032
    033    public class UncorrelatedRandomVectorGenerator
    034      implements RandomVectorGenerator {
    035
    036        /** Underlying scalar generator. */
    037        private final NormalizedRandomGenerator generator;
    038
    039        /** Mean vector. */
    040        private final double[] mean;
    041
    042        /** Standard deviation vector. */
    043        private final double[] standardDeviation;
    044
    045      /** Simple constructor.
    046       * <p>Build an uncorrelated random vector generator from
    047       * its mean and standard deviation vectors.</p>
    048       * @param mean expected mean values for each component
    049       * @param standardDeviation standard deviation for each component
    050       * @param generator underlying generator for uncorrelated normalized
    051       * components
    052       */
    053      public UncorrelatedRandomVectorGenerator(double[] mean,
    054                                               double[] standardDeviation,
    055                                               NormalizedRandomGenerator generator) {
    056        if (mean.length != standardDeviation.length) {
    057            throw new DimensionMismatchException(mean.length, standardDeviation.length);
    058        }
    059        this.mean              = mean.clone();
    060        this.standardDeviation = standardDeviation.clone();
    061        this.generator = generator;
    062      }
    063
    064      /** Simple constructor.
    065       * <p>Build a null mean random and unit standard deviation
    066       * uncorrelated vector generator</p>
    067       * @param dimension dimension of the vectors to generate
    068       * @param generator underlying generator for uncorrelated normalized
    069       * components
    070       */
    071      public UncorrelatedRandomVectorGenerator(int dimension,
    072                                               NormalizedRandomGenerator generator) {
    073        mean              = new double[dimension];
    074        standardDeviation = new double[dimension];
    075        Arrays.fill(standardDeviation, 1.0);
    076        this.generator = generator;
    077      }
    078
    079      /** Generate an uncorrelated random vector.
    080       * @return a random vector as a newly built array of double
    081       */
    082      public double[] nextVector() {
    083
    084        double[] random = new double[mean.length];
    085        for (int i = 0; i < random.length; ++i) {
    086          random[i] = mean[i] + standardDeviation[i] * generator.nextNormalizedDouble();
    087        }
    088
    089        return random;
    090
    091      }
    092
    093    }