View Javadoc
1   /*
2    * Copyright (C) 2012 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.algebra;
17  
18  /**
19   * Class in charge of computing norms of arrays and matrices.
20   * Norms can be computed in different ways depending on the desired norm
21   * measure. For that purpose subclass implementations of this class attempt to
22   * work on different norm types.
23   * By default, Frobenius norm is used for arrays and matrices, which consists
24   * on computing the square root of summation of all the squared elements within
25   * a given matrix or array.
26   */
27  public abstract class NormComputer {
28      /**
29       * Constant defining default norm type to be used.
30       */
31      public static final NormType DEFAULT_NORM_TYPE = NormType.FROBENIUS_NORM;
32  
33      /**
34       * Constructor of this class.
35       */
36      protected NormComputer() {
37      }
38  
39      /**
40       * Returns norm type being used by this class.
41       *
42       * @return Norm type being used by this class.
43       */
44      public abstract NormType getNormType();
45  
46      /**
47       * Computes norm of provided matrix.
48       *
49       * @param m Matrix being used for norm computation.
50       * @return Norm of provided matrix.
51       */
52      public abstract double getNorm(final Matrix m);
53  
54      /**
55       * Computes norm of provided array.
56       *
57       * @param array Array being used for norm computation.
58       * @return Norm of provided vector.
59       */
60      public abstract double getNorm(final double[] array);
61  
62      /**
63       * Computes norm of provided array and stores the jacobian into provided
64       * instance.
65       *
66       * @param array    array being used for norm computation.
67       * @param jacobian instance where jacobian will be stored. Must be 1xN,
68       *                 where N is length of array.
69       * @return norm of provided vector.
70       * @throws WrongSizeException if provided jacobian is not 1xN, where N is
71       *                            length of array.
72       */
73      public double getNorm(final double[] array, final Matrix jacobian) throws WrongSizeException {
74          if (jacobian != null && (jacobian.getRows() != 1 || jacobian.getColumns() != array.length)) {
75              throw new WrongSizeException("jacobian must be 1xN, where N is length of array");
76          }
77  
78          final var norm = getNorm(array);
79  
80          if (jacobian != null) {
81              jacobian.fromArray(array);
82              jacobian.multiplyByScalar(1.0 / norm);
83          }
84  
85          return norm;
86      }
87  
88      /**
89       * Factory method. Returns a new instance of NormComputer prepared to
90       * compute norms using provided NormType.
91       *
92       * @param normType Norm type to be used by returned instance.
93       * @return New instance of NormComputer.
94       */
95      public static NormComputer create(final NormType normType) {
96          return switch (normType) {
97              case INFINITY_NORM -> new InfinityNormComputer();
98              case ONE_NORM -> new OneNormComputer();
99              default -> new FrobeniusNormComputer();
100         };
101     }
102 
103     /**
104      * Factory method. Returns a new instance of NormComputer prepared to
105      * compute norms using provided NormType.
106      *
107      * @return New instance of NormComputer.
108      */
109     public static NormComputer create() {
110         return create(DEFAULT_NORM_TYPE);
111     }
112 }