libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNMatrixDouble.cpp
Go to the documentation of this file.
1 /* Copyright 2007-2016 Yann LEYDIER, CoReNum, INSA-Lyon, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNMatrixDouble.cpp
19  * \author Jean DUONG, Yann LEYDIER
20  */
21 
22 #include <CRNException.h>
25 #include <CRNData/CRNData.h>
26 #include <CRNData/CRNDataFactory.h>
27 #include <CRNi18n.h>
28 
29 using namespace crn;
30 
37 {
38  double sum = 0.0;
39 
40  for (size_t r = 0; r < rows; ++r)
41  {
42  for (size_t c = 0; c < cols; ++c)
43  {
44  double val = At(r, c);
45  sum += val * val;
46  }
47  }
48 
49  return sum;
50 }
51 
62 {
63  if (sigma < 0)
64  throw ExceptionDomain(StringUTF8("MatrixDouble::NewGaussianLine(double sigma): ") +
65  _("Negative standard deviation"));
66  if (sigma <= 0.001)
67  return MatrixDouble(1, 1, 1);
68 
69  int hwin = (int)ceil(Thrice(sigma));
70  int size = hwin + hwin + 1;
71  MatrixDouble mat(1, size, 0);
72 
73  for (int tmp = 0; tmp < size; ++tmp)
74  mat.At(0, tmp) = MeanGauss(double(tmp) - double(hwin), sigma);
75 
76  return mat;
77 }
78 
89 {
90  if (sigma < 0)
91  throw ExceptionDomain(StringUTF8("MatrixDouble* MatrixDouble::NewGaussianLineDerivative(double sigma): ") +
92  _("Negative standard deviation"));
93  if (sigma == 0)
94  {
95  MatrixDouble mat(1, 3, 0);
96  mat[0][0] = 1;
97  mat[0][2] = -1;
98  return mat;
99  }
100 
101  int hwin = (int)ceil(Thrice(sigma));
102  int size = hwin + hwin + 1;
103  MatrixDouble mat(1, size, 0);
104 
105  for (int tmp = 0; tmp < size; ++tmp)
106  {
107  double v = (double)hwin - (double)tmp; // -x
108  mat.At(0, tmp) = (v * Gauss(v, sigma) +
109  (v - 0.5) * Gauss(v - 0.5, sigma) +
110  (v + 0.5) * Gauss(v + 0.5, sigma)) / 3.0;
111  }
112 
113  return mat;
114 }
115 
126 {
127  if (sigma < 0)
128  throw ExceptionDomain(StringUTF8("MatrixDouble* MatrixDouble::NewGaussianLineSecondDerivative(double sigma): ") +
129  _("Negative standard deviation"));
130  if (sigma == 0)
131  {
132  MatrixDouble mat(1, 3, -1);
133  mat[0][1] = 2;
134  return mat;
135  }
136  int hwin = (int)ceil(6 * sigma);
137  int size = hwin + hwin + 1;
138  MatrixDouble mat(1, size, 0);
139  for (int tmp = 0; tmp < size; ++tmp)
140  {
141  double v = (double)tmp - (double)hwin; // x
142  mat.At(0, tmp) = ((Sqr(v) - Sqr(sigma)) * Gauss(v, sigma) +
143  (Sqr(v - 0.5) - Sqr(sigma)) * Gauss(v - 0.5, sigma) +
144  (Sqr(v + 0.5) - Sqr(sigma)) * Gauss(v + 0.5, sigma)) / 3.0;
145  }
146  return mat;
147 }
148 
157 {
158  if (GetCols() == 1)
159  {
160  size_t s = GetRows();
161 
162  SquareMatrixDouble m(s, 0.0);
163 
164  for (size_t r = 0; r < s; ++r)
165  {
166  double vr = At(r, 0);
167 
168  for (size_t c = 0; c < s; ++c)
169  {
170  m.At(r, c) = vr * At(c, 0);
171  }
172  }
173 
174  return m;
175  }
176  throw ExceptionDimension(StringUTF8("MatrixDouble::MakeVectorRightAutoProduct(): ") + _("not a column vector."));
177 }
178 
192 {
193  if (el.GetName() != getClassName())
194  {
195  throw ExceptionInvalidArgument(StringUTF8("bool MatrixDouble::Deserialize(xml::Element &el): ") +
196  _("Wrong XML element."));
197  }
198  size_t nr = el.GetAttribute<int>("nb_rows", false); // may throw
199  size_t nc = el.GetAttribute<int>("nb_columns", false); // may throw
200 
201  xml::Node n(el.GetFirstChild());
202  xml::Text t(n.AsText()); // may throw
203 
204  auto vals = Data::ASCII85Decode<double>(t.GetValue());
205  if (vals.size() != nc * nr)
206  throw ExceptionRuntime(StringUTF8("bool MatrixDouble::Deserialize(TiXmlElement *el): ") +
207  _("Cannot convert CDATA."));
208 
209  rows = nr;
210  cols = nc;
211  data.swap(vals);
212 }
213 
224 {
225  xml::Element el(parent.PushBackElement(getClassName()));
226 
227  el.SetAttribute("nb_rows", int(rows));
228  el.SetAttribute("nb_columns", int(cols));
229 
230  auto text = Data::ASCII85Encode(reinterpret_cast<const uint8_t * const>(data.data()), cols * rows * sizeof(double));
231  xml::Text t(el.PushBackText(text, false));
232 
233  return el;
234 }
235 
237  CRN_DATA_FACTORY_REGISTER(U"MatrixDouble", MatrixDouble)
238  Cloner::Register<MatrixDouble>();
239 CRN_END_CLASS_CONSTRUCTOR(MatrixDouble)
240 
static MatrixDouble NewGaussianLineDerivative(double sigma)
Creates a line matrix with the derivative of a centered Gaussian.
size_t GetRows() const noexcept
Returns the number of rows.
Definition: CRNMatrix.h:157
size_t GetCols() const noexcept
Returns the number of columns.
Definition: CRNMatrix.h:163
XML element.
Definition: CRNXml.h:135
A generic runtime error.
Definition: CRNException.h:131
StringUTF8 GetName() const
Gets the label of the element.
Definition: CRNXml.h:146
double CumulateSquaredCells() const
Computes the sum of the squared elements.
#define _(String)
Definition: CRNi18n.h:51
double MeanGauss(double x, double sigma)
Computes Gauss function at x for a given standard deviation (centered in 0) – to use with matrices...
Definition: CRNMath.h:81
MatrixDouble(const Matrix< double > &m)
static MatrixDouble NewGaussianLineSecondDerivative(double sigma)
Creates a line matrix with the second derivative of a centered Gaussian.
static MatrixDouble NewGaussianLine(double sigma)
Creates a line matrix with a centered Gaussian.
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:198
A generic domain error.
Definition: CRNException.h:83
virtual xml::Element Serialize(xml::Element &parent) const
XML text.
Definition: CRNXml.h:394
#define CRN_DATA_FACTORY_REGISTER(elemname, classname)
Registers a class to the data factory.
constexpr SumType< T > Sqr(const T &v) noexcept(noexcept(v *v))
Returns the square of a value.
Definition: CRNMath.h:61
virtual void Deserialize(xml::Element &el)
A dimension error.
Definition: CRNException.h:119
void SetAttribute(const StringUTF8 &name, const StringUTF8 &value)
Sets the value of an attribute.
Definition: CRNXml.cpp:595
double matrix class
double Gauss(double x, double sigma)
Computes Gauss function at x for a given standard deviation (centered in 0)
Definition: CRNMath.h:78
T GetAttribute(const StringUTF8 &name, bool silent=true) const
Gets an attribute.
Definition: CRNXml.h:219
Node GetFirstChild()
Gets the first child node.
Definition: CRNXml.cpp:303
const double & At(size_t pos) const noexcept
Definition: CRNMatrix.h:165
Square double matrix class.
constexpr TypeInfo< T >::SumType Thrice(const T &v) noexcept(noexcept(v+v))
Returns three times a value.
Definition: CRNMath.h:57
A character string class.
Definition: CRNStringUTF8.h:49
crn::StringUTF8 ASCII85Encode(const uint8_t *const data, size_t len)
Encodes any data into a printable string.
Definition: CRNData.cpp:109
Element PushBackElement(const StringUTF8 &name)
Adds an element at the end of the children list.
Definition: CRNXml.cpp:355
XML node.
Definition: CRNXml.h:60
Invalid argument error (e.g.: nullptr pointer)
Definition: CRNException.h:107
SquareMatrixDouble MakeVectorRightAutoProduct() const
Get the product of a column vector by its own transposed on the right side.
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:185