1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS 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    *   http://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.orekit.estimation.measurements.gnss;
18  
19  import org.hipparchus.linear.MatrixUtils;
20  import org.hipparchus.linear.QRDecomposer;
21  import org.hipparchus.linear.RealMatrix;
22  import org.hipparchus.random.RandomGenerator;
23  import org.hipparchus.random.Well19937a;
24  import org.hipparchus.util.FastMath;
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.Test;
27  
28  public class ModifiedLambdaMethodTest extends AbstractLambdaMethodTest {
29  
30      protected AbstractLambdaMethod buildReducer() {
31          return new ModifiedLambdaMethod();
32      }
33  
34      protected RealMatrix buildCovariance(AbstractLambdaMethod reducer) {
35          RealMatrix Z  = getZMatrix(reducer);
36          RealMatrix Zt = Z.transpose();
37          return Zt.multiply(getLow(reducer).transposeMultiply(getDiag(reducer))).
38                          multiply(getLow(reducer)).multiply(Z);
39      }
40  
41     private RealMatrix getZMatrix(final AbstractLambdaMethod reducer) {
42          final int n = reducer.getSize();
43          RealMatrix Z = MatrixUtils.createRealMatrix(n,n);
44          for(int i = 0; i<n; i++) {
45              for(int j = 0; j<n ;j++) {
46                  Z.setEntry(i, j, reducer.getZInverseTransformationReference()[reducer.zIndex(i,j)]);
47              }
48          }
49          return(Z);
50     }
51  
52     @Test
53     public void testReduction() {
54  
55          RandomGenerator random = new Well19937a(0xf824c33093974ee5l);
56          for (int k = 0; k < 1000; ++k) {
57              // generate random test data
58              final int        n           = FastMath.max(2, 1 + random.nextInt(20));
59  
60              final RealMatrix covariance  = createRandomSymmetricPositiveDefiniteMatrix(n, random);
61              final int[]      indirection = createRandomIndirectionArray(n, random);
62  
63              // perform ILS resolution test
64              doTestReduction(random, indirection, covariance);
65  
66          }
67      }
68  
69      private void doTestReduction(final RandomGenerator random,
70                                     final int[] indirection, final RealMatrix covariance) {
71          final double[] floatAmbiguities = new double[indirection.length];
72          for (int i = 0; i < floatAmbiguities.length; ++i) {
73              floatAmbiguities[i] = 2 * random.nextDouble() - 1.0;
74          }
75          RealMatrix filteredCovariance = filterCovariance(covariance, indirection);
76          final AbstractLambdaMethod reducer = buildReducer();
77          initializeProblem(reducer, floatAmbiguities, indirection, covariance, 2);
78          reducer.ltdlDecomposition();
79          reducer.reduction();
80  
81          //Rebuilt the covariance
82          RealMatrix Z                  = this.getZMatrix(reducer);
83          RealMatrix RebuiltCov         = Z.transposeMultiply(getLow(reducer).transposeMultiply(getDiag(reducer))).
84                                          multiply(getLow(reducer)).multiply(Z);
85  
86          //Check the covariance are the same
87          double norm                   = filteredCovariance.subtract(RebuiltCov).getNorm1();
88          Assertions.assertEquals(0.0, norm, 1e-11);
89  
90          //Check the floatAmbiguities have been well transform by Z transformation
91          RealMatrix a = MatrixUtils.createColumnRealMatrix(floatAmbiguities);
92          RealMatrix invZ = new QRDecomposer(1.0e-10).
93                          decompose(Z).
94                          getInverse();
95          RealMatrix zRef = invZ.transposeMultiply(a);
96          double[] zComputed = getDecorrelated(reducer);
97          for(int i= 0; i<zComputed.length; i++) {
98              Assertions.assertEquals(zRef.getEntry(i, 0),zComputed[i],1e-6);
99          }
100     }
101 }
102 
103