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 */
017package org.apache.commons.math4.filter;
018
019import org.apache.commons.math4.exception.DimensionMismatchException;
020import org.apache.commons.math4.exception.NoDataException;
021import org.apache.commons.math4.exception.NullArgumentException;
022import org.apache.commons.math4.linear.Array2DRowRealMatrix;
023import org.apache.commons.math4.linear.ArrayRealVector;
024import org.apache.commons.math4.linear.RealMatrix;
025import org.apache.commons.math4.linear.RealVector;
026
027/**
028 * Default implementation of a {@link ProcessModel} for the use with a {@link KalmanFilter}.
029 *
030 * @since 3.0
031 */
032public class DefaultProcessModel implements ProcessModel {
033    /**
034     * The state transition matrix, used to advance the internal state estimation each time-step.
035     */
036    private final RealMatrix stateTransitionMatrix;
037
038    /**
039     * The control matrix, used to integrate a control input into the state estimation.
040     */
041    private final RealMatrix controlMatrix;
042
043    /** The process noise covariance matrix. */
044    private final RealMatrix processNoiseCovMatrix;
045
046    /** The initial state estimation of the observed process. */
047    private final RealVector initialStateEstimateVector;
048
049    /** The initial error covariance matrix of the observed process. */
050    private final RealMatrix initialErrorCovMatrix;
051
052    /**
053     * Create a new {@link ProcessModel}, taking double arrays as input parameters.
054     *
055     * @param stateTransition
056     *            the state transition matrix
057     * @param control
058     *            the control matrix
059     * @param processNoise
060     *            the process noise matrix
061     * @param initialStateEstimate
062     *            the initial state estimate vector
063     * @param initialErrorCovariance
064     *            the initial error covariance matrix
065     * @throws NullArgumentException
066     *             if any of the input arrays is {@code null}
067     * @throws NoDataException
068     *             if any row / column dimension of the input matrices is zero
069     * @throws DimensionMismatchException
070     *             if any of the input matrices is non-rectangular
071     */
072    public DefaultProcessModel(final double[][] stateTransition,
073                               final double[][] control,
074                               final double[][] processNoise,
075                               final double[] initialStateEstimate,
076                               final double[][] initialErrorCovariance)
077            throws NullArgumentException, NoDataException, DimensionMismatchException {
078
079        this(new Array2DRowRealMatrix(stateTransition),
080                new Array2DRowRealMatrix(control),
081                new Array2DRowRealMatrix(processNoise),
082                new ArrayRealVector(initialStateEstimate),
083                new Array2DRowRealMatrix(initialErrorCovariance));
084    }
085
086    /**
087     * Create a new {@link ProcessModel}, taking double arrays as input parameters.
088     * <p>
089     * The initial state estimate and error covariance are omitted and will be initialized by the
090     * {@link KalmanFilter} to default values.
091     *
092     * @param stateTransition
093     *            the state transition matrix
094     * @param control
095     *            the control matrix
096     * @param processNoise
097     *            the process noise matrix
098     * @throws NullArgumentException
099     *             if any of the input arrays is {@code null}
100     * @throws NoDataException
101     *             if any row / column dimension of the input matrices is zero
102     * @throws DimensionMismatchException
103     *             if any of the input matrices is non-rectangular
104     */
105    public DefaultProcessModel(final double[][] stateTransition,
106                               final double[][] control,
107                               final double[][] processNoise)
108            throws NullArgumentException, NoDataException, DimensionMismatchException {
109
110        this(new Array2DRowRealMatrix(stateTransition),
111                new Array2DRowRealMatrix(control),
112                new Array2DRowRealMatrix(processNoise), null, null);
113    }
114
115    /**
116     * Create a new {@link ProcessModel}, taking double arrays as input parameters.
117     *
118     * @param stateTransition
119     *            the state transition matrix
120     * @param control
121     *            the control matrix
122     * @param processNoise
123     *            the process noise matrix
124     * @param initialStateEstimate
125     *            the initial state estimate vector
126     * @param initialErrorCovariance
127     *            the initial error covariance matrix
128     */
129    public DefaultProcessModel(final RealMatrix stateTransition,
130                               final RealMatrix control,
131                               final RealMatrix processNoise,
132                               final RealVector initialStateEstimate,
133                               final RealMatrix initialErrorCovariance) {
134        this.stateTransitionMatrix = stateTransition;
135        this.controlMatrix = control;
136        this.processNoiseCovMatrix = processNoise;
137        this.initialStateEstimateVector = initialStateEstimate;
138        this.initialErrorCovMatrix = initialErrorCovariance;
139    }
140
141    /** {@inheritDoc} */
142    @Override
143    public RealMatrix getStateTransitionMatrix() {
144        return stateTransitionMatrix;
145    }
146
147    /** {@inheritDoc} */
148    @Override
149    public RealMatrix getControlMatrix() {
150        return controlMatrix;
151    }
152
153    /** {@inheritDoc} */
154    @Override
155    public RealMatrix getProcessNoise() {
156        return processNoiseCovMatrix;
157    }
158
159    /** {@inheritDoc} */
160    @Override
161    public RealVector getInitialStateEstimate() {
162        return initialStateEstimateVector;
163    }
164
165    /** {@inheritDoc} */
166    @Override
167    public RealMatrix getInitialErrorCovariance() {
168        return initialErrorCovMatrix;
169    }
170}