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.linear;
18
19 import java.util.List;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.exception.LocalizedCoreFormats;
24 import org.hipparchus.exception.MathIllegalArgumentException;
25
26 /** Enumerate to specify how dependent vectors should be handled in
27 * {@link MatrixUtils#orthonormalize(List, double, DependentVectorsHandler)} and
28 * {@link MatrixUtils#orthonormalize(Field, List, CalculusFieldElement, DependentVectorsHandler)}.
29 * @since 2.1
30 */
31 public enum DependentVectorsHandler {
32
33 /** Generate a {@link MathIllegalArgumentException} if dependent vectors are found. */
34 GENERATE_EXCEPTION {
35
36 /** {@inheritDoc} */
37 @Override
38 public int manageDependent(final int index, final List<RealVector> basis) {
39 // generate exception, dependent vectors are forbidden with this settings
40 throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_NORM);
41 }
42
43
44 /** {@inheritDoc} */
45 @Override
46 public <T extends CalculusFieldElement<T>> int manageDependent(final Field<T> field,
47 final int index,
48 final List<FieldVector<T>> basis) {
49 // generate exception, dependent vectors are forbidden with this settings
50 throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_NORM);
51 }
52
53 },
54
55 /** Replace dependent vectors by vectors with norm 0.
56 * <p>
57 * This behavior matches the Wolfram language API. It keeps the
58 * number of output vectors equal to the number of input vectors.
59 * The only two norms output vectors can have are 0 and 1.
60 * </p>
61 */
62 ADD_ZERO_VECTOR {
63
64 /** {@inheritDoc} */
65 @Override
66 public int manageDependent(final int index, final List<RealVector> basis) {
67 // add a zero vector, preserving output vector size (and dropping its normalization property)
68 basis.set(index, MatrixUtils.createRealVector(basis.get(index).getDimension()));
69 return index + 1;
70 }
71
72
73 /** {@inheritDoc} */
74 @Override
75 public <T extends CalculusFieldElement<T>> int manageDependent(final Field<T> field,
76 final int index,
77 final List<FieldVector<T>> basis) {
78 // add a zero vector, preserving output vector size (and dropping its normalization property)
79 basis.set(index, MatrixUtils.createFieldVector(field, basis.get(index).getDimension()));
80 return index + 1;
81 }
82
83 },
84
85 /** Ignore dependent vectors.
86 * <p>
87 * This behavior ensures the output vectors form an orthonormal
88 * basis, i.e. all vectors are independent and they all have norm 1.
89 * The number of output vectors may be smaller than the number of
90 * input vectors, this number corresponds to the dimension of the
91 * span of the input vectors.
92 * </p>
93 */
94 REDUCE_BASE_TO_SPAN {
95
96 /** {@inheritDoc} */
97 @Override
98 public int manageDependent(final int index, final List<RealVector> basis) {
99 // remove dependent vector
100 basis.remove(index);
101 return index;
102 }
103
104
105 /** {@inheritDoc} */
106 @Override
107 public <T extends CalculusFieldElement<T>> int manageDependent(final Field<T> field,
108 final int index,
109 final List<FieldVector<T>> basis) {
110 // remove dependent vector
111 basis.remove(index);
112 return index;
113 }
114
115 };
116
117 /** Manage a dependent vector.
118 * @param index of the vector in the basis
119 * @param basis placeholder for basis vectors
120 * @return next index to manage
121 */
122 public abstract int manageDependent(int index, List<RealVector> basis);
123
124 /** Manage a dependent vector.
125 * @param <T> type of the vectors components
126 * @param field field to which the vectors belong
127 * @param index of the vector in the basis
128 * @param basis placeholder for basis vectors
129 * @return next index to manage
130 */
131 public abstract <T extends CalculusFieldElement<T>> int manageDependent(Field<T> field, int index, List<FieldVector<T>> basis);
132
133 }