CVM Class Library  8.1
This C++ class library encapsulates concepts of vector and different matrices including square, band, symmetric and hermitian ones in Euclidean space of real and complex numbers.
 All Classes Files Functions Variables Typedefs Friends Macros Pages
utils.cpp
Go to the documentation of this file.
1 // CVM Class Library
2 // http://cvmlib.com
3 //
4 // Copyright Sergei Nikolaev 1992-2014
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 
9 #include "cvm.h"
10 #include "blas.h"
11 #include "cfun.h"
12 
14 
15 #if defined (CVM_STD_MUTEX)
16 std::mutex cvm_mutex;
17 #else
18 CriticalSection emCS;
19 #endif
20 
22 char Chars::mchars[15] = { 'T', 'N', 'U', 'L', 'P', 'Q', 'B', 'E', 'R', 'A', 'S', 'V', 'O', 'I', 'C' };
24 
25 // global error messages holder
27 {
28  static ErrMessages _ErrMessages;
29  return _ErrMessages;
30 }
31 
32 CVM_API ErrMessages::ErrMessages()
33  : msUnknown("Unknown exception"), mmMsg()
34 {
35 #if defined (CVM_STD_MUTEX)
36  std::unique_lock<std::mutex> l(cvm_mutex);
37 #else
38  Lock l(emCS);
39 #endif
40 
41  mmMsg.insert(pair_Msg(CVM_OK, "All OK"));
42  mmMsg.insert(pair_Msg(CVM_OUTOFMEMORY, "Failed to allocate %u bytes of memory"));
43  mmMsg.insert(pair_Msg(CVM_WRONGSIZE, "Wrong size: " CVM_TINT_FORMAT));
44  mmMsg.insert(pair_Msg(CVM_SIZESMISMATCH, "Sizes mismatch: " CVM_TINT_FORMAT " != " CVM_TINT_FORMAT));
45  mmMsg.insert(pair_Msg(CVM_WRONGMKLARG, "Wrong argument " CVM_TINT_FORMAT " passed to BLAS or LAPACK subroutine"));
46  mmMsg.insert(pair_Msg(CVM_WRONGMKLARG2, "Wrong argument " CVM_TINT_FORMAT " passed to BLAS or LAPACK subroutine %s"));
47  mmMsg.insert(pair_Msg(CVM_SINGULARMATRIX, "The diagonal element (or main minor) " CVM_TINT_FORMAT " of the matrix is zero (or singular)"));
48  mmMsg.insert(pair_Msg(CVM_NOTPOSITIVEDEFINITE, "The leading minor of order " CVM_TINT_FORMAT " (hence the matrix itself) is not positive-definite"));
49  mmMsg.insert(pair_Msg(CVM_WRONGCHOLESKYFACTOR, "The diagonal element " CVM_TINT_FORMAT " of the Cholesky factor (hence the factor itself) is zero"));
50  mmMsg.insert(pair_Msg(CVM_WRONGBUNCHKAUFMANFACTOR, "The diagonal element " CVM_TINT_FORMAT " of the Bunch-Kaufman factor (and hence the factor itself) is zero"));
51  mmMsg.insert(pair_Msg(CVM_NOTPOSITIVEDIAG, "The diagonal element " CVM_TINT_FORMAT " of the matrix is nonpositive. Equilibration failed"));
52  mmMsg.insert(pair_Msg(CVM_CONVERGENCE_ERROR, "Method failed to converge: %s at %s:%d"));
53  mmMsg.insert(pair_Msg(CVM_DIVISIONBYZERO, "Attempt to divide by zero"));
54 #if defined (WIN32) || defined (_WIN32)
55  mmMsg.insert(pair_Msg(CVM_SEMAPHOREERROR, "Critical Section access error"));
56 #else
57  mmMsg.insert(pair_Msg(CVM_SEMAPHOREERROR, "Semaphore access error"));
58 #endif
59  mmMsg.insert(pair_Msg(CVM_READ_ONLY_ACCESS, "Attempt to change a read-only element"));
60  mmMsg.insert(pair_Msg(CVM_SUBMATRIXACCESSERROR, "Attempt to access non-continuous submatrix as a continuous array, see programmer\'s reference for details"));
61  mmMsg.insert(pair_Msg(CVM_SUBMATRIXNOTAVAILABLE, "Submatrix instantiation is not available for class \'%s\', see programmer\'s reference for details"));
62  mmMsg.insert(pair_Msg(CVM_MATRIXNOTSYMMETRIC, "The matrix passed doesn't appear to be symmetric"));
63  mmMsg.insert(pair_Msg(CVM_MATRIXNOTHERMITIAN, "The matrix passed doesn't appear to be hermitian (%g vs. tolerance %g)"));
64  mmMsg.insert(pair_Msg(CVM_BREAKS_HERMITIANITY, "This operation could make the matrix non-hermitian. Use %s instead"));
65  mmMsg.insert(pair_Msg(CVM_METHODNOTAVAILABLE, "Function \'%s\' is not available for class \'%s\'. See programmer\'s reference for details"));
66  mmMsg.insert(pair_Msg(CVM_NOTIMPLEMENTED, "Function \'%s\' is not implemented"));
67  mmMsg.insert(pair_Msg(CVM_CANT_RESIZE_SHARED_MEM, "Can\'t resize shared memory"));
68  mmMsg.insert(pair_Msg(CVM_NOT_CONJUGATED, "Complex numbers are not conjugated: (%g,%g) vs. (%g,%g) with tolerance %g"));
69  // 8.1
70  mmMsg.insert(pair_Msg(CVM_WRONGSIZE_LT, "Wrong size: " CVM_TINT_FORMAT " < " CVM_TINT_FORMAT));
71  mmMsg.insert(pair_Msg(CVM_WRONGSIZE_LE, "Wrong size: " CVM_TINT_FORMAT " <= " CVM_TINT_FORMAT));
72  mmMsg.insert(pair_Msg(CVM_INDEX_GT, "Index value " CVM_TINT_FORMAT " > " CVM_TINT_FORMAT));
73  mmMsg.insert(pair_Msg(CVM_INDEX_GE, "Index value " CVM_TINT_FORMAT " >= " CVM_TINT_FORMAT));
74  mmMsg.insert(pair_Msg(CVM_OUTOFRANGE_LTGT, "Index value " CVM_TINT_FORMAT " is out of [" CVM_TINT_FORMAT "," CVM_TINT_FORMAT "] range"));
75  mmMsg.insert(pair_Msg(CVM_OUTOFRANGE_LTGE, "Index value " CVM_TINT_FORMAT " is out of [" CVM_TINT_FORMAT "," CVM_TINT_FORMAT ") range"));
76  mmMsg.insert(pair_Msg(CVM_OUTOFRANGE_LTGE1, "First index value " CVM_TINT_FORMAT " is out of [" CVM_TINT_FORMAT "," CVM_TINT_FORMAT ") range"));
77  mmMsg.insert(pair_Msg(CVM_OUTOFRANGE_LTGE2, "Second index value " CVM_TINT_FORMAT " is out of [" CVM_TINT_FORMAT "," CVM_TINT_FORMAT ") range"));
78  mmMsg.insert(pair_Msg(CVM_SIZESMISMATCH_GT, "Sizes mismatch: " CVM_TINT_FORMAT " > " CVM_TINT_FORMAT));
79  mmMsg.insert(pair_Msg(CVM_SIZESMISMATCH_LT, "Sizes mismatch: " CVM_TINT_FORMAT " < " CVM_TINT_FORMAT));
80 
81  mmMsg.insert(pair_Msg(CFUN_PARSEERROR, "Error while parsing \'%s\' for variables %s"));
82  mmMsg.insert(pair_Msg(CFUN_DOMAINERROR, "Domain error while calculating %s of %g"));
83  mmMsg.insert(pair_Msg(CFUN_DOMAINERROR_C, "Domain error while calculating %s of (%g,%g)"));
84  mmMsg.insert(pair_Msg(CFUN_CONVERGENCEERROR, "Convergence error while calculating %s of %g"));
85  mmMsg.insert(pair_Msg(CFUN_CONVERGENCEERROR_C, "Convergence error while calculating %s of (%g,%g)"));
86  mmMsg.insert(pair_Msg(CFUN_SUBSTPARAMETERERROR, "Error while substituting parameter \'%s\'"));
87  mmMsg.insert(pair_Msg(CFUN_VARSDONTMATCH, "Variables don\'t match: \'%s\' vs. \'%s\'"));
88  mmMsg.insert(pair_Msg(CFUN_NULLPOINTERERROR, "Null pointer passed to \'%s\'"));
89  mmMsg.insert(pair_Msg(CFUN_PARAMETER_RECURSION, "Parameter \'%s\' can\'t be a part of its own meaning \'%s\'"));
90 }
91 
92 CVM_API const std::string& ErrMessages::_get(int nException)
93 {
94 #if defined (CVM_STD_MUTEX)
95  std::unique_lock<std::mutex> l(cvm_mutex);
96 #else
97  Lock l(emCS);
98 #endif
99  citr_Msg i = mmMsg.size() > 0 ? mmMsg.find(nException) : mmMsg.end();
100  return i == mmMsg.end() ? msUnknown : (*i).second;
101 }
102 
103 CVM_API bool ErrMessages::_add(int nNewCause, const char* szNewMessage)
104 {
105 #if defined (CVM_STD_MUTEX)
106  std::unique_lock<std::mutex> l(cvm_mutex);
107 #else
108  Lock l(emCS);
109 #endif
110  bool bRes = true;
111  itr_Msg i = mmMsg.find(nNewCause);
112  if (i != mmMsg.end()) {
113  (*i).second = (*i).second + " | " + szNewMessage; // Defenition is overlapped. This is not a good idea
114  bRes = false; // to do so, use CVM_THE_LAST_ERROR_CODE + 1 as an error code.
115  }
116  else {
117  mmMsg.insert(pair_Msg(nNewCause, szNewMessage)); // new error definition
118  }
119  return bRes;
120 }
121 
122 template <>
123 CVM_API float _real<std::complex<float>, float>(const std::complex<float>& mT)
124 {
125  return mT.real();
126 }
127 
128 template <>
129 CVM_API double _real<std::complex<double>, double>(const std::complex<double>& mT)
130 {
131  return mT.real();
132 }
133 
134 template <>
135 CVM_API float _imag<std::complex<float>, float>(const std::complex<float>& mT)
136 {
137  return mT.imag();
138 }
139 
140 template <>
141 CVM_API double _imag<std::complex<double>, double>(const std::complex<double>& mT)
142 {
143  return mT.imag();
144 }
145 
146 template <>
147 CVM_API void __copy<float>(tint nSize, const float* pFrom, tint nFromIncr, float* pTo, tint nToIncr)
148 {
149  CVM_ASSERT(pFrom, ((nFromIncr)*(nSize - 1)+ 1)* sizeof(float))
150  CVM_ASSERT(pTo, ((nToIncr)*(nSize - 1)+ 1)* sizeof(float))
151  SCOPY(& nSize, pFrom, &nFromIncr, pTo, &nToIncr);
152 }
153 
154 template <>
155 CVM_API void __copy<double>(tint nSize, const double* pFrom, tint nFromIncr, double* pTo, tint nToIncr)
156 {
157  CVM_ASSERT(pFrom, ((nFromIncr)*(nSize - 1)+ 1)* sizeof(double))
158  CVM_ASSERT(pTo, ((nToIncr)*(nSize - 1)+ 1)* sizeof(double))
159  DCOPY(& nSize, pFrom, &nFromIncr, pTo, &nToIncr);
160 }
161 
162 template <>
163 CVM_API void __copy<std::complex<float> >(tint nSize, const std::complex<float>* pFrom, tint nFromIncr, std::complex<float>* pTo, tint nToIncr)
164 {
165  CVM_ASSERT(pFrom, ((nFromIncr)*(nSize - 1)+ 1)* sizeof(std::complex<float>))
166  CVM_ASSERT(pTo, ((nToIncr)*(nSize - 1)+ 1)* sizeof(std::complex<float>))
167  CCOPY(& nSize, pFrom, &nFromIncr, pTo, &nToIncr);
168 }
169 
170 template <>
171 CVM_API void __copy<std::complex<double> >(tint nSize, const std::complex<double>* pFrom, tint nFromIncr, std::complex<double>* pTo, tint nToIncr)
172 {
173  CVM_ASSERT(pFrom, ((nFromIncr)*(nSize - 1)+ 1)* sizeof(std::complex<double>))
174  CVM_ASSERT(pTo, ((nToIncr)*(nSize - 1)+ 1)* sizeof(std::complex<double>))
175  ZCOPY(& nSize, pFrom, &nFromIncr, pTo, &nToIncr);
176 }
177 
178 template <>
179 CVM_API void __copy<tint>(tint nSize, const tint* pFrom, tint nFromIncr, tint* pTo, tint nToIncr)
180 {
181  CVM_ASSERT(pFrom, ((nFromIncr)*(nSize - 1)+ 1)* sizeof(tint))
182  CVM_ASSERT(pTo, ((nToIncr)*(nSize - 1)+ 1)* sizeof(tint))
183  for(tint i = 0; i < nSize; ++i) {
184  pTo[i* nToIncr] = pFrom[i* nFromIncr];
185  }
186 }
187 
188 template <>
189 CVM_API void __swap<float>(tint nSize, float* p1, tint n1Incr, float* p2, tint n2Incr)
190 {
191  CVM_ASSERT(p1, ((n1Incr)*(nSize - 1)+ 1)* sizeof(float))
192  CVM_ASSERT(p2, ((n2Incr)*(nSize - 1)+ 1)* sizeof(float))
193  SSWAP(& nSize, p1, &n1Incr, p2, &n2Incr);
194 }
195 
196 template <>
197 CVM_API void __swap<double>(tint nSize, double* p1, tint n1Incr, double* p2, tint n2Incr)
198 {
199  CVM_ASSERT(p1, ((n1Incr)*(nSize - 1)+ 1)* sizeof(double))
200  CVM_ASSERT(p2, ((n2Incr)*(nSize - 1)+ 1)* sizeof(double))
201  DSWAP(& nSize, p1, &n1Incr, p2, &n2Incr);
202 }
203 
204 template <>
205 CVM_API void __swap<std::complex<float> >(tint nSize, std::complex<float>* p1, tint n1Incr, std::complex<float>* p2, tint n2Incr)
206 {
207  CVM_ASSERT(p1, ((n1Incr)*(nSize - 1)+ 1)* sizeof(std::complex<float>))
208  CVM_ASSERT(p2, ((n2Incr)*(nSize - 1)+ 1)* sizeof(std::complex<float>))
209  CSWAP(& nSize, p1, &n1Incr, p2, &n2Incr);
210 }
211 
212 template <>
213 CVM_API void __swap<std::complex<double> >(tint nSize, std::complex<double>* p1, tint n1Incr, std::complex<double>* p2, tint n2Incr)
214 {
215  CVM_ASSERT(p1, ((n1Incr)*(nSize - 1)+ 1)* sizeof(std::complex<double>))
216  CVM_ASSERT(p2, ((n2Incr)*(nSize - 1)+ 1)* sizeof(std::complex<double>))
217  ZSWAP(& nSize, p1, &n1Incr, p2, &n2Incr);
218 }
219 
220 template <>
221 CVM_API void __swap<tint>(tint nSize, tint* p1, tint n1Incr, tint* p2, tint n2Incr)
222 {
223  tint n;
224  CVM_ASSERT(p1, (n1Incr*(nSize - 1)+ 1)* sizeof(tint))
225  CVM_ASSERT(p2, (n2Incr*(nSize - 1)+ 1)* sizeof(tint))
226  for(tint i = 0; i < nSize; ++i) {
227  n = p1[i* n1Incr];
228  p1[i* n1Incr] = p2[i* n2Incr];
229  p2[i* n2Incr] = n;
230  }
231 }
232 
233 template <>
234 CVM_API void __low_up<basic_srmatrix<float> >(basic_srmatrix<float>& m, tint* nPivots)throw(cvmexception)
235 {
236  tint nOutInfo = 0;
237  SGETRF(m._pm(), m._pn(), m, m._pld(), nPivots, &nOutInfo);
238  _check_negative(CVM_WRONGMKLARG, nOutInfo);
239  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
240 }
241 
242 template <>
243 CVM_API void __low_up<basic_srmatrix<double> >(basic_srmatrix<double>& m, tint* nPivots)throw(cvmexception)
244 {
245  tint nOutInfo = 0;
246  DGETRF(m._pm(), m._pn(), m, m._pld(), nPivots, &nOutInfo);
247  _check_negative(CVM_WRONGMKLARG, nOutInfo);
248  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
249 }
250 
251 template <>
252 CVM_API void __low_up<basic_scmatrix<float, std::complex<float> > >
254 {
255  tint nOutInfo = 0;
256  CGETRF(m._pm(), m._pn(), m, m._pld(), nPivots, &nOutInfo);
257  _check_negative(CVM_WRONGMKLARG, nOutInfo);
258  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
259 }
260 
261 template <>
262 CVM_API void __low_up<basic_scmatrix<double, std::complex<double> > >
264 {
265  tint nOutInfo = 0;
266  ZGETRF(m._pm(), m._pn(), m, m._pld(), nPivots, &nOutInfo);
267  _check_negative(CVM_WRONGMKLARG, nOutInfo);
268  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
269 }
270 
271 template <>
272 CVM_API void __low_up<basic_srbmatrix<float> >
274 {
275  tint nOutInfo = 0;
276  const tint nKL = m.lsize();
277  const tint nKU = m.usize();
278  m.resize_lu(nKL, nKL + nKU);
279  SGBTRF(m._pm(), m._pn(), &nKL, &nKU, m, m._pld(), nPivots, &nOutInfo);
280  _check_negative(CVM_WRONGMKLARG, nOutInfo);
281  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
282 }
283 
284 template <>
285 CVM_API void __low_up<basic_srbmatrix<double> >
287 {
288  tint nOutInfo = 0;
289  const tint nKL = m.lsize();
290  const tint nKU = m.usize();
291  m.resize_lu(nKL, nKL + nKU);
292  DGBTRF(m._pm(), m._pn(), &nKL, &nKU, m, m._pld(), nPivots, &nOutInfo);
293  _check_negative(CVM_WRONGMKLARG, nOutInfo);
294  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
295 }
296 
297 template <>
298 CVM_API void __low_up<basic_scbmatrix<float, std::complex<float> > >
300 {
301  tint nOutInfo = 0;
302  const tint nKL = m.lsize();
303  const tint nKU = m.usize();
304  m.resize_lu(nKL, nKL + nKU);
305  CGBTRF(m._pm(), m._pn(), &nKL, &nKU, m, m._pld(), nPivots, &nOutInfo);
306  _check_negative(CVM_WRONGMKLARG, nOutInfo);
307  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
308 }
309 
310 template <>
311 CVM_API void __low_up<basic_scbmatrix<double, std::complex<double> > >
313 {
314  tint nOutInfo = 0;
315  const tint nKL = m.lsize();
316  const tint nKU = m.usize();
317  m.resize_lu(nKL, nKL + nKU);
318  ZGBTRF(m._pm(), m._pn(), &nKL, &nKU, m, m._pld(), nPivots, &nOutInfo);
319  _check_negative(CVM_WRONGMKLARG, nOutInfo);
320  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
321 }
322 
323 template <>
324 CVM_API tint __cholesky<basic_srmatrix<float> >
325  (basic_srmatrix<float>& m) // input is symmetric, output is triangular
326 {
327  tint nOutInfo = 0;
328  SPOTRF(Chars::pU(),
329 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
330  1,
331 #endif
332  m._pm(), m, m._pld(), &nOutInfo);
333  return nOutInfo;
334 }
335 
336 template <>
337 CVM_API tint __cholesky<basic_srmatrix<double> >
338  (basic_srmatrix<double>& m) // input is symmetric, output is triangular
339 {
340  tint nOutInfo = 0;
341  DPOTRF(Chars::pU(),
342 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
343  1,
344 #endif
345  m._pm(), m, m._pld(), &nOutInfo);
346  return nOutInfo;
347 }
348 
349 template <>
350 CVM_API tint __cholesky<basic_scmatrix<float, std::complex<float> > >
351  (basic_scmatrix<float, std::complex<float> >& m) // input is hermitian, output is triangular
352 {
353  tint nOutInfo = 0;
354  CPOTRF(Chars::pU(),
355 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
356  1,
357 #endif
358  m._pm(), m, m._pld(), &nOutInfo);
359  return nOutInfo;
360 }
361 
362 template <>
363 CVM_API tint __cholesky<basic_scmatrix<double, std::complex<double> > >
364  (basic_scmatrix<double, std::complex<double> >& m) // input is hermitian, output is triangular
365 {
366  tint nOutInfo = 0;
367  ZPOTRF(Chars::pU(),
368 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
369  1,
370 #endif
371  m._pm(), m, m._pld(), &nOutInfo);
372  return nOutInfo;
373 }
374 
375 template <>
376 CVM_API void __bunch_kaufman<basic_srmatrix<float> >
377  (basic_srmatrix<float>& m, tint* nPivots)throw(cvmexception) // input is symmetric, output is square
378 {
379  tint nOutInfo = 0;
380  const tint lwork = m.msize()* 64;
381  basic_rvector<float> work(lwork);
382  SSYTRF(Chars::pU(),
383 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
384  1,
385 #endif
386  m._pm(), m, m._pld(), nPivots, work, &lwork, &nOutInfo);
387 
388  _check_negative(CVM_WRONGMKLARG, nOutInfo);
389  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
390 }
391 
392 template <>
393 CVM_API void __bunch_kaufman<basic_srmatrix<double> >
394  (basic_srmatrix<double>& m, tint* nPivots)throw(cvmexception) // input is symmetric, output is square
395 {
396  tint nOutInfo = 0;
397  const tint lwork = m.msize()* 64;
398  basic_rvector<double> work(lwork);
399  DSYTRF(Chars::pU(),
400 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
401  1,
402 #endif
403  m._pm(), m, m._pld(), nPivots, work, &lwork, &nOutInfo);
404 
405  _check_negative(CVM_WRONGMKLARG, nOutInfo);
406  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
407 }
408 
409 template <>
410 CVM_API void __bunch_kaufman<basic_scmatrix<float, std::complex<float> > >
411  (basic_scmatrix<float, std::complex<float> >& m, tint* nPivots)throw(cvmexception) // input is hermitian, output is square
412 {
413  tint nOutInfo = 0;
414  const tint lwork = m.msize()* 64;
416  CHETRF(Chars::pU(),
417 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
418  1,
419 #endif
420  m._pm(), m, m._pld(), nPivots, work, &lwork, &nOutInfo);
421 
422  _check_negative(CVM_WRONGMKLARG, nOutInfo);
423  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
424 }
425 
426 template <>
427 CVM_API void __bunch_kaufman<basic_scmatrix<double, std::complex<double> > >
428  (basic_scmatrix<double, std::complex<double> >& m, tint* nPivots)throw(cvmexception) // input is hermitian, output is square
429 {
430  tint nOutInfo = 0;
431  const tint lwork = m.msize()* 64;
433  ZHETRF(Chars::pU(),
434 #if defined (CVM_PASS_STRING_LENGTH_TO_FTN_SUBROUTINES)
435  1,
436 #endif
437  m._pm(), m, m._pld(), nPivots, work, &lwork, &nOutInfo);
438 
439  _check_negative(CVM_WRONGMKLARG, nOutInfo);
440  _check_positive(CVM_SINGULARMATRIX, nOutInfo);
441 }
442 
443 template <>
444 CVM_API void __ger<float, basic_rmatrix<float>, basic_rvector<float> >
446  const basic_rvector<float>& vCol,
447  const basic_rvector<float>& vRow,
448  float dAlpha)
449 {
450  CVM_ASSERT(m.get(), vCol.size()* vRow.size()* sizeof(float))
451  SGER(vCol._psize(), vRow._psize(), &dAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
452 }
453 
454 template <>
455 CVM_API void __ger<double, basic_rmatrix<double>, basic_rvector<double> >
457  const basic_rvector<double>& vCol,
458  const basic_rvector<double>& vRow,
459  double dAlpha)
460 {
461  CVM_ASSERT(m.get(), vCol.size()* vRow.size()* sizeof(double))
462  DGER(vCol._psize(), vRow._psize(), &dAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
463 }
464 
466 template <>
467 CVM_API void __geru<std::complex<float>, basic_cmatrix<float, std::complex<float> >, basic_cvector<float, std::complex<float> > >
468  (basic_cmatrix<float, std::complex<float> >& m,
471  std::complex<float> cAlpha)
472 {
473  CVM_ASSERT(m, vCol.size()* vRow.size()* sizeof(std::complex<float>))
474  CGERU(vCol._psize(), vRow._psize(), &cAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
475 }
476 
477 template <>
478 CVM_API void __geru<std::complex<double>, basic_cmatrix<double, std::complex<double> >, basic_cvector<double, std::complex<double> > >
479  (basic_cmatrix<double, std::complex<double> >& m,
480  const basic_cvector<double, std::complex<double> >& vCol,
481  const basic_cvector<double, std::complex<double> >& vRow,
482  std::complex<double> cAlpha)
483 {
484  CVM_ASSERT(m, vCol.size()* vRow.size()* sizeof(std::complex<double>))
485  ZGERU(vCol._psize(), vRow._psize(), &cAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
486 }
487 
488 template <>
489 CVM_API void __gerc<std::complex<float>, basic_cmatrix<float, std::complex<float> >, basic_cvector<float, std::complex<float> > >
490  (basic_cmatrix<float, std::complex<float> >& m,
491  const basic_cvector<float, std::complex<float> >& vCol,
492  const basic_cvector<float, std::complex<float> >& vRow,
493  std::complex<float> cAlpha)
494 {
495  CVM_ASSERT(m, vCol.size()* vRow.size()* sizeof(std::complex<float>))
496  CGERC(vCol._psize(), vRow._psize(), &cAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
497 }
498 
499 template <>
500 CVM_API void __gerc<std::complex<double>, basic_cmatrix<double, std::complex<double> >, basic_cvector<double, std::complex<double> > >
501  (basic_cmatrix<double, std::complex<double> >& m,
502  const basic_cvector<double, std::complex<double> >& vCol,
503  const basic_cvector<double, std::complex<double> >& vRow,
504  std::complex<double> cAlpha)
505 {
506  CVM_ASSERT(m, vCol.size()* vRow.size()* sizeof(std::complex<double>))
507  ZGERC(vCol._psize(), vRow._psize(), &cAlpha, vCol, vCol._pincr(), vRow, vRow._pincr(), m, m._pld());
508 }
510 
511 template <>
512 CVM_API void __poequ<float, basic_srsmatrix<float>, basic_rvector<float> >
513  (const basic_srsmatrix<float>& m,
514  basic_rvector<float>& vScalings,
515  float& dCond,
516  float& dMax)
517 {
518  tint nOutInfo = 0;
519  SPOEQU(m._pm(), m, m._pld(), vScalings, &dCond, &dMax, &nOutInfo);
520  _check_negative(CVM_WRONGMKLARG, nOutInfo);
521  _check_positive(CVM_NOTPOSITIVEDIAG, nOutInfo);
522 }
523 
524 template <>
525 CVM_API void __poequ<double, basic_srsmatrix<double>, basic_rvector<double> >
527  basic_rvector<double>& vScalings,
528  double& dCond,
529  double& dMax)
530 {
531  tint nOutInfo = 0;
532  DPOEQU(m._pm(), m, m._pld(), vScalings, &dCond, &dMax, &nOutInfo);
533  _check_negative(CVM_WRONGMKLARG, nOutInfo);
534  _check_positive(CVM_NOTPOSITIVEDIAG, nOutInfo);
535 }
536 
537 template <>
538 CVM_API void __poequ<float, basic_schmatrix<float, std::complex<float> >, basic_rvector<float> >
540  basic_rvector<float>& vScalings,
541  float& dCond,
542  float& dMax)
543 {
544  tint nOutInfo = 0;
545  CPOEQU(m._pm(), m, m._pld(), vScalings, &dCond, &dMax, &nOutInfo);
546  _check_negative(CVM_WRONGMKLARG, nOutInfo);
547  _check_positive(CVM_NOTPOSITIVEDIAG, nOutInfo);
548 }
549 
550 template <>
551 CVM_API void __poequ<double, basic_schmatrix<double, std::complex<double> >, basic_rvector<double> >
553  basic_rvector<double>& vScalings,
554  double& dCond,
555  double& dMax)
556 {
557  tint nOutInfo = 0;
558  ZPOEQU(m._pm(), m, m._pld(), vScalings, &dCond, &dMax, &nOutInfo);
559  _check_negative(CVM_WRONGMKLARG, nOutInfo);
560  _check_positive(CVM_NOTPOSITIVEDIAG, nOutInfo);
561 }
562