1 /* 2 * Licensed to the Hipparchus project 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 Hipparchus project 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 package org.hipparchus.util; 18 19 import org.hipparchus.exception.LocalizedCoreFormats; 20 import org.hipparchus.exception.MathIllegalArgumentException; 21 import org.hipparchus.linear.ArrayRealVector; 22 import org.hipparchus.linear.RealMatrix; 23 import org.hipparchus.linear.RealVector; 24 import org.hipparchus.linear.SemiDefinitePositiveCholeskyDecomposition; 25 26 /** 27 * Base class for unscented transform providers. 28 * @since 2.2 29 */ 30 public abstract class AbstractUnscentedTransform implements UnscentedTransformProvider { 31 32 /** 33 * Constructor. 34 * @param stateDim the dimension of the state 35 */ 36 public AbstractUnscentedTransform(final int stateDim) { 37 // Check state dimension 38 if (stateDim == 0) { 39 // State dimension must be different from 0 40 throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_STATE_SIZE); 41 } 42 } 43 44 /** 45 * {@inheritDoc} 46 * <p> 47 * Let n be the state dimension and Si be the ith row of the covariance matrix square root. 48 * The returned array is organized as follow. Element 0 contains the process state, also 49 * called the mean state. Elements from 1 to n contain the process state + Si. Finally, 50 * elements from n + 1 to 2n contain the process state - Si 51 */ 52 @Override 53 public RealVector[] unscentedTransform(final RealVector state, final RealMatrix covariance) { 54 55 // State dimensions 56 final int n = state.getDimension(); 57 58 // Initialize array containing sigma points 59 final RealVector[] sigmaPoints = new ArrayRealVector[(2 * n) + 1]; 60 sigmaPoints[0] = state; 61 62 // Apply multiplication factor to the covariance matrix 63 final double factor = getMultiplicationFactor(); 64 final RealMatrix temp = covariance.scalarMultiply(factor); 65 66 // Compute lower triangular matrix of Cholesky decomposition 67 // Note: When the estimation error covariance is propagated, it sometimes 68 // cannot maintain the positive semidefiniteness. 69 // To enhance the numerical stability of the unscented transform, 70 // the semidefinite positive Cholesky decomposition is used. 71 final RealMatrix L = new SemiDefinitePositiveCholeskyDecomposition(temp).getL(); 72 73 // Compute sigma points 74 for (int i = 1; i <= n; i++) { 75 sigmaPoints[i] = sigmaPoints[0].add(L.getColumnVector(i - 1)); 76 sigmaPoints[i + n] = sigmaPoints[0].subtract(L.getColumnVector(i - 1)); 77 } 78 79 // Return sigma points 80 return sigmaPoints; 81 82 } 83 84 /** 85 * Get the factor applied to the covariance matrix during the unscented transform. 86 * @return the factor applied to the covariance matrix during the unscented transform 87 */ 88 protected abstract double getMultiplicationFactor(); 89 90 }