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 one norms of arrays and matrices.
20   * One norm is defined as the maximum column sum on a matrix or array.
21   * For the case of arrays, this library considers arrays as column matrices
22   * with one column and array length rows.
23   */
24  public class OneNormComputer extends NormComputer {
25  
26      /**
27       * Constructor of this class.
28       */
29      public OneNormComputer() {
30          super();
31      }
32  
33      /**
34       * Returns norm type being used by this class.
35       *
36       * @return Norm type being used by this class.
37       */
38      @Override
39      public NormType getNormType() {
40          return NormType.ONE_NORM;
41      }
42  
43      /**
44       * Computes norm of provided matrix.
45       *
46       * @param m matrix being used for norm computation.
47       * @return norm of provided matrix.
48       */
49      @SuppressWarnings("DuplicatedCode")
50      public static double norm(final Matrix m) {
51          final var rows = m.getRows();
52          final var columns = m.getColumns();
53          double colSum;
54          var maxColSum = 0.0;
55  
56          for (var j = 0; j < columns; j++) {
57              colSum = 0.0;
58              for (var i = 0; i < rows; i++) {
59                  colSum += Math.abs(m.getElementAt(i, j));
60              }
61  
62              maxColSum = Math.max(colSum, maxColSum);
63          }
64  
65          return maxColSum;
66      }
67  
68      /**
69       * Computes norm of provided matrix.
70       *
71       * @param m Matrix being used for norm computation.
72       * @return Norm of provided matrix.
73       */
74      @Override
75      public double getNorm(final Matrix m) {
76          return norm(m);
77      }
78  
79      /**
80       * Computes norm of provided array.
81       *
82       * @param array array being used for norm computation.
83       * @return norm of provided vector.
84       */
85      public static double norm(final double[] array) {
86          var colSum = 0.0;
87  
88          for (final var value : array) {
89              colSum += Math.abs(value);
90          }
91  
92          return colSum;
93      }
94  
95      /**
96       * Computes norm of provided array and stores the jacobian into provided
97       * instance.
98       *
99       * @param array    array being used for norm computation.
100      * @param jacobian instance where jacobian will be stored. Must be 1xN,
101      *                 where N is length of array.
102      * @return norm of provided vector.
103      * @throws WrongSizeException if provided jacobian is not 1xN, where N is
104      *                            length of array.
105      */
106     public static double norm(final double[] array, final Matrix jacobian) throws WrongSizeException {
107         if (jacobian != null && (jacobian.getRows() != 1 || jacobian.getColumns() != array.length)) {
108             throw new WrongSizeException("jacobian must be 1xN, where N is length of array");
109         }
110 
111         final var norm = norm(array);
112 
113         if (jacobian != null) {
114             jacobian.fromArray(array);
115             if (norm != 0.0) {
116                 jacobian.multiplyByScalar(1.0 / norm);
117             } else {
118                 jacobian.initialize(Double.MAX_VALUE);
119             }
120         }
121 
122         return norm;
123     }
124 
125     /**
126      * Computes norm of provided array.
127      *
128      * @param array Array being used for norm computation.
129      * @return Norm of provided vector.
130      */
131     @Override
132     public double getNorm(final double[] array) {
133         return norm(array);
134     }
135 }