Line data Source code
1 : /*************************************************************************
2 : ALGLIB 3.17.0 (source code generated 2020-12-27)
3 : Copyright (c) Sergey Bochkanov (ALGLIB project).
4 :
5 : >>> SOURCE LICENSE >>>
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation (www.fsf.org); either version 2 of the
9 : License, or (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : A copy of the GNU General Public License is available at
17 : http://www.fsf.org/licensing/licenses
18 : >>> END OF LICENSE >>>
19 : *************************************************************************/
20 : #ifdef _MSC_VER
21 : #define _CRT_SECURE_NO_WARNINGS
22 : #endif
23 : #include "stdafx.h"
24 : #include "solvers.h"
25 :
26 : // disable some irrelevant warnings
27 : #if (AE_COMPILER==AE_MSVC) && !defined(AE_ALL_WARNINGS)
28 : #pragma warning(disable:4100)
29 : #pragma warning(disable:4127)
30 : #pragma warning(disable:4611)
31 : #pragma warning(disable:4702)
32 : #pragma warning(disable:4996)
33 : #endif
34 :
35 : /////////////////////////////////////////////////////////////////////////
36 : //
37 : // THIS SECTION CONTAINS IMPLEMENTATION OF C++ INTERFACE
38 : //
39 : /////////////////////////////////////////////////////////////////////////
40 : namespace alglib
41 : {
42 :
43 : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
44 :
45 : #endif
46 :
47 : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
48 :
49 : #endif
50 :
51 : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
52 :
53 : #endif
54 :
55 : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
56 :
57 : #endif
58 :
59 : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
60 :
61 : #endif
62 :
63 : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
64 :
65 : #endif
66 :
67 : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
68 : /*************************************************************************
69 :
70 : *************************************************************************/
71 0 : _densesolverreport_owner::_densesolverreport_owner()
72 : {
73 : jmp_buf _break_jump;
74 : alglib_impl::ae_state _state;
75 :
76 0 : alglib_impl::ae_state_init(&_state);
77 0 : if( setjmp(_break_jump) )
78 : {
79 0 : if( p_struct!=NULL )
80 : {
81 0 : alglib_impl::_densesolverreport_destroy(p_struct);
82 0 : alglib_impl::ae_free(p_struct);
83 : }
84 0 : p_struct = NULL;
85 : #if !defined(AE_NO_EXCEPTIONS)
86 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
87 : #else
88 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
89 : return;
90 : #endif
91 : }
92 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
93 0 : p_struct = NULL;
94 0 : p_struct = (alglib_impl::densesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverreport), &_state);
95 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
96 0 : alglib_impl::_densesolverreport_init(p_struct, &_state, ae_false);
97 0 : ae_state_clear(&_state);
98 0 : }
99 :
100 0 : _densesolverreport_owner::_densesolverreport_owner(const _densesolverreport_owner &rhs)
101 : {
102 : jmp_buf _break_jump;
103 : alglib_impl::ae_state _state;
104 :
105 0 : alglib_impl::ae_state_init(&_state);
106 0 : if( setjmp(_break_jump) )
107 : {
108 0 : if( p_struct!=NULL )
109 : {
110 0 : alglib_impl::_densesolverreport_destroy(p_struct);
111 0 : alglib_impl::ae_free(p_struct);
112 : }
113 0 : p_struct = NULL;
114 : #if !defined(AE_NO_EXCEPTIONS)
115 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
116 : #else
117 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
118 : return;
119 : #endif
120 : }
121 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
122 0 : p_struct = NULL;
123 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverreport copy constructor failure (source is not initialized)", &_state);
124 0 : p_struct = (alglib_impl::densesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverreport), &_state);
125 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
126 0 : alglib_impl::_densesolverreport_init_copy(p_struct, const_cast<alglib_impl::densesolverreport*>(rhs.p_struct), &_state, ae_false);
127 0 : ae_state_clear(&_state);
128 0 : }
129 :
130 0 : _densesolverreport_owner& _densesolverreport_owner::operator=(const _densesolverreport_owner &rhs)
131 : {
132 0 : if( this==&rhs )
133 0 : return *this;
134 : jmp_buf _break_jump;
135 : alglib_impl::ae_state _state;
136 :
137 0 : alglib_impl::ae_state_init(&_state);
138 0 : if( setjmp(_break_jump) )
139 : {
140 : #if !defined(AE_NO_EXCEPTIONS)
141 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
142 : #else
143 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
144 : return *this;
145 : #endif
146 : }
147 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
148 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: densesolverreport assignment constructor failure (destination is not initialized)", &_state);
149 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverreport assignment constructor failure (source is not initialized)", &_state);
150 0 : alglib_impl::_densesolverreport_destroy(p_struct);
151 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
152 0 : alglib_impl::_densesolverreport_init_copy(p_struct, const_cast<alglib_impl::densesolverreport*>(rhs.p_struct), &_state, ae_false);
153 0 : ae_state_clear(&_state);
154 0 : return *this;
155 : }
156 :
157 0 : _densesolverreport_owner::~_densesolverreport_owner()
158 : {
159 0 : if( p_struct!=NULL )
160 : {
161 0 : alglib_impl::_densesolverreport_destroy(p_struct);
162 0 : ae_free(p_struct);
163 : }
164 0 : }
165 :
166 0 : alglib_impl::densesolverreport* _densesolverreport_owner::c_ptr()
167 : {
168 0 : return p_struct;
169 : }
170 :
171 0 : alglib_impl::densesolverreport* _densesolverreport_owner::c_ptr() const
172 : {
173 0 : return const_cast<alglib_impl::densesolverreport*>(p_struct);
174 : }
175 0 : densesolverreport::densesolverreport() : _densesolverreport_owner() ,r1(p_struct->r1),rinf(p_struct->rinf)
176 : {
177 0 : }
178 :
179 0 : densesolverreport::densesolverreport(const densesolverreport &rhs):_densesolverreport_owner(rhs) ,r1(p_struct->r1),rinf(p_struct->rinf)
180 : {
181 0 : }
182 :
183 0 : densesolverreport& densesolverreport::operator=(const densesolverreport &rhs)
184 : {
185 0 : if( this==&rhs )
186 0 : return *this;
187 0 : _densesolverreport_owner::operator=(rhs);
188 0 : return *this;
189 : }
190 :
191 0 : densesolverreport::~densesolverreport()
192 : {
193 0 : }
194 :
195 :
196 : /*************************************************************************
197 :
198 : *************************************************************************/
199 0 : _densesolverlsreport_owner::_densesolverlsreport_owner()
200 : {
201 : jmp_buf _break_jump;
202 : alglib_impl::ae_state _state;
203 :
204 0 : alglib_impl::ae_state_init(&_state);
205 0 : if( setjmp(_break_jump) )
206 : {
207 0 : if( p_struct!=NULL )
208 : {
209 0 : alglib_impl::_densesolverlsreport_destroy(p_struct);
210 0 : alglib_impl::ae_free(p_struct);
211 : }
212 0 : p_struct = NULL;
213 : #if !defined(AE_NO_EXCEPTIONS)
214 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
215 : #else
216 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
217 : return;
218 : #endif
219 : }
220 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
221 0 : p_struct = NULL;
222 0 : p_struct = (alglib_impl::densesolverlsreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverlsreport), &_state);
223 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
224 0 : alglib_impl::_densesolverlsreport_init(p_struct, &_state, ae_false);
225 0 : ae_state_clear(&_state);
226 0 : }
227 :
228 0 : _densesolverlsreport_owner::_densesolverlsreport_owner(const _densesolverlsreport_owner &rhs)
229 : {
230 : jmp_buf _break_jump;
231 : alglib_impl::ae_state _state;
232 :
233 0 : alglib_impl::ae_state_init(&_state);
234 0 : if( setjmp(_break_jump) )
235 : {
236 0 : if( p_struct!=NULL )
237 : {
238 0 : alglib_impl::_densesolverlsreport_destroy(p_struct);
239 0 : alglib_impl::ae_free(p_struct);
240 : }
241 0 : p_struct = NULL;
242 : #if !defined(AE_NO_EXCEPTIONS)
243 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
244 : #else
245 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
246 : return;
247 : #endif
248 : }
249 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
250 0 : p_struct = NULL;
251 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverlsreport copy constructor failure (source is not initialized)", &_state);
252 0 : p_struct = (alglib_impl::densesolverlsreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverlsreport), &_state);
253 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
254 0 : alglib_impl::_densesolverlsreport_init_copy(p_struct, const_cast<alglib_impl::densesolverlsreport*>(rhs.p_struct), &_state, ae_false);
255 0 : ae_state_clear(&_state);
256 0 : }
257 :
258 0 : _densesolverlsreport_owner& _densesolverlsreport_owner::operator=(const _densesolverlsreport_owner &rhs)
259 : {
260 0 : if( this==&rhs )
261 0 : return *this;
262 : jmp_buf _break_jump;
263 : alglib_impl::ae_state _state;
264 :
265 0 : alglib_impl::ae_state_init(&_state);
266 0 : if( setjmp(_break_jump) )
267 : {
268 : #if !defined(AE_NO_EXCEPTIONS)
269 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
270 : #else
271 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
272 : return *this;
273 : #endif
274 : }
275 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
276 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: densesolverlsreport assignment constructor failure (destination is not initialized)", &_state);
277 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverlsreport assignment constructor failure (source is not initialized)", &_state);
278 0 : alglib_impl::_densesolverlsreport_destroy(p_struct);
279 0 : memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
280 0 : alglib_impl::_densesolverlsreport_init_copy(p_struct, const_cast<alglib_impl::densesolverlsreport*>(rhs.p_struct), &_state, ae_false);
281 0 : ae_state_clear(&_state);
282 0 : return *this;
283 : }
284 :
285 0 : _densesolverlsreport_owner::~_densesolverlsreport_owner()
286 : {
287 0 : if( p_struct!=NULL )
288 : {
289 0 : alglib_impl::_densesolverlsreport_destroy(p_struct);
290 0 : ae_free(p_struct);
291 : }
292 0 : }
293 :
294 0 : alglib_impl::densesolverlsreport* _densesolverlsreport_owner::c_ptr()
295 : {
296 0 : return p_struct;
297 : }
298 :
299 0 : alglib_impl::densesolverlsreport* _densesolverlsreport_owner::c_ptr() const
300 : {
301 0 : return const_cast<alglib_impl::densesolverlsreport*>(p_struct);
302 : }
303 0 : densesolverlsreport::densesolverlsreport() : _densesolverlsreport_owner() ,r2(p_struct->r2),cx(&p_struct->cx),n(p_struct->n),k(p_struct->k)
304 : {
305 0 : }
306 :
307 0 : densesolverlsreport::densesolverlsreport(const densesolverlsreport &rhs):_densesolverlsreport_owner(rhs) ,r2(p_struct->r2),cx(&p_struct->cx),n(p_struct->n),k(p_struct->k)
308 : {
309 0 : }
310 :
311 0 : densesolverlsreport& densesolverlsreport::operator=(const densesolverlsreport &rhs)
312 : {
313 0 : if( this==&rhs )
314 0 : return *this;
315 0 : _densesolverlsreport_owner::operator=(rhs);
316 0 : return *this;
317 : }
318 :
319 0 : densesolverlsreport::~densesolverlsreport()
320 : {
321 0 : }
322 :
323 : /*************************************************************************
324 : Dense solver for A*x=b with N*N real matrix A and N*1 real vectorx x and
325 : b. This is "slow-but-feature rich" version of the linear solver. Faster
326 : version is RMatrixSolveFast() function.
327 :
328 : Algorithm features:
329 : * automatic detection of degenerate cases
330 : * condition number estimation
331 : * iterative refinement
332 : * O(N^3) complexity
333 :
334 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
335 : ! by ALGLIB. It estimates condition number of linear system
336 : ! and performs iterative refinement, which results in
337 : ! significant performance penalty when compared with "fast"
338 : ! version which just performs LU decomposition and calls
339 : ! triangular solver.
340 : !
341 : ! This performance penalty is especially visible in the
342 : ! multithreaded mode, because both condition number estimation
343 : ! and iterative refinement are inherently sequential
344 : ! calculations. It is also very significant on small matrices.
345 : !
346 : ! Thus, if you need high performance and if you are pretty sure
347 : ! that your system is well conditioned, we strongly recommend
348 : ! you to use faster solver, RMatrixSolveFast() function.
349 :
350 : ! COMMERCIAL EDITION OF ALGLIB:
351 : !
352 : ! Commercial Edition of ALGLIB includes following important improvements
353 : ! of this function:
354 : ! * high-performance native backend with same C# interface (C# version)
355 : ! * multithreading support (C++ and C# versions)
356 : ! * hardware vendor (Intel) implementations of linear algebra primitives
357 : ! (C++ and C# versions, x86/x64 platform)
358 : !
359 : ! We recommend you to read 'Working with commercial version' section of
360 : ! ALGLIB Reference Manual in order to find out how to use performance-
361 : ! related features provided by commercial edition of ALGLIB.
362 :
363 : INPUT PARAMETERS
364 : A - array[0..N-1,0..N-1], system matrix
365 : N - size of A
366 : B - array[0..N-1], right part
367 :
368 : OUTPUT PARAMETERS
369 : Info - return code:
370 : * -3 matrix is very badly conditioned or exactly singular.
371 : * -1 N<=0 was passed
372 : * 1 task is solved (but matrix A may be ill-conditioned,
373 : check R1/RInf parameters for condition numbers).
374 : Rep - additional report, following fields are set:
375 : * rep.r1 condition number in 1-norm
376 : * rep.rinf condition number in inf-norm
377 : X - array[N], it contains:
378 : * info>0 => solution
379 : * info=-3 => filled by zeros
380 :
381 : -- ALGLIB --
382 : Copyright 27.01.2010 by Bochkanov Sergey
383 : *************************************************************************/
384 0 : void rmatrixsolve(const real_2d_array &a, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
385 : {
386 : jmp_buf _break_jump;
387 : alglib_impl::ae_state _alglib_env_state;
388 0 : alglib_impl::ae_state_init(&_alglib_env_state);
389 0 : if( setjmp(_break_jump) )
390 : {
391 : #if !defined(AE_NO_EXCEPTIONS)
392 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
393 : #else
394 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
395 : return;
396 : #endif
397 : }
398 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
399 0 : if( _xparams.flags!=0x0 )
400 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
401 0 : alglib_impl::rmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
402 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
403 0 : return;
404 : }
405 :
406 : /*************************************************************************
407 : Dense solver.
408 :
409 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
410 : real matrix, x and b are vectors. This is a "fast" version of linear
411 : solver which does NOT provide any additional functions like condition
412 : number estimation or iterative refinement.
413 :
414 : Algorithm features:
415 : * efficient algorithm O(N^3) complexity
416 : * no performance overhead from additional functionality
417 :
418 : If you need condition number estimation or iterative refinement, use more
419 : feature-rich version - RMatrixSolve().
420 :
421 : ! COMMERCIAL EDITION OF ALGLIB:
422 : !
423 : ! Commercial Edition of ALGLIB includes following important improvements
424 : ! of this function:
425 : ! * high-performance native backend with same C# interface (C# version)
426 : ! * multithreading support (C++ and C# versions)
427 : ! * hardware vendor (Intel) implementations of linear algebra primitives
428 : ! (C++ and C# versions, x86/x64 platform)
429 : !
430 : ! We recommend you to read 'Working with commercial version' section of
431 : ! ALGLIB Reference Manual in order to find out how to use performance-
432 : ! related features provided by commercial edition of ALGLIB.
433 :
434 : INPUT PARAMETERS
435 : A - array[0..N-1,0..N-1], system matrix
436 : N - size of A
437 : B - array[0..N-1], right part
438 :
439 : OUTPUT PARAMETERS
440 : Info - return code:
441 : * -3 matrix is exactly singular (ill conditioned matrices
442 : are not recognized).
443 : * -1 N<=0 was passed
444 : * 1 task is solved
445 : B - array[N]:
446 : * info>0 => overwritten by solution
447 : * info=-3 => filled by zeros
448 :
449 : -- ALGLIB --
450 : Copyright 16.03.2015 by Bochkanov Sergey
451 : *************************************************************************/
452 0 : void rmatrixsolvefast(const real_2d_array &a, const ae_int_t n, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
453 : {
454 : jmp_buf _break_jump;
455 : alglib_impl::ae_state _alglib_env_state;
456 0 : alglib_impl::ae_state_init(&_alglib_env_state);
457 0 : if( setjmp(_break_jump) )
458 : {
459 : #if !defined(AE_NO_EXCEPTIONS)
460 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
461 : #else
462 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
463 : return;
464 : #endif
465 : }
466 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
467 0 : if( _xparams.flags!=0x0 )
468 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
469 0 : alglib_impl::rmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
470 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
471 0 : return;
472 : }
473 :
474 : /*************************************************************************
475 : Dense solver.
476 :
477 : Similar to RMatrixSolve() but solves task with multiple right parts (where
478 : b and x are NxM matrices). This is "slow-but-robust" version of linear
479 : solver with additional functionality like condition number estimation.
480 : There also exists faster version - RMatrixSolveMFast().
481 :
482 : Algorithm features:
483 : * automatic detection of degenerate cases
484 : * condition number estimation
485 : * optional iterative refinement
486 : * O(N^3+M*N^2) complexity
487 :
488 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
489 : ! by ALGLIB. It estimates condition number of linear system
490 : ! and performs iterative refinement, which results in
491 : ! significant performance penalty when compared with "fast"
492 : ! version which just performs LU decomposition and calls
493 : ! triangular solver.
494 : !
495 : ! This performance penalty is especially visible in the
496 : ! multithreaded mode, because both condition number estimation
497 : ! and iterative refinement are inherently sequential
498 : ! calculations. It also very significant on small matrices.
499 : !
500 : ! Thus, if you need high performance and if you are pretty sure
501 : ! that your system is well conditioned, we strongly recommend
502 : ! you to use faster solver, RMatrixSolveMFast() function.
503 :
504 : ! COMMERCIAL EDITION OF ALGLIB:
505 : !
506 : ! Commercial Edition of ALGLIB includes following important improvements
507 : ! of this function:
508 : ! * high-performance native backend with same C# interface (C# version)
509 : ! * multithreading support (C++ and C# versions)
510 : ! * hardware vendor (Intel) implementations of linear algebra primitives
511 : ! (C++ and C# versions, x86/x64 platform)
512 : !
513 : ! We recommend you to read 'Working with commercial version' section of
514 : ! ALGLIB Reference Manual in order to find out how to use performance-
515 : ! related features provided by commercial edition of ALGLIB.
516 :
517 : INPUT PARAMETERS
518 : A - array[0..N-1,0..N-1], system matrix
519 : N - size of A
520 : B - array[0..N-1,0..M-1], right part
521 : M - right part size
522 : RFS - iterative refinement switch:
523 : * True - refinement is used.
524 : Less performance, more precision.
525 : * False - refinement is not used.
526 : More performance, less precision.
527 :
528 : OUTPUT PARAMETERS
529 : Info - return code:
530 : * -3 A is ill conditioned or singular.
531 : X is filled by zeros in such cases.
532 : * -1 N<=0 was passed
533 : * 1 task is solved (but matrix A may be ill-conditioned,
534 : check R1/RInf parameters for condition numbers).
535 : Rep - additional report, following fields are set:
536 : * rep.r1 condition number in 1-norm
537 : * rep.rinf condition number in inf-norm
538 : X - array[N], it contains:
539 : * info>0 => solution
540 : * info=-3 => filled by zeros
541 :
542 :
543 : -- ALGLIB --
544 : Copyright 27.01.2010 by Bochkanov Sergey
545 : *************************************************************************/
546 0 : void rmatrixsolvem(const real_2d_array &a, const ae_int_t n, const real_2d_array &b, const ae_int_t m, const bool rfs, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
547 : {
548 : jmp_buf _break_jump;
549 : alglib_impl::ae_state _alglib_env_state;
550 0 : alglib_impl::ae_state_init(&_alglib_env_state);
551 0 : if( setjmp(_break_jump) )
552 : {
553 : #if !defined(AE_NO_EXCEPTIONS)
554 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
555 : #else
556 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
557 : return;
558 : #endif
559 : }
560 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
561 0 : if( _xparams.flags!=0x0 )
562 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
563 0 : alglib_impl::rmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, rfs, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
564 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
565 0 : return;
566 : }
567 :
568 : /*************************************************************************
569 : Dense solver.
570 :
571 : Similar to RMatrixSolve() but solves task with multiple right parts (where
572 : b and x are NxM matrices). This is "fast" version of linear solver which
573 : does NOT offer additional functions like condition number estimation or
574 : iterative refinement.
575 :
576 : Algorithm features:
577 : * O(N^3+M*N^2) complexity
578 : * no additional functionality, highest performance
579 :
580 : ! COMMERCIAL EDITION OF ALGLIB:
581 : !
582 : ! Commercial Edition of ALGLIB includes following important improvements
583 : ! of this function:
584 : ! * high-performance native backend with same C# interface (C# version)
585 : ! * multithreading support (C++ and C# versions)
586 : ! * hardware vendor (Intel) implementations of linear algebra primitives
587 : ! (C++ and C# versions, x86/x64 platform)
588 : !
589 : ! We recommend you to read 'Working with commercial version' section of
590 : ! ALGLIB Reference Manual in order to find out how to use performance-
591 : ! related features provided by commercial edition of ALGLIB.
592 :
593 : INPUT PARAMETERS
594 : A - array[0..N-1,0..N-1], system matrix
595 : N - size of A
596 : B - array[0..N-1,0..M-1], right part
597 : M - right part size
598 : RFS - iterative refinement switch:
599 : * True - refinement is used.
600 : Less performance, more precision.
601 : * False - refinement is not used.
602 : More performance, less precision.
603 :
604 : OUTPUT PARAMETERS
605 : Info - return code:
606 : * -3 matrix is exactly singular (ill conditioned matrices
607 : are not recognized).
608 : X is filled by zeros in such cases.
609 : * -1 N<=0 was passed
610 : * 1 task is solved
611 : Rep - additional report, following fields are set:
612 : * rep.r1 condition number in 1-norm
613 : * rep.rinf condition number in inf-norm
614 : B - array[N]:
615 : * info>0 => overwritten by solution
616 : * info=-3 => filled by zeros
617 :
618 :
619 : -- ALGLIB --
620 : Copyright 27.01.2010 by Bochkanov Sergey
621 : *************************************************************************/
622 0 : void rmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
623 : {
624 : jmp_buf _break_jump;
625 : alglib_impl::ae_state _alglib_env_state;
626 0 : alglib_impl::ae_state_init(&_alglib_env_state);
627 0 : if( setjmp(_break_jump) )
628 : {
629 : #if !defined(AE_NO_EXCEPTIONS)
630 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
631 : #else
632 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
633 : return;
634 : #endif
635 : }
636 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
637 0 : if( _xparams.flags!=0x0 )
638 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
639 0 : alglib_impl::rmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
640 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
641 0 : return;
642 : }
643 :
644 : /*************************************************************************
645 : Dense solver.
646 :
647 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
648 : real matrix given by its LU decomposition, x and b are real vectors. This
649 : is "slow-but-robust" version of the linear LU-based solver. Faster version
650 : is RMatrixLUSolveFast() function.
651 :
652 : Algorithm features:
653 : * automatic detection of degenerate cases
654 : * O(N^2) complexity
655 : * condition number estimation
656 :
657 : No iterative refinement is provided because exact form of original matrix
658 : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you
659 : need iterative refinement.
660 :
661 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
662 : ! by ALGLIB. It estimates condition number of linear system,
663 : ! which results in 10-15x performance penalty when compared
664 : ! with "fast" version which just calls triangular solver.
665 : !
666 : ! This performance penalty is insignificant when compared with
667 : ! cost of large LU decomposition. However, if you call this
668 : ! function many times for the same left side, this overhead
669 : ! BECOMES significant. It also becomes significant for small-
670 : ! scale problems.
671 : !
672 : ! In such cases we strongly recommend you to use faster solver,
673 : ! RMatrixLUSolveFast() function.
674 :
675 : INPUT PARAMETERS
676 : LUA - array[N,N], LU decomposition, RMatrixLU result
677 : P - array[N], pivots array, RMatrixLU result
678 : N - size of A
679 : B - array[N], right part
680 :
681 : OUTPUT PARAMETERS
682 : Info - return code:
683 : * -3 matrix is very badly conditioned or exactly singular.
684 : * -1 N<=0 was passed
685 : * 1 task is solved (but matrix A may be ill-conditioned,
686 : check R1/RInf parameters for condition numbers).
687 : Rep - additional report, following fields are set:
688 : * rep.r1 condition number in 1-norm
689 : * rep.rinf condition number in inf-norm
690 : X - array[N], it contains:
691 : * info>0 => solution
692 : * info=-3 => filled by zeros
693 :
694 :
695 : -- ALGLIB --
696 : Copyright 27.01.2010 by Bochkanov Sergey
697 : *************************************************************************/
698 0 : void rmatrixlusolve(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
699 : {
700 : jmp_buf _break_jump;
701 : alglib_impl::ae_state _alglib_env_state;
702 0 : alglib_impl::ae_state_init(&_alglib_env_state);
703 0 : if( setjmp(_break_jump) )
704 : {
705 : #if !defined(AE_NO_EXCEPTIONS)
706 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
707 : #else
708 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
709 : return;
710 : #endif
711 : }
712 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
713 0 : if( _xparams.flags!=0x0 )
714 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
715 0 : alglib_impl::rmatrixlusolve(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
716 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
717 0 : return;
718 : }
719 :
720 : /*************************************************************************
721 : Dense solver.
722 :
723 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
724 : real matrix given by its LU decomposition, x and b are real vectors. This
725 : is "fast-without-any-checks" version of the linear LU-based solver. Slower
726 : but more robust version is RMatrixLUSolve() function.
727 :
728 : Algorithm features:
729 : * O(N^2) complexity
730 : * fast algorithm without ANY additional checks, just triangular solver
731 :
732 : INPUT PARAMETERS
733 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
734 : P - array[0..N-1], pivots array, RMatrixLU result
735 : N - size of A
736 : B - array[0..N-1], right part
737 :
738 : OUTPUT PARAMETERS
739 : Info - return code:
740 : * -3 matrix is exactly singular (ill conditioned matrices
741 : are not recognized).
742 : X is filled by zeros in such cases.
743 : * -1 N<=0 was passed
744 : * 1 task is solved
745 : B - array[N]:
746 : * info>0 => overwritten by solution
747 : * info=-3 => filled by zeros
748 :
749 : -- ALGLIB --
750 : Copyright 18.03.2015 by Bochkanov Sergey
751 : *************************************************************************/
752 0 : void rmatrixlusolvefast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
753 : {
754 : jmp_buf _break_jump;
755 : alglib_impl::ae_state _alglib_env_state;
756 0 : alglib_impl::ae_state_init(&_alglib_env_state);
757 0 : if( setjmp(_break_jump) )
758 : {
759 : #if !defined(AE_NO_EXCEPTIONS)
760 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
761 : #else
762 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
763 : return;
764 : #endif
765 : }
766 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
767 0 : if( _xparams.flags!=0x0 )
768 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
769 0 : alglib_impl::rmatrixlusolvefast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
770 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
771 0 : return;
772 : }
773 :
774 : /*************************************************************************
775 : Dense solver.
776 :
777 : Similar to RMatrixLUSolve() but solves task with multiple right parts
778 : (where b and x are NxM matrices). This is "robust-but-slow" version of
779 : LU-based solver which performs additional checks for non-degeneracy of
780 : inputs (condition number estimation). If you need best performance, use
781 : "fast-without-any-checks" version, RMatrixLUSolveMFast().
782 :
783 : Algorithm features:
784 : * automatic detection of degenerate cases
785 : * O(M*N^2) complexity
786 : * condition number estimation
787 :
788 : No iterative refinement is provided because exact form of original matrix
789 : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you
790 : need iterative refinement.
791 :
792 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
793 : ! by ALGLIB. It estimates condition number of linear system,
794 : ! which results in significant performance penalty when
795 : ! compared with "fast" version which just calls triangular
796 : ! solver.
797 : !
798 : ! This performance penalty is especially apparent when you use
799 : ! ALGLIB parallel capabilities (condition number estimation is
800 : ! inherently sequential). It also becomes significant for
801 : ! small-scale problems.
802 : !
803 : ! In such cases we strongly recommend you to use faster solver,
804 : ! RMatrixLUSolveMFast() function.
805 :
806 : ! COMMERCIAL EDITION OF ALGLIB:
807 : !
808 : ! Commercial Edition of ALGLIB includes following important improvements
809 : ! of this function:
810 : ! * high-performance native backend with same C# interface (C# version)
811 : ! * multithreading support (C++ and C# versions)
812 : ! * hardware vendor (Intel) implementations of linear algebra primitives
813 : ! (C++ and C# versions, x86/x64 platform)
814 : !
815 : ! We recommend you to read 'Working with commercial version' section of
816 : ! ALGLIB Reference Manual in order to find out how to use performance-
817 : ! related features provided by commercial edition of ALGLIB.
818 :
819 : INPUT PARAMETERS
820 : LUA - array[N,N], LU decomposition, RMatrixLU result
821 : P - array[N], pivots array, RMatrixLU result
822 : N - size of A
823 : B - array[0..N-1,0..M-1], right part
824 : M - right part size
825 :
826 : OUTPUT PARAMETERS
827 : Info - return code:
828 : * -3 matrix is very badly conditioned or exactly singular.
829 : X is filled by zeros in such cases.
830 : * -1 N<=0 was passed
831 : * 1 task is solved (but matrix A may be ill-conditioned,
832 : check R1/RInf parameters for condition numbers).
833 : Rep - additional report, following fields are set:
834 : * rep.r1 condition number in 1-norm
835 : * rep.rinf condition number in inf-norm
836 : X - array[N,M], it contains:
837 : * info>0 => solution
838 : * info=-3 => filled by zeros
839 :
840 :
841 : -- ALGLIB --
842 : Copyright 27.01.2010 by Bochkanov Sergey
843 : *************************************************************************/
844 0 : void rmatrixlusolvem(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
845 : {
846 : jmp_buf _break_jump;
847 : alglib_impl::ae_state _alglib_env_state;
848 0 : alglib_impl::ae_state_init(&_alglib_env_state);
849 0 : if( setjmp(_break_jump) )
850 : {
851 : #if !defined(AE_NO_EXCEPTIONS)
852 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
853 : #else
854 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
855 : return;
856 : #endif
857 : }
858 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
859 0 : if( _xparams.flags!=0x0 )
860 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
861 0 : alglib_impl::rmatrixlusolvem(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
862 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
863 0 : return;
864 : }
865 :
866 : /*************************************************************************
867 : Dense solver.
868 :
869 : Similar to RMatrixLUSolve() but solves task with multiple right parts,
870 : where b and x are NxM matrices. This is "fast-without-any-checks" version
871 : of LU-based solver. It does not estimate condition number of a system,
872 : so it is extremely fast. If you need better detection of near-degenerate
873 : cases, use RMatrixLUSolveM() function.
874 :
875 : Algorithm features:
876 : * O(M*N^2) complexity
877 : * fast algorithm without ANY additional checks, just triangular solver
878 :
879 : ! COMMERCIAL EDITION OF ALGLIB:
880 : !
881 : ! Commercial Edition of ALGLIB includes following important improvements
882 : ! of this function:
883 : ! * high-performance native backend with same C# interface (C# version)
884 : ! * multithreading support (C++ and C# versions)
885 : ! * hardware vendor (Intel) implementations of linear algebra primitives
886 : ! (C++ and C# versions, x86/x64 platform)
887 : !
888 : ! We recommend you to read 'Working with commercial version' section of
889 : ! ALGLIB Reference Manual in order to find out how to use performance-
890 : ! related features provided by commercial edition of ALGLIB.
891 :
892 : INPUT PARAMETERS:
893 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
894 : P - array[0..N-1], pivots array, RMatrixLU result
895 : N - size of A
896 : B - array[0..N-1,0..M-1], right part
897 : M - right part size
898 :
899 : OUTPUT PARAMETERS:
900 : Info - return code:
901 : * -3 matrix is exactly singular (ill conditioned matrices
902 : are not recognized).
903 : * -1 N<=0 was passed
904 : * 1 task is solved
905 : B - array[N,M]:
906 : * info>0 => overwritten by solution
907 : * info=-3 => filled by zeros
908 :
909 : -- ALGLIB --
910 : Copyright 18.03.2015 by Bochkanov Sergey
911 : *************************************************************************/
912 0 : void rmatrixlusolvemfast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
913 : {
914 : jmp_buf _break_jump;
915 : alglib_impl::ae_state _alglib_env_state;
916 0 : alglib_impl::ae_state_init(&_alglib_env_state);
917 0 : if( setjmp(_break_jump) )
918 : {
919 : #if !defined(AE_NO_EXCEPTIONS)
920 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
921 : #else
922 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
923 : return;
924 : #endif
925 : }
926 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
927 0 : if( _xparams.flags!=0x0 )
928 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
929 0 : alglib_impl::rmatrixlusolvemfast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
930 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
931 0 : return;
932 : }
933 :
934 : /*************************************************************************
935 : Dense solver.
936 :
937 : This subroutine solves a system A*x=b, where BOTH ORIGINAL A AND ITS
938 : LU DECOMPOSITION ARE KNOWN. You can use it if for some reasons you have
939 : both A and its LU decomposition.
940 :
941 : Algorithm features:
942 : * automatic detection of degenerate cases
943 : * condition number estimation
944 : * iterative refinement
945 : * O(N^2) complexity
946 :
947 : INPUT PARAMETERS
948 : A - array[0..N-1,0..N-1], system matrix
949 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
950 : P - array[0..N-1], pivots array, RMatrixLU result
951 : N - size of A
952 : B - array[0..N-1], right part
953 :
954 : OUTPUT PARAMETERS
955 : Info - return code:
956 : * -3 matrix is very badly conditioned or exactly singular.
957 : * -1 N<=0 was passed
958 : * 1 task is solved (but matrix A may be ill-conditioned,
959 : check R1/RInf parameters for condition numbers).
960 : Rep - additional report, following fields are set:
961 : * rep.r1 condition number in 1-norm
962 : * rep.rinf condition number in inf-norm
963 : X - array[N], it contains:
964 : * info>0 => solution
965 : * info=-3 => filled by zeros
966 :
967 : -- ALGLIB --
968 : Copyright 27.01.2010 by Bochkanov Sergey
969 : *************************************************************************/
970 0 : void rmatrixmixedsolve(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
971 : {
972 : jmp_buf _break_jump;
973 : alglib_impl::ae_state _alglib_env_state;
974 0 : alglib_impl::ae_state_init(&_alglib_env_state);
975 0 : if( setjmp(_break_jump) )
976 : {
977 : #if !defined(AE_NO_EXCEPTIONS)
978 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
979 : #else
980 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
981 : return;
982 : #endif
983 : }
984 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
985 0 : if( _xparams.flags!=0x0 )
986 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
987 0 : alglib_impl::rmatrixmixedsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
988 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
989 0 : return;
990 : }
991 :
992 : /*************************************************************************
993 : Dense solver.
994 :
995 : Similar to RMatrixMixedSolve() but solves task with multiple right parts
996 : (where b and x are NxM matrices).
997 :
998 : Algorithm features:
999 : * automatic detection of degenerate cases
1000 : * condition number estimation
1001 : * iterative refinement
1002 : * O(M*N^2) complexity
1003 :
1004 : INPUT PARAMETERS
1005 : A - array[0..N-1,0..N-1], system matrix
1006 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
1007 : P - array[0..N-1], pivots array, RMatrixLU result
1008 : N - size of A
1009 : B - array[0..N-1,0..M-1], right part
1010 : M - right part size
1011 :
1012 : OUTPUT PARAMETERS
1013 : Info - return code:
1014 : * -3 matrix is very badly conditioned or exactly singular.
1015 : * -1 N<=0 was passed
1016 : * 1 task is solved (but matrix A may be ill-conditioned,
1017 : check R1/RInf parameters for condition numbers).
1018 : Rep - additional report, following fields are set:
1019 : * rep.r1 condition number in 1-norm
1020 : * rep.rinf condition number in inf-norm
1021 : X - array[N,M], it contains:
1022 : * info>0 => solution
1023 : * info=-3 => filled by zeros
1024 :
1025 : -- ALGLIB --
1026 : Copyright 27.01.2010 by Bochkanov Sergey
1027 : *************************************************************************/
1028 0 : void rmatrixmixedsolvem(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
1029 : {
1030 : jmp_buf _break_jump;
1031 : alglib_impl::ae_state _alglib_env_state;
1032 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1033 0 : if( setjmp(_break_jump) )
1034 : {
1035 : #if !defined(AE_NO_EXCEPTIONS)
1036 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1037 : #else
1038 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1039 : return;
1040 : #endif
1041 : }
1042 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1043 0 : if( _xparams.flags!=0x0 )
1044 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1045 0 : alglib_impl::rmatrixmixedsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1046 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1047 0 : return;
1048 : }
1049 :
1050 : /*************************************************************************
1051 : Complex dense solver for A*X=B with N*N complex matrix A, N*M complex
1052 : matrices X and B. "Slow-but-feature-rich" version which provides
1053 : additional functions, at the cost of slower performance. Faster version
1054 : may be invoked with CMatrixSolveMFast() function.
1055 :
1056 : Algorithm features:
1057 : * automatic detection of degenerate cases
1058 : * condition number estimation
1059 : * iterative refinement
1060 : * O(N^3+M*N^2) complexity
1061 :
1062 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1063 : ! by ALGLIB. It estimates condition number of linear system
1064 : ! and performs iterative refinement, which results in
1065 : ! significant performance penalty when compared with "fast"
1066 : ! version which just performs LU decomposition and calls
1067 : ! triangular solver.
1068 : !
1069 : ! This performance penalty is especially visible in the
1070 : ! multithreaded mode, because both condition number estimation
1071 : ! and iterative refinement are inherently sequential
1072 : ! calculations.
1073 : !
1074 : ! Thus, if you need high performance and if you are pretty sure
1075 : ! that your system is well conditioned, we strongly recommend
1076 : ! you to use faster solver, CMatrixSolveMFast() function.
1077 :
1078 : ! COMMERCIAL EDITION OF ALGLIB:
1079 : !
1080 : ! Commercial Edition of ALGLIB includes following important improvements
1081 : ! of this function:
1082 : ! * high-performance native backend with same C# interface (C# version)
1083 : ! * multithreading support (C++ and C# versions)
1084 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1085 : ! (C++ and C# versions, x86/x64 platform)
1086 : !
1087 : ! We recommend you to read 'Working with commercial version' section of
1088 : ! ALGLIB Reference Manual in order to find out how to use performance-
1089 : ! related features provided by commercial edition of ALGLIB.
1090 :
1091 : INPUT PARAMETERS
1092 : A - array[0..N-1,0..N-1], system matrix
1093 : N - size of A
1094 : B - array[0..N-1,0..M-1], right part
1095 : M - right part size
1096 : RFS - iterative refinement switch:
1097 : * True - refinement is used.
1098 : Less performance, more precision.
1099 : * False - refinement is not used.
1100 : More performance, less precision.
1101 :
1102 : OUTPUT PARAMETERS
1103 : Info - return code:
1104 : * -3 matrix is very badly conditioned or exactly singular.
1105 : X is filled by zeros in such cases.
1106 : * -1 N<=0 was passed
1107 : * 1 task is solved (but matrix A may be ill-conditioned,
1108 : check R1/RInf parameters for condition numbers).
1109 : Rep - additional report, following fields are set:
1110 : * rep.r1 condition number in 1-norm
1111 : * rep.rinf condition number in inf-norm
1112 : X - array[N,M], it contains:
1113 : * info>0 => solution
1114 : * info=-3 => filled by zeros
1115 :
1116 : -- ALGLIB --
1117 : Copyright 27.01.2010 by Bochkanov Sergey
1118 : *************************************************************************/
1119 0 : void cmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, const bool rfs, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
1120 : {
1121 : jmp_buf _break_jump;
1122 : alglib_impl::ae_state _alglib_env_state;
1123 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1124 0 : if( setjmp(_break_jump) )
1125 : {
1126 : #if !defined(AE_NO_EXCEPTIONS)
1127 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1128 : #else
1129 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1130 : return;
1131 : #endif
1132 : }
1133 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1134 0 : if( _xparams.flags!=0x0 )
1135 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1136 0 : alglib_impl::cmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, rfs, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1137 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1138 0 : return;
1139 : }
1140 :
1141 : /*************************************************************************
1142 : Complex dense solver for A*X=B with N*N complex matrix A, N*M complex
1143 : matrices X and B. "Fast-but-lightweight" version which provides just
1144 : triangular solver - and no additional functions like iterative refinement
1145 : or condition number estimation.
1146 :
1147 : Algorithm features:
1148 : * O(N^3+M*N^2) complexity
1149 : * no additional time consuming functions
1150 :
1151 : ! COMMERCIAL EDITION OF ALGLIB:
1152 : !
1153 : ! Commercial Edition of ALGLIB includes following important improvements
1154 : ! of this function:
1155 : ! * high-performance native backend with same C# interface (C# version)
1156 : ! * multithreading support (C++ and C# versions)
1157 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1158 : ! (C++ and C# versions, x86/x64 platform)
1159 : !
1160 : ! We recommend you to read 'Working with commercial version' section of
1161 : ! ALGLIB Reference Manual in order to find out how to use performance-
1162 : ! related features provided by commercial edition of ALGLIB.
1163 :
1164 : INPUT PARAMETERS
1165 : A - array[0..N-1,0..N-1], system matrix
1166 : N - size of A
1167 : B - array[0..N-1,0..M-1], right part
1168 : M - right part size
1169 :
1170 : OUTPUT PARAMETERS:
1171 : Info - return code:
1172 : * -3 matrix is exactly singular (ill conditioned matrices
1173 : are not recognized).
1174 : * -1 N<=0 was passed
1175 : * 1 task is solved
1176 : B - array[N,M]:
1177 : * info>0 => overwritten by solution
1178 : * info=-3 => filled by zeros
1179 :
1180 : -- ALGLIB --
1181 : Copyright 16.03.2015 by Bochkanov Sergey
1182 : *************************************************************************/
1183 0 : void cmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
1184 : {
1185 : jmp_buf _break_jump;
1186 : alglib_impl::ae_state _alglib_env_state;
1187 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1188 0 : if( setjmp(_break_jump) )
1189 : {
1190 : #if !defined(AE_NO_EXCEPTIONS)
1191 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1192 : #else
1193 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1194 : return;
1195 : #endif
1196 : }
1197 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1198 0 : if( _xparams.flags!=0x0 )
1199 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1200 0 : alglib_impl::cmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
1201 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1202 0 : return;
1203 : }
1204 :
1205 : /*************************************************************************
1206 : Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex
1207 : vectors x and b. "Slow-but-feature-rich" version of the solver.
1208 :
1209 : Algorithm features:
1210 : * automatic detection of degenerate cases
1211 : * condition number estimation
1212 : * iterative refinement
1213 : * O(N^3) complexity
1214 :
1215 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1216 : ! by ALGLIB. It estimates condition number of linear system
1217 : ! and performs iterative refinement, which results in
1218 : ! significant performance penalty when compared with "fast"
1219 : ! version which just performs LU decomposition and calls
1220 : ! triangular solver.
1221 : !
1222 : ! This performance penalty is especially visible in the
1223 : ! multithreaded mode, because both condition number estimation
1224 : ! and iterative refinement are inherently sequential
1225 : ! calculations.
1226 : !
1227 : ! Thus, if you need high performance and if you are pretty sure
1228 : ! that your system is well conditioned, we strongly recommend
1229 : ! you to use faster solver, CMatrixSolveFast() function.
1230 :
1231 : ! COMMERCIAL EDITION OF ALGLIB:
1232 : !
1233 : ! Commercial Edition of ALGLIB includes following important improvements
1234 : ! of this function:
1235 : ! * high-performance native backend with same C# interface (C# version)
1236 : ! * multithreading support (C++ and C# versions)
1237 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1238 : ! (C++ and C# versions, x86/x64 platform)
1239 : !
1240 : ! We recommend you to read 'Working with commercial version' section of
1241 : ! ALGLIB Reference Manual in order to find out how to use performance-
1242 : ! related features provided by commercial edition of ALGLIB.
1243 :
1244 : INPUT PARAMETERS
1245 : A - array[0..N-1,0..N-1], system matrix
1246 : N - size of A
1247 : B - array[0..N-1], right part
1248 :
1249 : OUTPUT PARAMETERS
1250 : Info - return code:
1251 : * -3 matrix is very badly conditioned or exactly singular.
1252 : * -1 N<=0 was passed
1253 : * 1 task is solved (but matrix A may be ill-conditioned,
1254 : check R1/RInf parameters for condition numbers).
1255 : Rep - additional report, following fields are set:
1256 : * rep.r1 condition number in 1-norm
1257 : * rep.rinf condition number in inf-norm
1258 : X - array[N], it contains:
1259 : * info>0 => solution
1260 : * info=-3 => filled by zeros
1261 :
1262 : -- ALGLIB --
1263 : Copyright 27.01.2010 by Bochkanov Sergey
1264 : *************************************************************************/
1265 0 : void cmatrixsolve(const complex_2d_array &a, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
1266 : {
1267 : jmp_buf _break_jump;
1268 : alglib_impl::ae_state _alglib_env_state;
1269 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1270 0 : if( setjmp(_break_jump) )
1271 : {
1272 : #if !defined(AE_NO_EXCEPTIONS)
1273 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1274 : #else
1275 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1276 : return;
1277 : #endif
1278 : }
1279 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1280 0 : if( _xparams.flags!=0x0 )
1281 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1282 0 : alglib_impl::cmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
1283 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1284 0 : return;
1285 : }
1286 :
1287 : /*************************************************************************
1288 : Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex
1289 : vectors x and b. "Fast-but-lightweight" version of the solver.
1290 :
1291 : Algorithm features:
1292 : * O(N^3) complexity
1293 : * no additional time consuming features, just triangular solver
1294 :
1295 : ! COMMERCIAL EDITION OF ALGLIB:
1296 : !
1297 : ! Commercial Edition of ALGLIB includes following important improvements
1298 : ! of this function:
1299 : ! * high-performance native backend with same C# interface (C# version)
1300 : ! * multithreading support (C++ and C# versions)
1301 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1302 : ! (C++ and C# versions, x86/x64 platform)
1303 : !
1304 : ! We recommend you to read 'Working with commercial version' section of
1305 : ! ALGLIB Reference Manual in order to find out how to use performance-
1306 : ! related features provided by commercial edition of ALGLIB.
1307 :
1308 : INPUT PARAMETERS:
1309 : A - array[0..N-1,0..N-1], system matrix
1310 : N - size of A
1311 : B - array[0..N-1], right part
1312 :
1313 : OUTPUT PARAMETERS:
1314 : Info - return code:
1315 : * -3 matrix is exactly singular (ill conditioned matrices
1316 : are not recognized).
1317 : * -1 N<=0 was passed
1318 : * 1 task is solved
1319 : B - array[N]:
1320 : * info>0 => overwritten by solution
1321 : * info=-3 => filled by zeros
1322 :
1323 : -- ALGLIB --
1324 : Copyright 27.01.2010 by Bochkanov Sergey
1325 : *************************************************************************/
1326 0 : void cmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
1327 : {
1328 : jmp_buf _break_jump;
1329 : alglib_impl::ae_state _alglib_env_state;
1330 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1331 0 : if( setjmp(_break_jump) )
1332 : {
1333 : #if !defined(AE_NO_EXCEPTIONS)
1334 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1335 : #else
1336 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1337 : return;
1338 : #endif
1339 : }
1340 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1341 0 : if( _xparams.flags!=0x0 )
1342 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1343 0 : alglib_impl::cmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
1344 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1345 0 : return;
1346 : }
1347 :
1348 : /*************************************************************************
1349 : Dense solver for A*X=B with N*N complex A given by its LU decomposition,
1350 : and N*M matrices X and B (multiple right sides). "Slow-but-feature-rich"
1351 : version of the solver.
1352 :
1353 : Algorithm features:
1354 : * automatic detection of degenerate cases
1355 : * O(M*N^2) complexity
1356 : * condition number estimation
1357 :
1358 : No iterative refinement is provided because exact form of original matrix
1359 : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you
1360 : need iterative refinement.
1361 :
1362 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1363 : ! by ALGLIB. It estimates condition number of linear system,
1364 : ! which results in significant performance penalty when
1365 : ! compared with "fast" version which just calls triangular
1366 : ! solver.
1367 : !
1368 : ! This performance penalty is especially apparent when you use
1369 : ! ALGLIB parallel capabilities (condition number estimation is
1370 : ! inherently sequential). It also becomes significant for
1371 : ! small-scale problems.
1372 : !
1373 : ! In such cases we strongly recommend you to use faster solver,
1374 : ! CMatrixLUSolveMFast() function.
1375 :
1376 : ! COMMERCIAL EDITION OF ALGLIB:
1377 : !
1378 : ! Commercial Edition of ALGLIB includes following important improvements
1379 : ! of this function:
1380 : ! * high-performance native backend with same C# interface (C# version)
1381 : ! * multithreading support (C++ and C# versions)
1382 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1383 : ! (C++ and C# versions, x86/x64 platform)
1384 : !
1385 : ! We recommend you to read 'Working with commercial version' section of
1386 : ! ALGLIB Reference Manual in order to find out how to use performance-
1387 : ! related features provided by commercial edition of ALGLIB.
1388 :
1389 : INPUT PARAMETERS
1390 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
1391 : P - array[0..N-1], pivots array, RMatrixLU result
1392 : N - size of A
1393 : B - array[0..N-1,0..M-1], right part
1394 : M - right part size
1395 :
1396 : OUTPUT PARAMETERS
1397 : Info - return code:
1398 : * -3 matrix is very badly conditioned or exactly singular.
1399 : * -1 N<=0 was passed
1400 : * 1 task is solved (but matrix A may be ill-conditioned,
1401 : check R1/RInf parameters for condition numbers).
1402 : Rep - additional report, following fields are set:
1403 : * rep.r1 condition number in 1-norm
1404 : * rep.rinf condition number in inf-norm
1405 : X - array[N,M], it contains:
1406 : * info>0 => solution
1407 : * info=-3 => filled by zeros
1408 :
1409 : -- ALGLIB --
1410 : Copyright 27.01.2010 by Bochkanov Sergey
1411 : *************************************************************************/
1412 0 : void cmatrixlusolvem(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
1413 : {
1414 : jmp_buf _break_jump;
1415 : alglib_impl::ae_state _alglib_env_state;
1416 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1417 0 : if( setjmp(_break_jump) )
1418 : {
1419 : #if !defined(AE_NO_EXCEPTIONS)
1420 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1421 : #else
1422 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1423 : return;
1424 : #endif
1425 : }
1426 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1427 0 : if( _xparams.flags!=0x0 )
1428 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1429 0 : alglib_impl::cmatrixlusolvem(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1430 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1431 0 : return;
1432 : }
1433 :
1434 : /*************************************************************************
1435 : Dense solver for A*X=B with N*N complex A given by its LU decomposition,
1436 : and N*M matrices X and B (multiple right sides). "Fast-but-lightweight"
1437 : version of the solver.
1438 :
1439 : Algorithm features:
1440 : * O(M*N^2) complexity
1441 : * no additional time-consuming features
1442 :
1443 : ! COMMERCIAL EDITION OF ALGLIB:
1444 : !
1445 : ! Commercial Edition of ALGLIB includes following important improvements
1446 : ! of this function:
1447 : ! * high-performance native backend with same C# interface (C# version)
1448 : ! * multithreading support (C++ and C# versions)
1449 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1450 : ! (C++ and C# versions, x86/x64 platform)
1451 : !
1452 : ! We recommend you to read 'Working with commercial version' section of
1453 : ! ALGLIB Reference Manual in order to find out how to use performance-
1454 : ! related features provided by commercial edition of ALGLIB.
1455 :
1456 : INPUT PARAMETERS
1457 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
1458 : P - array[0..N-1], pivots array, RMatrixLU result
1459 : N - size of A
1460 : B - array[0..N-1,0..M-1], right part
1461 : M - right part size
1462 :
1463 : OUTPUT PARAMETERS
1464 : Info - return code:
1465 : * -3 matrix is exactly singular (ill conditioned matrices
1466 : are not recognized).
1467 : * -1 N<=0 was passed
1468 : * 1 task is solved
1469 : B - array[N,M]:
1470 : * info>0 => overwritten by solution
1471 : * info=-3 => filled by zeros
1472 :
1473 :
1474 : -- ALGLIB --
1475 : Copyright 27.01.2010 by Bochkanov Sergey
1476 : *************************************************************************/
1477 0 : void cmatrixlusolvemfast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
1478 : {
1479 : jmp_buf _break_jump;
1480 : alglib_impl::ae_state _alglib_env_state;
1481 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1482 0 : if( setjmp(_break_jump) )
1483 : {
1484 : #if !defined(AE_NO_EXCEPTIONS)
1485 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1486 : #else
1487 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1488 : return;
1489 : #endif
1490 : }
1491 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1492 0 : if( _xparams.flags!=0x0 )
1493 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1494 0 : alglib_impl::cmatrixlusolvemfast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
1495 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1496 0 : return;
1497 : }
1498 :
1499 : /*************************************************************************
1500 : Complex dense linear solver for A*x=b with complex N*N A given by its LU
1501 : decomposition and N*1 vectors x and b. This is "slow-but-robust" version
1502 : of the complex linear solver with additional features which add
1503 : significant performance overhead. Faster version is CMatrixLUSolveFast()
1504 : function.
1505 :
1506 : Algorithm features:
1507 : * automatic detection of degenerate cases
1508 : * O(N^2) complexity
1509 : * condition number estimation
1510 :
1511 : No iterative refinement is provided because exact form of original matrix
1512 : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you
1513 : need iterative refinement.
1514 :
1515 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1516 : ! by ALGLIB. It estimates condition number of linear system,
1517 : ! which results in 10-15x performance penalty when compared
1518 : ! with "fast" version which just calls triangular solver.
1519 : !
1520 : ! This performance penalty is insignificant when compared with
1521 : ! cost of large LU decomposition. However, if you call this
1522 : ! function many times for the same left side, this overhead
1523 : ! BECOMES significant. It also becomes significant for small-
1524 : ! scale problems.
1525 : !
1526 : ! In such cases we strongly recommend you to use faster solver,
1527 : ! CMatrixLUSolveFast() function.
1528 :
1529 : INPUT PARAMETERS
1530 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
1531 : P - array[0..N-1], pivots array, CMatrixLU result
1532 : N - size of A
1533 : B - array[0..N-1], right part
1534 :
1535 : OUTPUT PARAMETERS
1536 : Info - return code:
1537 : * -3 matrix is very badly conditioned or exactly singular.
1538 : * -1 N<=0 was passed
1539 : * 1 task is solved (but matrix A may be ill-conditioned,
1540 : check R1/RInf parameters for condition numbers).
1541 : Rep - additional report, following fields are set:
1542 : * rep.r1 condition number in 1-norm
1543 : * rep.rinf condition number in inf-norm
1544 : X - array[N], it contains:
1545 : * info>0 => solution
1546 : * info=-3 => filled by zeros
1547 :
1548 : -- ALGLIB --
1549 : Copyright 27.01.2010 by Bochkanov Sergey
1550 : *************************************************************************/
1551 0 : void cmatrixlusolve(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
1552 : {
1553 : jmp_buf _break_jump;
1554 : alglib_impl::ae_state _alglib_env_state;
1555 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1556 0 : if( setjmp(_break_jump) )
1557 : {
1558 : #if !defined(AE_NO_EXCEPTIONS)
1559 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1560 : #else
1561 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1562 : return;
1563 : #endif
1564 : }
1565 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1566 0 : if( _xparams.flags!=0x0 )
1567 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1568 0 : alglib_impl::cmatrixlusolve(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
1569 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1570 0 : return;
1571 : }
1572 :
1573 : /*************************************************************************
1574 : Complex dense linear solver for A*x=b with N*N complex A given by its LU
1575 : decomposition and N*1 vectors x and b. This is fast lightweight version
1576 : of solver, which is significantly faster than CMatrixLUSolve(), but does
1577 : not provide additional information (like condition numbers).
1578 :
1579 : Algorithm features:
1580 : * O(N^2) complexity
1581 : * no additional time-consuming features, just triangular solver
1582 :
1583 : INPUT PARAMETERS
1584 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
1585 : P - array[0..N-1], pivots array, CMatrixLU result
1586 : N - size of A
1587 : B - array[0..N-1], right part
1588 :
1589 : OUTPUT PARAMETERS
1590 : Info - return code:
1591 : * -3 matrix is exactly singular (ill conditioned matrices
1592 : are not recognized).
1593 : * -1 N<=0 was passed
1594 : * 1 task is solved
1595 : B - array[N]:
1596 : * info>0 => overwritten by solution
1597 : * info=-3 => filled by zeros
1598 :
1599 : NOTE: unlike CMatrixLUSolve(), this function does NOT check for
1600 : near-degeneracy of input matrix. It checks for EXACT degeneracy,
1601 : because this check is easy to do. However, very badly conditioned
1602 : matrices may went unnoticed.
1603 :
1604 :
1605 : -- ALGLIB --
1606 : Copyright 27.01.2010 by Bochkanov Sergey
1607 : *************************************************************************/
1608 0 : void cmatrixlusolvefast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
1609 : {
1610 : jmp_buf _break_jump;
1611 : alglib_impl::ae_state _alglib_env_state;
1612 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1613 0 : if( setjmp(_break_jump) )
1614 : {
1615 : #if !defined(AE_NO_EXCEPTIONS)
1616 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1617 : #else
1618 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1619 : return;
1620 : #endif
1621 : }
1622 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1623 0 : if( _xparams.flags!=0x0 )
1624 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1625 0 : alglib_impl::cmatrixlusolvefast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
1626 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1627 0 : return;
1628 : }
1629 :
1630 : /*************************************************************************
1631 : Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
1632 :
1633 : Algorithm features:
1634 : * automatic detection of degenerate cases
1635 : * condition number estimation
1636 : * iterative refinement
1637 : * O(M*N^2) complexity
1638 :
1639 : INPUT PARAMETERS
1640 : A - array[0..N-1,0..N-1], system matrix
1641 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
1642 : P - array[0..N-1], pivots array, CMatrixLU result
1643 : N - size of A
1644 : B - array[0..N-1,0..M-1], right part
1645 : M - right part size
1646 :
1647 : OUTPUT PARAMETERS
1648 : Info - return code:
1649 : * -3 matrix is very badly conditioned or exactly singular.
1650 : * -1 N<=0 was passed
1651 : * 1 task is solved (but matrix A may be ill-conditioned,
1652 : check R1/RInf parameters for condition numbers).
1653 : Rep - additional report, following fields are set:
1654 : * rep.r1 condition number in 1-norm
1655 : * rep.rinf condition number in inf-norm
1656 : X - array[N,M], it contains:
1657 : * info>0 => solution
1658 : * info=-3 => filled by zeros
1659 :
1660 : -- ALGLIB --
1661 : Copyright 27.01.2010 by Bochkanov Sergey
1662 : *************************************************************************/
1663 0 : void cmatrixmixedsolvem(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
1664 : {
1665 : jmp_buf _break_jump;
1666 : alglib_impl::ae_state _alglib_env_state;
1667 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1668 0 : if( setjmp(_break_jump) )
1669 : {
1670 : #if !defined(AE_NO_EXCEPTIONS)
1671 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1672 : #else
1673 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1674 : return;
1675 : #endif
1676 : }
1677 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1678 0 : if( _xparams.flags!=0x0 )
1679 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1680 0 : alglib_impl::cmatrixmixedsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1681 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1682 0 : return;
1683 : }
1684 :
1685 : /*************************************************************************
1686 : Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
1687 :
1688 : Algorithm features:
1689 : * automatic detection of degenerate cases
1690 : * condition number estimation
1691 : * iterative refinement
1692 : * O(N^2) complexity
1693 :
1694 : INPUT PARAMETERS
1695 : A - array[0..N-1,0..N-1], system matrix
1696 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
1697 : P - array[0..N-1], pivots array, CMatrixLU result
1698 : N - size of A
1699 : B - array[0..N-1], right part
1700 :
1701 : OUTPUT PARAMETERS
1702 : Info - return code:
1703 : * -3 matrix is very badly conditioned or exactly singular.
1704 : * -1 N<=0 was passed
1705 : * 1 task is solved (but matrix A may be ill-conditioned,
1706 : check R1/RInf parameters for condition numbers).
1707 : Rep - additional report, following fields are set:
1708 : * rep.r1 condition number in 1-norm
1709 : * rep.rinf condition number in inf-norm
1710 : X - array[N], it contains:
1711 : * info>0 => solution
1712 : * info=-3 => filled by zeros
1713 :
1714 : -- ALGLIB --
1715 : Copyright 27.01.2010 by Bochkanov Sergey
1716 : *************************************************************************/
1717 0 : void cmatrixmixedsolve(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
1718 : {
1719 : jmp_buf _break_jump;
1720 : alglib_impl::ae_state _alglib_env_state;
1721 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1722 0 : if( setjmp(_break_jump) )
1723 : {
1724 : #if !defined(AE_NO_EXCEPTIONS)
1725 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1726 : #else
1727 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1728 : return;
1729 : #endif
1730 : }
1731 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1732 0 : if( _xparams.flags!=0x0 )
1733 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1734 0 : alglib_impl::cmatrixmixedsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
1735 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1736 0 : return;
1737 : }
1738 :
1739 : /*************************************************************************
1740 : Dense solver for A*X=B with N*N symmetric positive definite matrix A, and
1741 : N*M vectors X and B. It is "slow-but-feature-rich" version of the solver.
1742 :
1743 : Algorithm features:
1744 : * automatic detection of degenerate cases
1745 : * condition number estimation
1746 : * O(N^3+M*N^2) complexity
1747 : * matrix is represented by its upper or lower triangle
1748 :
1749 : No iterative refinement is provided because such partial representation of
1750 : matrix does not allow efficient calculation of extra-precise matrix-vector
1751 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
1752 : need iterative refinement.
1753 :
1754 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1755 : ! by ALGLIB. It estimates condition number of linear system,
1756 : ! which results in significant performance penalty when
1757 : ! compared with "fast" version which just performs Cholesky
1758 : ! decomposition and calls triangular solver.
1759 : !
1760 : ! This performance penalty is especially visible in the
1761 : ! multithreaded mode, because both condition number estimation
1762 : ! and iterative refinement are inherently sequential
1763 : ! calculations.
1764 : !
1765 : ! Thus, if you need high performance and if you are pretty sure
1766 : ! that your system is well conditioned, we strongly recommend
1767 : ! you to use faster solver, SPDMatrixSolveMFast() function.
1768 :
1769 : ! COMMERCIAL EDITION OF ALGLIB:
1770 : !
1771 : ! Commercial Edition of ALGLIB includes following important improvements
1772 : ! of this function:
1773 : ! * high-performance native backend with same C# interface (C# version)
1774 : ! * multithreading support (C++ and C# versions)
1775 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1776 : ! (C++ and C# versions, x86/x64 platform)
1777 : !
1778 : ! We recommend you to read 'Working with commercial version' section of
1779 : ! ALGLIB Reference Manual in order to find out how to use performance-
1780 : ! related features provided by commercial edition of ALGLIB.
1781 :
1782 : INPUT PARAMETERS
1783 : A - array[0..N-1,0..N-1], system matrix
1784 : N - size of A
1785 : IsUpper - what half of A is provided
1786 : B - array[0..N-1,0..M-1], right part
1787 : M - right part size
1788 :
1789 : OUTPUT PARAMETERS
1790 : Info - return code:
1791 : * -3 matrix is very badly conditioned or non-SPD.
1792 : * -1 N<=0 was passed
1793 : * 1 task is solved (but matrix A may be ill-conditioned,
1794 : check R1/RInf parameters for condition numbers).
1795 : Rep - additional report, following fields are set:
1796 : * rep.r1 condition number in 1-norm
1797 : * rep.rinf condition number in inf-norm
1798 : X - array[N,M], it contains:
1799 : * info>0 => solution
1800 : * info=-3 => filled by zeros
1801 :
1802 : -- ALGLIB --
1803 : Copyright 27.01.2010 by Bochkanov Sergey
1804 : *************************************************************************/
1805 0 : void spdmatrixsolvem(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
1806 : {
1807 : jmp_buf _break_jump;
1808 : alglib_impl::ae_state _alglib_env_state;
1809 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1810 0 : if( setjmp(_break_jump) )
1811 : {
1812 : #if !defined(AE_NO_EXCEPTIONS)
1813 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1814 : #else
1815 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1816 : return;
1817 : #endif
1818 : }
1819 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1820 0 : if( _xparams.flags!=0x0 )
1821 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1822 0 : alglib_impl::spdmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
1823 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1824 0 : return;
1825 : }
1826 :
1827 : /*************************************************************************
1828 : Dense solver for A*X=B with N*N symmetric positive definite matrix A, and
1829 : N*M vectors X and B. It is "fast-but-lightweight" version of the solver.
1830 :
1831 : Algorithm features:
1832 : * O(N^3+M*N^2) complexity
1833 : * matrix is represented by its upper or lower triangle
1834 : * no additional time consuming features
1835 :
1836 : ! COMMERCIAL EDITION OF ALGLIB:
1837 : !
1838 : ! Commercial Edition of ALGLIB includes following important improvements
1839 : ! of this function:
1840 : ! * high-performance native backend with same C# interface (C# version)
1841 : ! * multithreading support (C++ and C# versions)
1842 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1843 : ! (C++ and C# versions, x86/x64 platform)
1844 : !
1845 : ! We recommend you to read 'Working with commercial version' section of
1846 : ! ALGLIB Reference Manual in order to find out how to use performance-
1847 : ! related features provided by commercial edition of ALGLIB.
1848 :
1849 : INPUT PARAMETERS
1850 : A - array[0..N-1,0..N-1], system matrix
1851 : N - size of A
1852 : IsUpper - what half of A is provided
1853 : B - array[0..N-1,0..M-1], right part
1854 : M - right part size
1855 :
1856 : OUTPUT PARAMETERS
1857 : Info - return code:
1858 : * -3 A is is exactly singular
1859 : * -1 N<=0 was passed
1860 : * 1 task was solved
1861 : B - array[N,M], it contains:
1862 : * info>0 => solution
1863 : * info=-3 => filled by zeros
1864 :
1865 : -- ALGLIB --
1866 : Copyright 17.03.2015 by Bochkanov Sergey
1867 : *************************************************************************/
1868 0 : void spdmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
1869 : {
1870 : jmp_buf _break_jump;
1871 : alglib_impl::ae_state _alglib_env_state;
1872 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1873 0 : if( setjmp(_break_jump) )
1874 : {
1875 : #if !defined(AE_NO_EXCEPTIONS)
1876 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1877 : #else
1878 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1879 : return;
1880 : #endif
1881 : }
1882 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1883 0 : if( _xparams.flags!=0x0 )
1884 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1885 0 : alglib_impl::spdmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
1886 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1887 0 : return;
1888 : }
1889 :
1890 : /*************************************************************************
1891 : Dense linear solver for A*x=b with N*N real symmetric positive definite
1892 : matrix A, N*1 vectors x and b. "Slow-but-feature-rich" version of the
1893 : solver.
1894 :
1895 : Algorithm features:
1896 : * automatic detection of degenerate cases
1897 : * condition number estimation
1898 : * O(N^3) complexity
1899 : * matrix is represented by its upper or lower triangle
1900 :
1901 : No iterative refinement is provided because such partial representation of
1902 : matrix does not allow efficient calculation of extra-precise matrix-vector
1903 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
1904 : need iterative refinement.
1905 :
1906 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
1907 : ! by ALGLIB. It estimates condition number of linear system,
1908 : ! which results in significant performance penalty when
1909 : ! compared with "fast" version which just performs Cholesky
1910 : ! decomposition and calls triangular solver.
1911 : !
1912 : ! This performance penalty is especially visible in the
1913 : ! multithreaded mode, because both condition number estimation
1914 : ! and iterative refinement are inherently sequential
1915 : ! calculations.
1916 : !
1917 : ! Thus, if you need high performance and if you are pretty sure
1918 : ! that your system is well conditioned, we strongly recommend
1919 : ! you to use faster solver, SPDMatrixSolveFast() function.
1920 :
1921 : ! COMMERCIAL EDITION OF ALGLIB:
1922 : !
1923 : ! Commercial Edition of ALGLIB includes following important improvements
1924 : ! of this function:
1925 : ! * high-performance native backend with same C# interface (C# version)
1926 : ! * multithreading support (C++ and C# versions)
1927 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1928 : ! (C++ and C# versions, x86/x64 platform)
1929 : !
1930 : ! We recommend you to read 'Working with commercial version' section of
1931 : ! ALGLIB Reference Manual in order to find out how to use performance-
1932 : ! related features provided by commercial edition of ALGLIB.
1933 :
1934 : INPUT PARAMETERS
1935 : A - array[0..N-1,0..N-1], system matrix
1936 : N - size of A
1937 : IsUpper - what half of A is provided
1938 : B - array[0..N-1], right part
1939 :
1940 : OUTPUT PARAMETERS
1941 : Info - return code:
1942 : * -3 matrix is very badly conditioned or non-SPD.
1943 : * -1 N<=0 was passed
1944 : * 1 task is solved (but matrix A may be ill-conditioned,
1945 : check R1/RInf parameters for condition numbers).
1946 : Rep - additional report, following fields are set:
1947 : * rep.r1 condition number in 1-norm
1948 : * rep.rinf condition number in inf-norm
1949 : X - array[N], it contains:
1950 : * info>0 => solution
1951 : * info=-3 => filled by zeros
1952 :
1953 : -- ALGLIB --
1954 : Copyright 27.01.2010 by Bochkanov Sergey
1955 : *************************************************************************/
1956 0 : void spdmatrixsolve(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
1957 : {
1958 : jmp_buf _break_jump;
1959 : alglib_impl::ae_state _alglib_env_state;
1960 0 : alglib_impl::ae_state_init(&_alglib_env_state);
1961 0 : if( setjmp(_break_jump) )
1962 : {
1963 : #if !defined(AE_NO_EXCEPTIONS)
1964 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1965 : #else
1966 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1967 : return;
1968 : #endif
1969 : }
1970 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1971 0 : if( _xparams.flags!=0x0 )
1972 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1973 0 : alglib_impl::spdmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
1974 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
1975 0 : return;
1976 : }
1977 :
1978 : /*************************************************************************
1979 : Dense linear solver for A*x=b with N*N real symmetric positive definite
1980 : matrix A, N*1 vectors x and b. "Fast-but-lightweight" version of the
1981 : solver.
1982 :
1983 : Algorithm features:
1984 : * O(N^3) complexity
1985 : * matrix is represented by its upper or lower triangle
1986 : * no additional time consuming features like condition number estimation
1987 :
1988 : ! COMMERCIAL EDITION OF ALGLIB:
1989 : !
1990 : ! Commercial Edition of ALGLIB includes following important improvements
1991 : ! of this function:
1992 : ! * high-performance native backend with same C# interface (C# version)
1993 : ! * multithreading support (C++ and C# versions)
1994 : ! * hardware vendor (Intel) implementations of linear algebra primitives
1995 : ! (C++ and C# versions, x86/x64 platform)
1996 : !
1997 : ! We recommend you to read 'Working with commercial version' section of
1998 : ! ALGLIB Reference Manual in order to find out how to use performance-
1999 : ! related features provided by commercial edition of ALGLIB.
2000 :
2001 : INPUT PARAMETERS
2002 : A - array[0..N-1,0..N-1], system matrix
2003 : N - size of A
2004 : IsUpper - what half of A is provided
2005 : B - array[0..N-1], right part
2006 :
2007 : OUTPUT PARAMETERS
2008 : Info - return code:
2009 : * -3 A is is exactly singular or non-SPD
2010 : * -1 N<=0 was passed
2011 : * 1 task was solved
2012 : B - array[N], it contains:
2013 : * info>0 => solution
2014 : * info=-3 => filled by zeros
2015 :
2016 : -- ALGLIB --
2017 : Copyright 17.03.2015 by Bochkanov Sergey
2018 : *************************************************************************/
2019 0 : void spdmatrixsolvefast(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
2020 : {
2021 : jmp_buf _break_jump;
2022 : alglib_impl::ae_state _alglib_env_state;
2023 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2024 0 : if( setjmp(_break_jump) )
2025 : {
2026 : #if !defined(AE_NO_EXCEPTIONS)
2027 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2028 : #else
2029 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2030 : return;
2031 : #endif
2032 : }
2033 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2034 0 : if( _xparams.flags!=0x0 )
2035 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2036 0 : alglib_impl::spdmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
2037 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2038 0 : return;
2039 : }
2040 :
2041 : /*************************************************************************
2042 : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
2043 : by its Cholesky decomposition, and N*M vectors X and B. It is "slow-but-
2044 : feature-rich" version of the solver which estimates condition number of
2045 : the system.
2046 :
2047 : Algorithm features:
2048 : * automatic detection of degenerate cases
2049 : * O(M*N^2) complexity
2050 : * condition number estimation
2051 : * matrix is represented by its upper or lower triangle
2052 :
2053 : No iterative refinement is provided because such partial representation of
2054 : matrix does not allow efficient calculation of extra-precise matrix-vector
2055 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2056 : need iterative refinement.
2057 :
2058 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2059 : ! by ALGLIB. It estimates condition number of linear system,
2060 : ! which results in significant performance penalty when
2061 : ! compared with "fast" version which just calls triangular
2062 : ! solver. Amount of overhead introduced depends on M (the
2063 : ! larger - the more efficient).
2064 : !
2065 : ! This performance penalty is insignificant when compared with
2066 : ! cost of large LU decomposition. However, if you call this
2067 : ! function many times for the same left side, this overhead
2068 : ! BECOMES significant. It also becomes significant for small-
2069 : ! scale problems (N<50).
2070 : !
2071 : ! In such cases we strongly recommend you to use faster solver,
2072 : ! SPDMatrixCholeskySolveMFast() function.
2073 :
2074 : INPUT PARAMETERS
2075 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
2076 : SPDMatrixCholesky result
2077 : N - size of CHA
2078 : IsUpper - what half of CHA is provided
2079 : B - array[0..N-1,0..M-1], right part
2080 : M - right part size
2081 :
2082 : OUTPUT PARAMETERS
2083 : Info - return code:
2084 : * -3 A is is exactly singular or badly conditioned
2085 : X is filled by zeros in such cases.
2086 : * -1 N<=0 was passed
2087 : * 1 task was solved
2088 : Rep - additional report, following fields are set:
2089 : * rep.r1 condition number in 1-norm
2090 : * rep.rinf condition number in inf-norm
2091 : X - array[N]:
2092 : * for info>0 contains solution
2093 : * for info=-3 filled by zeros
2094 :
2095 : -- ALGLIB --
2096 : Copyright 27.01.2010 by Bochkanov Sergey
2097 : *************************************************************************/
2098 0 : void spdmatrixcholeskysolvem(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
2099 : {
2100 : jmp_buf _break_jump;
2101 : alglib_impl::ae_state _alglib_env_state;
2102 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2103 0 : if( setjmp(_break_jump) )
2104 : {
2105 : #if !defined(AE_NO_EXCEPTIONS)
2106 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2107 : #else
2108 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2109 : return;
2110 : #endif
2111 : }
2112 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2113 0 : if( _xparams.flags!=0x0 )
2114 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2115 0 : alglib_impl::spdmatrixcholeskysolvem(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
2116 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2117 0 : return;
2118 : }
2119 :
2120 : /*************************************************************************
2121 : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
2122 : by its Cholesky decomposition, and N*M vectors X and B. It is "fast-but-
2123 : lightweight" version of the solver which just solves linear system,
2124 : without any additional functions.
2125 :
2126 : Algorithm features:
2127 : * O(M*N^2) complexity
2128 : * matrix is represented by its upper or lower triangle
2129 : * no additional functionality
2130 :
2131 : INPUT PARAMETERS
2132 : CHA - array[N,N], Cholesky decomposition,
2133 : SPDMatrixCholesky result
2134 : N - size of CHA
2135 : IsUpper - what half of CHA is provided
2136 : B - array[N,M], right part
2137 : M - right part size
2138 :
2139 : OUTPUT PARAMETERS
2140 : Info - return code:
2141 : * -3 A is is exactly singular or badly conditioned
2142 : X is filled by zeros in such cases.
2143 : * -1 N<=0 was passed
2144 : * 1 task was solved
2145 : B - array[N]:
2146 : * for info>0 overwritten by solution
2147 : * for info=-3 filled by zeros
2148 :
2149 : -- ALGLIB --
2150 : Copyright 18.03.2015 by Bochkanov Sergey
2151 : *************************************************************************/
2152 0 : void spdmatrixcholeskysolvemfast(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
2153 : {
2154 : jmp_buf _break_jump;
2155 : alglib_impl::ae_state _alglib_env_state;
2156 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2157 0 : if( setjmp(_break_jump) )
2158 : {
2159 : #if !defined(AE_NO_EXCEPTIONS)
2160 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2161 : #else
2162 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2163 : return;
2164 : #endif
2165 : }
2166 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2167 0 : if( _xparams.flags!=0x0 )
2168 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2169 0 : alglib_impl::spdmatrixcholeskysolvemfast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
2170 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2171 0 : return;
2172 : }
2173 :
2174 : /*************************************************************************
2175 : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
2176 : by its Cholesky decomposition, and N*1 real vectors x and b. This is "slow-
2177 : but-feature-rich" version of the solver which, in addition to the
2178 : solution, performs condition number estimation.
2179 :
2180 : Algorithm features:
2181 : * automatic detection of degenerate cases
2182 : * O(N^2) complexity
2183 : * condition number estimation
2184 : * matrix is represented by its upper or lower triangle
2185 :
2186 : No iterative refinement is provided because such partial representation of
2187 : matrix does not allow efficient calculation of extra-precise matrix-vector
2188 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2189 : need iterative refinement.
2190 :
2191 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2192 : ! by ALGLIB. It estimates condition number of linear system,
2193 : ! which results in 10-15x performance penalty when compared
2194 : ! with "fast" version which just calls triangular solver.
2195 : !
2196 : ! This performance penalty is insignificant when compared with
2197 : ! cost of large LU decomposition. However, if you call this
2198 : ! function many times for the same left side, this overhead
2199 : ! BECOMES significant. It also becomes significant for small-
2200 : ! scale problems (N<50).
2201 : !
2202 : ! In such cases we strongly recommend you to use faster solver,
2203 : ! SPDMatrixCholeskySolveFast() function.
2204 :
2205 : INPUT PARAMETERS
2206 : CHA - array[N,N], Cholesky decomposition,
2207 : SPDMatrixCholesky result
2208 : N - size of A
2209 : IsUpper - what half of CHA is provided
2210 : B - array[N], right part
2211 :
2212 : OUTPUT PARAMETERS
2213 : Info - return code:
2214 : * -3 A is is exactly singular or ill conditioned
2215 : X is filled by zeros in such cases.
2216 : * -1 N<=0 was passed
2217 : * 1 task is solved
2218 : Rep - additional report, following fields are set:
2219 : * rep.r1 condition number in 1-norm
2220 : * rep.rinf condition number in inf-norm
2221 : X - array[N]:
2222 : * for info>0 - solution
2223 : * for info=-3 - filled by zeros
2224 :
2225 : -- ALGLIB --
2226 : Copyright 27.01.2010 by Bochkanov Sergey
2227 : *************************************************************************/
2228 0 : void spdmatrixcholeskysolve(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
2229 : {
2230 : jmp_buf _break_jump;
2231 : alglib_impl::ae_state _alglib_env_state;
2232 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2233 0 : if( setjmp(_break_jump) )
2234 : {
2235 : #if !defined(AE_NO_EXCEPTIONS)
2236 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2237 : #else
2238 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2239 : return;
2240 : #endif
2241 : }
2242 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2243 0 : if( _xparams.flags!=0x0 )
2244 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2245 0 : alglib_impl::spdmatrixcholeskysolve(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
2246 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2247 0 : return;
2248 : }
2249 :
2250 : /*************************************************************************
2251 : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
2252 : by its Cholesky decomposition, and N*1 real vectors x and b. This is "fast-
2253 : but-lightweight" version of the solver.
2254 :
2255 : Algorithm features:
2256 : * O(N^2) complexity
2257 : * matrix is represented by its upper or lower triangle
2258 : * no additional features
2259 :
2260 : INPUT PARAMETERS
2261 : CHA - array[N,N], Cholesky decomposition,
2262 : SPDMatrixCholesky result
2263 : N - size of A
2264 : IsUpper - what half of CHA is provided
2265 : B - array[N], right part
2266 :
2267 : OUTPUT PARAMETERS
2268 : Info - return code:
2269 : * -3 A is is exactly singular or ill conditioned
2270 : X is filled by zeros in such cases.
2271 : * -1 N<=0 was passed
2272 : * 1 task is solved
2273 : B - array[N]:
2274 : * for info>0 - overwritten by solution
2275 : * for info=-3 - filled by zeros
2276 :
2277 : -- ALGLIB --
2278 : Copyright 27.01.2010 by Bochkanov Sergey
2279 : *************************************************************************/
2280 0 : void spdmatrixcholeskysolvefast(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
2281 : {
2282 : jmp_buf _break_jump;
2283 : alglib_impl::ae_state _alglib_env_state;
2284 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2285 0 : if( setjmp(_break_jump) )
2286 : {
2287 : #if !defined(AE_NO_EXCEPTIONS)
2288 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2289 : #else
2290 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2291 : return;
2292 : #endif
2293 : }
2294 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2295 0 : if( _xparams.flags!=0x0 )
2296 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2297 0 : alglib_impl::spdmatrixcholeskysolvefast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
2298 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2299 0 : return;
2300 : }
2301 :
2302 : /*************************************************************************
2303 : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and
2304 : N*M complex matrices X and B. "Slow-but-feature-rich" version of the
2305 : solver.
2306 :
2307 : Algorithm features:
2308 : * automatic detection of degenerate cases
2309 : * condition number estimation
2310 : * O(N^3+M*N^2) complexity
2311 : * matrix is represented by its upper or lower triangle
2312 :
2313 : No iterative refinement is provided because such partial representation of
2314 : matrix does not allow efficient calculation of extra-precise matrix-vector
2315 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2316 : need iterative refinement.
2317 :
2318 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2319 : ! by ALGLIB. It estimates condition number of linear system,
2320 : ! which results in significant performance penalty when
2321 : ! compared with "fast" version which just calls triangular
2322 : ! solver.
2323 : !
2324 : ! This performance penalty is especially apparent when you use
2325 : ! ALGLIB parallel capabilities (condition number estimation is
2326 : ! inherently sequential). It also becomes significant for
2327 : ! small-scale problems (N<100).
2328 : !
2329 : ! In such cases we strongly recommend you to use faster solver,
2330 : ! HPDMatrixSolveMFast() function.
2331 :
2332 : ! COMMERCIAL EDITION OF ALGLIB:
2333 : !
2334 : ! Commercial Edition of ALGLIB includes following important improvements
2335 : ! of this function:
2336 : ! * high-performance native backend with same C# interface (C# version)
2337 : ! * multithreading support (C++ and C# versions)
2338 : ! * hardware vendor (Intel) implementations of linear algebra primitives
2339 : ! (C++ and C# versions, x86/x64 platform)
2340 : !
2341 : ! We recommend you to read 'Working with commercial version' section of
2342 : ! ALGLIB Reference Manual in order to find out how to use performance-
2343 : ! related features provided by commercial edition of ALGLIB.
2344 :
2345 : INPUT PARAMETERS
2346 : A - array[0..N-1,0..N-1], system matrix
2347 : N - size of A
2348 : IsUpper - what half of A is provided
2349 : B - array[0..N-1,0..M-1], right part
2350 : M - right part size
2351 :
2352 : OUTPUT PARAMETERS
2353 : Info - same as in RMatrixSolve.
2354 : Returns -3 for non-HPD matrices.
2355 : Rep - same as in RMatrixSolve
2356 : X - same as in RMatrixSolve
2357 :
2358 : -- ALGLIB --
2359 : Copyright 27.01.2010 by Bochkanov Sergey
2360 : *************************************************************************/
2361 0 : void hpdmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
2362 : {
2363 : jmp_buf _break_jump;
2364 : alglib_impl::ae_state _alglib_env_state;
2365 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2366 0 : if( setjmp(_break_jump) )
2367 : {
2368 : #if !defined(AE_NO_EXCEPTIONS)
2369 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2370 : #else
2371 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2372 : return;
2373 : #endif
2374 : }
2375 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2376 0 : if( _xparams.flags!=0x0 )
2377 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2378 0 : alglib_impl::hpdmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
2379 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2380 0 : return;
2381 : }
2382 :
2383 : /*************************************************************************
2384 : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and
2385 : N*M complex matrices X and B. "Fast-but-lightweight" version of the solver.
2386 :
2387 : Algorithm features:
2388 : * O(N^3+M*N^2) complexity
2389 : * matrix is represented by its upper or lower triangle
2390 : * no additional time consuming features like condition number estimation
2391 :
2392 : ! COMMERCIAL EDITION OF ALGLIB:
2393 : !
2394 : ! Commercial Edition of ALGLIB includes following important improvements
2395 : ! of this function:
2396 : ! * high-performance native backend with same C# interface (C# version)
2397 : ! * multithreading support (C++ and C# versions)
2398 : ! * hardware vendor (Intel) implementations of linear algebra primitives
2399 : ! (C++ and C# versions, x86/x64 platform)
2400 : !
2401 : ! We recommend you to read 'Working with commercial version' section of
2402 : ! ALGLIB Reference Manual in order to find out how to use performance-
2403 : ! related features provided by commercial edition of ALGLIB.
2404 :
2405 : INPUT PARAMETERS
2406 : A - array[0..N-1,0..N-1], system matrix
2407 : N - size of A
2408 : IsUpper - what half of A is provided
2409 : B - array[0..N-1,0..M-1], right part
2410 : M - right part size
2411 :
2412 : OUTPUT PARAMETERS
2413 : Info - return code:
2414 : * -3 A is is exactly singular or is not positive definite.
2415 : B is filled by zeros in such cases.
2416 : * -1 N<=0 was passed
2417 : * 1 task is solved
2418 : B - array[0..N-1]:
2419 : * overwritten by solution
2420 : * zeros, if problem was not solved
2421 :
2422 : -- ALGLIB --
2423 : Copyright 17.03.2015 by Bochkanov Sergey
2424 : *************************************************************************/
2425 0 : void hpdmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
2426 : {
2427 : jmp_buf _break_jump;
2428 : alglib_impl::ae_state _alglib_env_state;
2429 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2430 0 : if( setjmp(_break_jump) )
2431 : {
2432 : #if !defined(AE_NO_EXCEPTIONS)
2433 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2434 : #else
2435 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2436 : return;
2437 : #endif
2438 : }
2439 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2440 0 : if( _xparams.flags!=0x0 )
2441 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2442 0 : alglib_impl::hpdmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
2443 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2444 0 : return;
2445 : }
2446 :
2447 : /*************************************************************************
2448 : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
2449 : N*1 complex vectors x and b. "Slow-but-feature-rich" version of the
2450 : solver.
2451 :
2452 : Algorithm features:
2453 : * automatic detection of degenerate cases
2454 : * condition number estimation
2455 : * O(N^3) complexity
2456 : * matrix is represented by its upper or lower triangle
2457 :
2458 : No iterative refinement is provided because such partial representation of
2459 : matrix does not allow efficient calculation of extra-precise matrix-vector
2460 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2461 : need iterative refinement.
2462 :
2463 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2464 : ! by ALGLIB. It estimates condition number of linear system,
2465 : ! which results in significant performance penalty when
2466 : ! compared with "fast" version which just performs Cholesky
2467 : ! decomposition and calls triangular solver.
2468 : !
2469 : ! This performance penalty is especially visible in the
2470 : ! multithreaded mode, because both condition number estimation
2471 : ! and iterative refinement are inherently sequential
2472 : ! calculations.
2473 : !
2474 : ! Thus, if you need high performance and if you are pretty sure
2475 : ! that your system is well conditioned, we strongly recommend
2476 : ! you to use faster solver, HPDMatrixSolveFast() function.
2477 :
2478 : ! COMMERCIAL EDITION OF ALGLIB:
2479 : !
2480 : ! Commercial Edition of ALGLIB includes following important improvements
2481 : ! of this function:
2482 : ! * high-performance native backend with same C# interface (C# version)
2483 : ! * multithreading support (C++ and C# versions)
2484 : ! * hardware vendor (Intel) implementations of linear algebra primitives
2485 : ! (C++ and C# versions, x86/x64 platform)
2486 : !
2487 : ! We recommend you to read 'Working with commercial version' section of
2488 : ! ALGLIB Reference Manual in order to find out how to use performance-
2489 : ! related features provided by commercial edition of ALGLIB.
2490 :
2491 : INPUT PARAMETERS
2492 : A - array[0..N-1,0..N-1], system matrix
2493 : N - size of A
2494 : IsUpper - what half of A is provided
2495 : B - array[0..N-1], right part
2496 :
2497 : OUTPUT PARAMETERS
2498 : Info - same as in RMatrixSolve
2499 : Returns -3 for non-HPD matrices.
2500 : Rep - same as in RMatrixSolve
2501 : X - same as in RMatrixSolve
2502 :
2503 : -- ALGLIB --
2504 : Copyright 27.01.2010 by Bochkanov Sergey
2505 : *************************************************************************/
2506 0 : void hpdmatrixsolve(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
2507 : {
2508 : jmp_buf _break_jump;
2509 : alglib_impl::ae_state _alglib_env_state;
2510 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2511 0 : if( setjmp(_break_jump) )
2512 : {
2513 : #if !defined(AE_NO_EXCEPTIONS)
2514 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2515 : #else
2516 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2517 : return;
2518 : #endif
2519 : }
2520 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2521 0 : if( _xparams.flags!=0x0 )
2522 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2523 0 : alglib_impl::hpdmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
2524 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2525 0 : return;
2526 : }
2527 :
2528 : /*************************************************************************
2529 : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
2530 : N*1 complex vectors x and b. "Fast-but-lightweight" version of the
2531 : solver without additional functions.
2532 :
2533 : Algorithm features:
2534 : * O(N^3) complexity
2535 : * matrix is represented by its upper or lower triangle
2536 : * no additional time consuming functions
2537 :
2538 : ! COMMERCIAL EDITION OF ALGLIB:
2539 : !
2540 : ! Commercial Edition of ALGLIB includes following important improvements
2541 : ! of this function:
2542 : ! * high-performance native backend with same C# interface (C# version)
2543 : ! * multithreading support (C++ and C# versions)
2544 : ! * hardware vendor (Intel) implementations of linear algebra primitives
2545 : ! (C++ and C# versions, x86/x64 platform)
2546 : !
2547 : ! We recommend you to read 'Working with commercial version' section of
2548 : ! ALGLIB Reference Manual in order to find out how to use performance-
2549 : ! related features provided by commercial edition of ALGLIB.
2550 :
2551 : INPUT PARAMETERS
2552 : A - array[0..N-1,0..N-1], system matrix
2553 : N - size of A
2554 : IsUpper - what half of A is provided
2555 : B - array[0..N-1], right part
2556 :
2557 : OUTPUT PARAMETERS
2558 : Info - return code:
2559 : * -3 A is is exactly singular or not positive definite
2560 : X is filled by zeros in such cases.
2561 : * -1 N<=0 was passed
2562 : * 1 task was solved
2563 : B - array[0..N-1]:
2564 : * overwritten by solution
2565 : * zeros, if A is exactly singular (diagonal of its LU
2566 : decomposition has exact zeros).
2567 :
2568 : -- ALGLIB --
2569 : Copyright 17.03.2015 by Bochkanov Sergey
2570 : *************************************************************************/
2571 0 : void hpdmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
2572 : {
2573 : jmp_buf _break_jump;
2574 : alglib_impl::ae_state _alglib_env_state;
2575 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2576 0 : if( setjmp(_break_jump) )
2577 : {
2578 : #if !defined(AE_NO_EXCEPTIONS)
2579 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2580 : #else
2581 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2582 : return;
2583 : #endif
2584 : }
2585 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2586 0 : if( _xparams.flags!=0x0 )
2587 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2588 0 : alglib_impl::hpdmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
2589 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2590 0 : return;
2591 : }
2592 :
2593 : /*************************************************************************
2594 : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
2595 : by its Cholesky decomposition and N*M complex matrices X and B. This is
2596 : "slow-but-feature-rich" version of the solver which, in addition to the
2597 : solution, estimates condition number of the system.
2598 :
2599 : Algorithm features:
2600 : * automatic detection of degenerate cases
2601 : * O(M*N^2) complexity
2602 : * condition number estimation
2603 : * matrix is represented by its upper or lower triangle
2604 :
2605 : No iterative refinement is provided because such partial representation of
2606 : matrix does not allow efficient calculation of extra-precise matrix-vector
2607 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2608 : need iterative refinement.
2609 :
2610 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2611 : ! by ALGLIB. It estimates condition number of linear system,
2612 : ! which results in significant performance penalty when
2613 : ! compared with "fast" version which just calls triangular
2614 : ! solver. Amount of overhead introduced depends on M (the
2615 : ! larger - the more efficient).
2616 : !
2617 : ! This performance penalty is insignificant when compared with
2618 : ! cost of large Cholesky decomposition. However, if you call
2619 : ! this function many times for the same left side, this
2620 : ! overhead BECOMES significant. It also becomes significant
2621 : ! for small-scale problems (N<50).
2622 : !
2623 : ! In such cases we strongly recommend you to use faster solver,
2624 : ! HPDMatrixCholeskySolveMFast() function.
2625 :
2626 :
2627 : INPUT PARAMETERS
2628 : CHA - array[N,N], Cholesky decomposition,
2629 : HPDMatrixCholesky result
2630 : N - size of CHA
2631 : IsUpper - what half of CHA is provided
2632 : B - array[N,M], right part
2633 : M - right part size
2634 :
2635 : OUTPUT PARAMETERS:
2636 : Info - return code:
2637 : * -3 A is singular, or VERY close to singular.
2638 : X is filled by zeros in such cases.
2639 : * -1 N<=0 was passed
2640 : * 1 task was solved
2641 : Rep - additional report, following fields are set:
2642 : * rep.r1 condition number in 1-norm
2643 : * rep.rinf condition number in inf-norm
2644 : X - array[N]:
2645 : * for info>0 contains solution
2646 : * for info=-3 filled by zeros
2647 :
2648 : -- ALGLIB --
2649 : Copyright 27.01.2010 by Bochkanov Sergey
2650 : *************************************************************************/
2651 0 : void hpdmatrixcholeskysolvem(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
2652 : {
2653 : jmp_buf _break_jump;
2654 : alglib_impl::ae_state _alglib_env_state;
2655 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2656 0 : if( setjmp(_break_jump) )
2657 : {
2658 : #if !defined(AE_NO_EXCEPTIONS)
2659 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2660 : #else
2661 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2662 : return;
2663 : #endif
2664 : }
2665 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2666 0 : if( _xparams.flags!=0x0 )
2667 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2668 0 : alglib_impl::hpdmatrixcholeskysolvem(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
2669 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2670 0 : return;
2671 : }
2672 :
2673 : /*************************************************************************
2674 : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
2675 : by its Cholesky decomposition and N*M complex matrices X and B. This is
2676 : "fast-but-lightweight" version of the solver.
2677 :
2678 : Algorithm features:
2679 : * O(M*N^2) complexity
2680 : * matrix is represented by its upper or lower triangle
2681 : * no additional time-consuming features
2682 :
2683 : INPUT PARAMETERS
2684 : CHA - array[N,N], Cholesky decomposition,
2685 : HPDMatrixCholesky result
2686 : N - size of CHA
2687 : IsUpper - what half of CHA is provided
2688 : B - array[N,M], right part
2689 : M - right part size
2690 :
2691 : OUTPUT PARAMETERS:
2692 : Info - return code:
2693 : * -3 A is singular, or VERY close to singular.
2694 : X is filled by zeros in such cases.
2695 : * -1 N<=0 was passed
2696 : * 1 task was solved
2697 : B - array[N]:
2698 : * for info>0 overwritten by solution
2699 : * for info=-3 filled by zeros
2700 :
2701 : -- ALGLIB --
2702 : Copyright 18.03.2015 by Bochkanov Sergey
2703 : *************************************************************************/
2704 0 : void hpdmatrixcholeskysolvemfast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
2705 : {
2706 : jmp_buf _break_jump;
2707 : alglib_impl::ae_state _alglib_env_state;
2708 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2709 0 : if( setjmp(_break_jump) )
2710 : {
2711 : #if !defined(AE_NO_EXCEPTIONS)
2712 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2713 : #else
2714 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2715 : return;
2716 : #endif
2717 : }
2718 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2719 0 : if( _xparams.flags!=0x0 )
2720 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2721 0 : alglib_impl::hpdmatrixcholeskysolvemfast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
2722 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2723 0 : return;
2724 : }
2725 :
2726 : /*************************************************************************
2727 : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
2728 : by its Cholesky decomposition, and N*1 complex vectors x and b. This is
2729 : "slow-but-feature-rich" version of the solver which estimates condition
2730 : number of the system.
2731 :
2732 : Algorithm features:
2733 : * automatic detection of degenerate cases
2734 : * O(N^2) complexity
2735 : * condition number estimation
2736 : * matrix is represented by its upper or lower triangle
2737 :
2738 : No iterative refinement is provided because such partial representation of
2739 : matrix does not allow efficient calculation of extra-precise matrix-vector
2740 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
2741 : need iterative refinement.
2742 :
2743 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
2744 : ! by ALGLIB. It estimates condition number of linear system,
2745 : ! which results in 10-15x performance penalty when compared
2746 : ! with "fast" version which just calls triangular solver.
2747 : !
2748 : ! This performance penalty is insignificant when compared with
2749 : ! cost of large LU decomposition. However, if you call this
2750 : ! function many times for the same left side, this overhead
2751 : ! BECOMES significant. It also becomes significant for small-
2752 : ! scale problems (N<50).
2753 : !
2754 : ! In such cases we strongly recommend you to use faster solver,
2755 : ! HPDMatrixCholeskySolveFast() function.
2756 :
2757 : INPUT PARAMETERS
2758 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
2759 : SPDMatrixCholesky result
2760 : N - size of A
2761 : IsUpper - what half of CHA is provided
2762 : B - array[0..N-1], right part
2763 :
2764 : OUTPUT PARAMETERS
2765 : Info - return code:
2766 : * -3 A is is exactly singular or ill conditioned
2767 : X is filled by zeros in such cases.
2768 : * -1 N<=0 was passed
2769 : * 1 task is solved
2770 : Rep - additional report, following fields are set:
2771 : * rep.r1 condition number in 1-norm
2772 : * rep.rinf condition number in inf-norm
2773 : X - array[N]:
2774 : * for info>0 - solution
2775 : * for info=-3 - filled by zeros
2776 :
2777 : -- ALGLIB --
2778 : Copyright 27.01.2010 by Bochkanov Sergey
2779 : *************************************************************************/
2780 0 : void hpdmatrixcholeskysolve(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
2781 : {
2782 : jmp_buf _break_jump;
2783 : alglib_impl::ae_state _alglib_env_state;
2784 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2785 0 : if( setjmp(_break_jump) )
2786 : {
2787 : #if !defined(AE_NO_EXCEPTIONS)
2788 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2789 : #else
2790 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2791 : return;
2792 : #endif
2793 : }
2794 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2795 0 : if( _xparams.flags!=0x0 )
2796 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2797 0 : alglib_impl::hpdmatrixcholeskysolve(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
2798 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2799 0 : return;
2800 : }
2801 :
2802 : /*************************************************************************
2803 : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
2804 : by its Cholesky decomposition, and N*1 complex vectors x and b. This is
2805 : "fast-but-lightweight" version of the solver.
2806 :
2807 : Algorithm features:
2808 : * O(N^2) complexity
2809 : * matrix is represented by its upper or lower triangle
2810 : * no additional time-consuming features
2811 :
2812 : INPUT PARAMETERS
2813 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
2814 : SPDMatrixCholesky result
2815 : N - size of A
2816 : IsUpper - what half of CHA is provided
2817 : B - array[0..N-1], right part
2818 :
2819 : OUTPUT PARAMETERS
2820 : Info - return code:
2821 : * -3 A is is exactly singular or ill conditioned
2822 : B is filled by zeros in such cases.
2823 : * -1 N<=0 was passed
2824 : * 1 task is solved
2825 : B - array[N]:
2826 : * for info>0 - overwritten by solution
2827 : * for info=-3 - filled by zeros
2828 :
2829 : -- ALGLIB --
2830 : Copyright 18.03.2015 by Bochkanov Sergey
2831 : *************************************************************************/
2832 0 : void hpdmatrixcholeskysolvefast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
2833 : {
2834 : jmp_buf _break_jump;
2835 : alglib_impl::ae_state _alglib_env_state;
2836 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2837 0 : if( setjmp(_break_jump) )
2838 : {
2839 : #if !defined(AE_NO_EXCEPTIONS)
2840 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2841 : #else
2842 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2843 : return;
2844 : #endif
2845 : }
2846 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2847 0 : if( _xparams.flags!=0x0 )
2848 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2849 0 : alglib_impl::hpdmatrixcholeskysolvefast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
2850 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2851 0 : return;
2852 : }
2853 :
2854 : /*************************************************************************
2855 : Dense solver.
2856 :
2857 : This subroutine finds solution of the linear system A*X=B with non-square,
2858 : possibly degenerate A. System is solved in the least squares sense, and
2859 : general least squares solution X = X0 + CX*y which minimizes |A*X-B| is
2860 : returned. If A is non-degenerate, solution in the usual sense is returned.
2861 :
2862 : Algorithm features:
2863 : * automatic detection (and correct handling!) of degenerate cases
2864 : * iterative refinement
2865 : * O(N^3) complexity
2866 :
2867 : ! COMMERCIAL EDITION OF ALGLIB:
2868 : !
2869 : ! Commercial Edition of ALGLIB includes following important improvements
2870 : ! of this function:
2871 : ! * high-performance native backend with same C# interface (C# version)
2872 : ! * multithreading support (C++ and C# versions)
2873 : ! * hardware vendor (Intel) implementations of linear algebra primitives
2874 : ! (C++ and C# versions, x86/x64 platform)
2875 : !
2876 : ! We recommend you to read 'Working with commercial version' section of
2877 : ! ALGLIB Reference Manual in order to find out how to use performance-
2878 : ! related features provided by commercial edition of ALGLIB.
2879 :
2880 : INPUT PARAMETERS
2881 : A - array[0..NRows-1,0..NCols-1], system matrix
2882 : NRows - vertical size of A
2883 : NCols - horizontal size of A
2884 : B - array[0..NCols-1], right part
2885 : Threshold- a number in [0,1]. Singular values beyond Threshold are
2886 : considered zero. Set it to 0.0, if you don't understand
2887 : what it means, so the solver will choose good value on its
2888 : own.
2889 :
2890 : OUTPUT PARAMETERS
2891 : Info - return code:
2892 : * -4 SVD subroutine failed
2893 : * -1 if NRows<=0 or NCols<=0 or Threshold<0 was passed
2894 : * 1 if task is solved
2895 : Rep - solver report, see below for more info
2896 : X - array[0..N-1,0..M-1], it contains:
2897 : * solution of A*X=B (even for singular A)
2898 : * zeros, if SVD subroutine failed
2899 :
2900 : SOLVER REPORT
2901 :
2902 : Subroutine sets following fields of the Rep structure:
2903 : * R2 reciprocal of condition number: 1/cond(A), 2-norm.
2904 : * N = NCols
2905 : * K dim(Null(A))
2906 : * CX array[0..N-1,0..K-1], kernel of A.
2907 : Columns of CX store such vectors that A*CX[i]=0.
2908 :
2909 : -- ALGLIB --
2910 : Copyright 24.08.2009 by Bochkanov Sergey
2911 : *************************************************************************/
2912 0 : void rmatrixsolvels(const real_2d_array &a, const ae_int_t nrows, const ae_int_t ncols, const real_1d_array &b, const double threshold, ae_int_t &info, densesolverlsreport &rep, real_1d_array &x, const xparams _xparams)
2913 : {
2914 : jmp_buf _break_jump;
2915 : alglib_impl::ae_state _alglib_env_state;
2916 0 : alglib_impl::ae_state_init(&_alglib_env_state);
2917 0 : if( setjmp(_break_jump) )
2918 : {
2919 : #if !defined(AE_NO_EXCEPTIONS)
2920 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
2921 : #else
2922 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
2923 : return;
2924 : #endif
2925 : }
2926 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
2927 0 : if( _xparams.flags!=0x0 )
2928 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
2929 0 : alglib_impl::rmatrixsolvels(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), nrows, ncols, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), threshold, &info, const_cast<alglib_impl::densesolverlsreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
2930 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
2931 0 : return;
2932 : }
2933 : #endif
2934 :
2935 : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
2936 : /*************************************************************************
2937 : This object stores state of the LinLSQR method.
2938 :
2939 : You should use ALGLIB functions to work with this object.
2940 : *************************************************************************/
2941 0 : _linlsqrstate_owner::_linlsqrstate_owner()
2942 : {
2943 : jmp_buf _break_jump;
2944 : alglib_impl::ae_state _state;
2945 :
2946 0 : alglib_impl::ae_state_init(&_state);
2947 0 : if( setjmp(_break_jump) )
2948 : {
2949 0 : if( p_struct!=NULL )
2950 : {
2951 0 : alglib_impl::_linlsqrstate_destroy(p_struct);
2952 0 : alglib_impl::ae_free(p_struct);
2953 : }
2954 0 : p_struct = NULL;
2955 : #if !defined(AE_NO_EXCEPTIONS)
2956 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
2957 : #else
2958 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
2959 : return;
2960 : #endif
2961 : }
2962 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
2963 0 : p_struct = NULL;
2964 0 : p_struct = (alglib_impl::linlsqrstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrstate), &_state);
2965 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
2966 0 : alglib_impl::_linlsqrstate_init(p_struct, &_state, ae_false);
2967 0 : ae_state_clear(&_state);
2968 0 : }
2969 :
2970 0 : _linlsqrstate_owner::_linlsqrstate_owner(const _linlsqrstate_owner &rhs)
2971 : {
2972 : jmp_buf _break_jump;
2973 : alglib_impl::ae_state _state;
2974 :
2975 0 : alglib_impl::ae_state_init(&_state);
2976 0 : if( setjmp(_break_jump) )
2977 : {
2978 0 : if( p_struct!=NULL )
2979 : {
2980 0 : alglib_impl::_linlsqrstate_destroy(p_struct);
2981 0 : alglib_impl::ae_free(p_struct);
2982 : }
2983 0 : p_struct = NULL;
2984 : #if !defined(AE_NO_EXCEPTIONS)
2985 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
2986 : #else
2987 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
2988 : return;
2989 : #endif
2990 : }
2991 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
2992 0 : p_struct = NULL;
2993 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrstate copy constructor failure (source is not initialized)", &_state);
2994 0 : p_struct = (alglib_impl::linlsqrstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrstate), &_state);
2995 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
2996 0 : alglib_impl::_linlsqrstate_init_copy(p_struct, const_cast<alglib_impl::linlsqrstate*>(rhs.p_struct), &_state, ae_false);
2997 0 : ae_state_clear(&_state);
2998 0 : }
2999 :
3000 0 : _linlsqrstate_owner& _linlsqrstate_owner::operator=(const _linlsqrstate_owner &rhs)
3001 : {
3002 0 : if( this==&rhs )
3003 0 : return *this;
3004 : jmp_buf _break_jump;
3005 : alglib_impl::ae_state _state;
3006 :
3007 0 : alglib_impl::ae_state_init(&_state);
3008 0 : if( setjmp(_break_jump) )
3009 : {
3010 : #if !defined(AE_NO_EXCEPTIONS)
3011 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3012 : #else
3013 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3014 : return *this;
3015 : #endif
3016 : }
3017 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3018 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: linlsqrstate assignment constructor failure (destination is not initialized)", &_state);
3019 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrstate assignment constructor failure (source is not initialized)", &_state);
3020 0 : alglib_impl::_linlsqrstate_destroy(p_struct);
3021 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
3022 0 : alglib_impl::_linlsqrstate_init_copy(p_struct, const_cast<alglib_impl::linlsqrstate*>(rhs.p_struct), &_state, ae_false);
3023 0 : ae_state_clear(&_state);
3024 0 : return *this;
3025 : }
3026 :
3027 0 : _linlsqrstate_owner::~_linlsqrstate_owner()
3028 : {
3029 0 : if( p_struct!=NULL )
3030 : {
3031 0 : alglib_impl::_linlsqrstate_destroy(p_struct);
3032 0 : ae_free(p_struct);
3033 : }
3034 0 : }
3035 :
3036 0 : alglib_impl::linlsqrstate* _linlsqrstate_owner::c_ptr()
3037 : {
3038 0 : return p_struct;
3039 : }
3040 :
3041 0 : alglib_impl::linlsqrstate* _linlsqrstate_owner::c_ptr() const
3042 : {
3043 0 : return const_cast<alglib_impl::linlsqrstate*>(p_struct);
3044 : }
3045 0 : linlsqrstate::linlsqrstate() : _linlsqrstate_owner()
3046 : {
3047 0 : }
3048 :
3049 0 : linlsqrstate::linlsqrstate(const linlsqrstate &rhs):_linlsqrstate_owner(rhs)
3050 : {
3051 0 : }
3052 :
3053 0 : linlsqrstate& linlsqrstate::operator=(const linlsqrstate &rhs)
3054 : {
3055 0 : if( this==&rhs )
3056 0 : return *this;
3057 0 : _linlsqrstate_owner::operator=(rhs);
3058 0 : return *this;
3059 : }
3060 :
3061 0 : linlsqrstate::~linlsqrstate()
3062 : {
3063 0 : }
3064 :
3065 :
3066 : /*************************************************************************
3067 :
3068 : *************************************************************************/
3069 0 : _linlsqrreport_owner::_linlsqrreport_owner()
3070 : {
3071 : jmp_buf _break_jump;
3072 : alglib_impl::ae_state _state;
3073 :
3074 0 : alglib_impl::ae_state_init(&_state);
3075 0 : if( setjmp(_break_jump) )
3076 : {
3077 0 : if( p_struct!=NULL )
3078 : {
3079 0 : alglib_impl::_linlsqrreport_destroy(p_struct);
3080 0 : alglib_impl::ae_free(p_struct);
3081 : }
3082 0 : p_struct = NULL;
3083 : #if !defined(AE_NO_EXCEPTIONS)
3084 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3085 : #else
3086 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3087 : return;
3088 : #endif
3089 : }
3090 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3091 0 : p_struct = NULL;
3092 0 : p_struct = (alglib_impl::linlsqrreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrreport), &_state);
3093 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
3094 0 : alglib_impl::_linlsqrreport_init(p_struct, &_state, ae_false);
3095 0 : ae_state_clear(&_state);
3096 0 : }
3097 :
3098 0 : _linlsqrreport_owner::_linlsqrreport_owner(const _linlsqrreport_owner &rhs)
3099 : {
3100 : jmp_buf _break_jump;
3101 : alglib_impl::ae_state _state;
3102 :
3103 0 : alglib_impl::ae_state_init(&_state);
3104 0 : if( setjmp(_break_jump) )
3105 : {
3106 0 : if( p_struct!=NULL )
3107 : {
3108 0 : alglib_impl::_linlsqrreport_destroy(p_struct);
3109 0 : alglib_impl::ae_free(p_struct);
3110 : }
3111 0 : p_struct = NULL;
3112 : #if !defined(AE_NO_EXCEPTIONS)
3113 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3114 : #else
3115 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3116 : return;
3117 : #endif
3118 : }
3119 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3120 0 : p_struct = NULL;
3121 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrreport copy constructor failure (source is not initialized)", &_state);
3122 0 : p_struct = (alglib_impl::linlsqrreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrreport), &_state);
3123 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
3124 0 : alglib_impl::_linlsqrreport_init_copy(p_struct, const_cast<alglib_impl::linlsqrreport*>(rhs.p_struct), &_state, ae_false);
3125 0 : ae_state_clear(&_state);
3126 0 : }
3127 :
3128 0 : _linlsqrreport_owner& _linlsqrreport_owner::operator=(const _linlsqrreport_owner &rhs)
3129 : {
3130 0 : if( this==&rhs )
3131 0 : return *this;
3132 : jmp_buf _break_jump;
3133 : alglib_impl::ae_state _state;
3134 :
3135 0 : alglib_impl::ae_state_init(&_state);
3136 0 : if( setjmp(_break_jump) )
3137 : {
3138 : #if !defined(AE_NO_EXCEPTIONS)
3139 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3140 : #else
3141 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3142 : return *this;
3143 : #endif
3144 : }
3145 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3146 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: linlsqrreport assignment constructor failure (destination is not initialized)", &_state);
3147 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrreport assignment constructor failure (source is not initialized)", &_state);
3148 0 : alglib_impl::_linlsqrreport_destroy(p_struct);
3149 0 : memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
3150 0 : alglib_impl::_linlsqrreport_init_copy(p_struct, const_cast<alglib_impl::linlsqrreport*>(rhs.p_struct), &_state, ae_false);
3151 0 : ae_state_clear(&_state);
3152 0 : return *this;
3153 : }
3154 :
3155 0 : _linlsqrreport_owner::~_linlsqrreport_owner()
3156 : {
3157 0 : if( p_struct!=NULL )
3158 : {
3159 0 : alglib_impl::_linlsqrreport_destroy(p_struct);
3160 0 : ae_free(p_struct);
3161 : }
3162 0 : }
3163 :
3164 0 : alglib_impl::linlsqrreport* _linlsqrreport_owner::c_ptr()
3165 : {
3166 0 : return p_struct;
3167 : }
3168 :
3169 0 : alglib_impl::linlsqrreport* _linlsqrreport_owner::c_ptr() const
3170 : {
3171 0 : return const_cast<alglib_impl::linlsqrreport*>(p_struct);
3172 : }
3173 0 : linlsqrreport::linlsqrreport() : _linlsqrreport_owner() ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype)
3174 : {
3175 0 : }
3176 :
3177 0 : linlsqrreport::linlsqrreport(const linlsqrreport &rhs):_linlsqrreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype)
3178 : {
3179 0 : }
3180 :
3181 0 : linlsqrreport& linlsqrreport::operator=(const linlsqrreport &rhs)
3182 : {
3183 0 : if( this==&rhs )
3184 0 : return *this;
3185 0 : _linlsqrreport_owner::operator=(rhs);
3186 0 : return *this;
3187 : }
3188 :
3189 0 : linlsqrreport::~linlsqrreport()
3190 : {
3191 0 : }
3192 :
3193 : /*************************************************************************
3194 : This function initializes linear LSQR Solver. This solver is used to solve
3195 : non-symmetric (and, possibly, non-square) problems. Least squares solution
3196 : is returned for non-compatible systems.
3197 :
3198 : USAGE:
3199 : 1. User initializes algorithm state with LinLSQRCreate() call
3200 : 2. User tunes solver parameters with LinLSQRSetCond() and other functions
3201 : 3. User calls LinLSQRSolveSparse() function which takes algorithm state
3202 : and SparseMatrix object.
3203 : 4. User calls LinLSQRResults() to get solution
3204 : 5. Optionally, user may call LinLSQRSolveSparse() again to solve another
3205 : problem with different matrix and/or right part without reinitializing
3206 : LinLSQRState structure.
3207 :
3208 : INPUT PARAMETERS:
3209 : M - number of rows in A
3210 : N - number of variables, N>0
3211 :
3212 : OUTPUT PARAMETERS:
3213 : State - structure which stores algorithm state
3214 :
3215 : NOTE: see also linlsqrcreatebuf() for version which reuses previously
3216 : allocated place as much as possible.
3217 :
3218 : -- ALGLIB --
3219 : Copyright 30.11.2011 by Bochkanov Sergey
3220 : *************************************************************************/
3221 0 : void linlsqrcreate(const ae_int_t m, const ae_int_t n, linlsqrstate &state, const xparams _xparams)
3222 : {
3223 : jmp_buf _break_jump;
3224 : alglib_impl::ae_state _alglib_env_state;
3225 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3226 0 : if( setjmp(_break_jump) )
3227 : {
3228 : #if !defined(AE_NO_EXCEPTIONS)
3229 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3230 : #else
3231 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3232 : return;
3233 : #endif
3234 : }
3235 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3236 0 : if( _xparams.flags!=0x0 )
3237 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3238 0 : alglib_impl::linlsqrcreate(m, n, const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
3239 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3240 0 : return;
3241 : }
3242 :
3243 : /*************************************************************************
3244 : This function initializes linear LSQR Solver. It provides exactly same
3245 : functionality as linlsqrcreate(), but reuses previously allocated space
3246 : as much as possible.
3247 :
3248 : INPUT PARAMETERS:
3249 : M - number of rows in A
3250 : N - number of variables, N>0
3251 :
3252 : OUTPUT PARAMETERS:
3253 : State - structure which stores algorithm state
3254 :
3255 : -- ALGLIB --
3256 : Copyright 14.11.2018 by Bochkanov Sergey
3257 : *************************************************************************/
3258 0 : void linlsqrcreatebuf(const ae_int_t m, const ae_int_t n, const linlsqrstate &state, const xparams _xparams)
3259 : {
3260 : jmp_buf _break_jump;
3261 : alglib_impl::ae_state _alglib_env_state;
3262 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3263 0 : if( setjmp(_break_jump) )
3264 : {
3265 : #if !defined(AE_NO_EXCEPTIONS)
3266 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3267 : #else
3268 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3269 : return;
3270 : #endif
3271 : }
3272 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3273 0 : if( _xparams.flags!=0x0 )
3274 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3275 0 : alglib_impl::linlsqrcreatebuf(m, n, const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
3276 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3277 0 : return;
3278 : }
3279 :
3280 : /*************************************************************************
3281 : This function changes preconditioning settings of LinLSQQSolveSparse()
3282 : function. By default, SolveSparse() uses diagonal preconditioner, but if
3283 : you want to use solver without preconditioning, you can call this function
3284 : which forces solver to use unit matrix for preconditioning.
3285 :
3286 : INPUT PARAMETERS:
3287 : State - structure which stores algorithm state
3288 :
3289 : -- ALGLIB --
3290 : Copyright 19.11.2012 by Bochkanov Sergey
3291 : *************************************************************************/
3292 0 : void linlsqrsetprecunit(const linlsqrstate &state, const xparams _xparams)
3293 : {
3294 : jmp_buf _break_jump;
3295 : alglib_impl::ae_state _alglib_env_state;
3296 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3297 0 : if( setjmp(_break_jump) )
3298 : {
3299 : #if !defined(AE_NO_EXCEPTIONS)
3300 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3301 : #else
3302 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3303 : return;
3304 : #endif
3305 : }
3306 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3307 0 : if( _xparams.flags!=0x0 )
3308 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3309 0 : alglib_impl::linlsqrsetprecunit(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
3310 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3311 0 : return;
3312 : }
3313 :
3314 : /*************************************************************************
3315 : This function changes preconditioning settings of LinCGSolveSparse()
3316 : function. LinCGSolveSparse() will use diagonal of the system matrix as
3317 : preconditioner. This preconditioning mode is active by default.
3318 :
3319 : INPUT PARAMETERS:
3320 : State - structure which stores algorithm state
3321 :
3322 : -- ALGLIB --
3323 : Copyright 19.11.2012 by Bochkanov Sergey
3324 : *************************************************************************/
3325 0 : void linlsqrsetprecdiag(const linlsqrstate &state, const xparams _xparams)
3326 : {
3327 : jmp_buf _break_jump;
3328 : alglib_impl::ae_state _alglib_env_state;
3329 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3330 0 : if( setjmp(_break_jump) )
3331 : {
3332 : #if !defined(AE_NO_EXCEPTIONS)
3333 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3334 : #else
3335 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3336 : return;
3337 : #endif
3338 : }
3339 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3340 0 : if( _xparams.flags!=0x0 )
3341 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3342 0 : alglib_impl::linlsqrsetprecdiag(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
3343 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3344 0 : return;
3345 : }
3346 :
3347 : /*************************************************************************
3348 : This function sets optional Tikhonov regularization coefficient.
3349 : It is zero by default.
3350 :
3351 : INPUT PARAMETERS:
3352 : LambdaI - regularization factor, LambdaI>=0
3353 :
3354 : OUTPUT PARAMETERS:
3355 : State - structure which stores algorithm state
3356 :
3357 : -- ALGLIB --
3358 : Copyright 30.11.2011 by Bochkanov Sergey
3359 : *************************************************************************/
3360 0 : void linlsqrsetlambdai(const linlsqrstate &state, const double lambdai, const xparams _xparams)
3361 : {
3362 : jmp_buf _break_jump;
3363 : alglib_impl::ae_state _alglib_env_state;
3364 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3365 0 : if( setjmp(_break_jump) )
3366 : {
3367 : #if !defined(AE_NO_EXCEPTIONS)
3368 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3369 : #else
3370 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3371 : return;
3372 : #endif
3373 : }
3374 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3375 0 : if( _xparams.flags!=0x0 )
3376 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3377 0 : alglib_impl::linlsqrsetlambdai(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), lambdai, &_alglib_env_state);
3378 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3379 0 : return;
3380 : }
3381 :
3382 : /*************************************************************************
3383 : Procedure for solution of A*x=b with sparse A.
3384 :
3385 : INPUT PARAMETERS:
3386 : State - algorithm state
3387 : A - sparse M*N matrix in the CRS format (you MUST contvert it
3388 : to CRS format by calling SparseConvertToCRS() function
3389 : BEFORE you pass it to this function).
3390 : B - right part, array[M]
3391 :
3392 : RESULT:
3393 : This function returns no result.
3394 : You can get solution by calling LinCGResults()
3395 :
3396 : NOTE: this function uses lightweight preconditioning - multiplication by
3397 : inverse of diag(A). If you want, you can turn preconditioning off by
3398 : calling LinLSQRSetPrecUnit(). However, preconditioning cost is low
3399 : and preconditioner is very important for solution of badly scaled
3400 : problems.
3401 :
3402 : -- ALGLIB --
3403 : Copyright 30.11.2011 by Bochkanov Sergey
3404 : *************************************************************************/
3405 0 : void linlsqrsolvesparse(const linlsqrstate &state, const sparsematrix &a, const real_1d_array &b, const xparams _xparams)
3406 : {
3407 : jmp_buf _break_jump;
3408 : alglib_impl::ae_state _alglib_env_state;
3409 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3410 0 : if( setjmp(_break_jump) )
3411 : {
3412 : #if !defined(AE_NO_EXCEPTIONS)
3413 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3414 : #else
3415 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3416 : return;
3417 : #endif
3418 : }
3419 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3420 0 : if( _xparams.flags!=0x0 )
3421 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3422 0 : alglib_impl::linlsqrsolvesparse(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &_alglib_env_state);
3423 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3424 0 : return;
3425 : }
3426 :
3427 : /*************************************************************************
3428 : This function sets stopping criteria.
3429 :
3430 : INPUT PARAMETERS:
3431 : EpsA - algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
3432 : EpsB - algorithm will be stopped if ||Rk||<=EpsB*||B||
3433 : MaxIts - algorithm will be stopped if number of iterations
3434 : more than MaxIts.
3435 :
3436 : OUTPUT PARAMETERS:
3437 : State - structure which stores algorithm state
3438 :
3439 : NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
3440 : be setted as default values.
3441 :
3442 : -- ALGLIB --
3443 : Copyright 30.11.2011 by Bochkanov Sergey
3444 : *************************************************************************/
3445 0 : void linlsqrsetcond(const linlsqrstate &state, const double epsa, const double epsb, const ae_int_t maxits, const xparams _xparams)
3446 : {
3447 : jmp_buf _break_jump;
3448 : alglib_impl::ae_state _alglib_env_state;
3449 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3450 0 : if( setjmp(_break_jump) )
3451 : {
3452 : #if !defined(AE_NO_EXCEPTIONS)
3453 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3454 : #else
3455 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3456 : return;
3457 : #endif
3458 : }
3459 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3460 0 : if( _xparams.flags!=0x0 )
3461 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3462 0 : alglib_impl::linlsqrsetcond(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), epsa, epsb, maxits, &_alglib_env_state);
3463 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3464 0 : return;
3465 : }
3466 :
3467 : /*************************************************************************
3468 : LSQR solver: results.
3469 :
3470 : This function must be called after LinLSQRSolve
3471 :
3472 : INPUT PARAMETERS:
3473 : State - algorithm state
3474 :
3475 : OUTPUT PARAMETERS:
3476 : X - array[N], solution
3477 : Rep - optimization report:
3478 : * Rep.TerminationType completetion code:
3479 : * 1 ||Rk||<=EpsB*||B||
3480 : * 4 ||A^T*Rk||/(||A||*||Rk||)<=EpsA
3481 : * 5 MaxIts steps was taken
3482 : * 7 rounding errors prevent further progress,
3483 : X contains best point found so far.
3484 : (sometimes returned on singular systems)
3485 : * 8 user requested termination via calling
3486 : linlsqrrequesttermination()
3487 : * Rep.IterationsCount contains iterations count
3488 : * NMV countains number of matrix-vector calculations
3489 :
3490 : -- ALGLIB --
3491 : Copyright 30.11.2011 by Bochkanov Sergey
3492 : *************************************************************************/
3493 0 : void linlsqrresults(const linlsqrstate &state, real_1d_array &x, linlsqrreport &rep, const xparams _xparams)
3494 : {
3495 : jmp_buf _break_jump;
3496 : alglib_impl::ae_state _alglib_env_state;
3497 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3498 0 : if( setjmp(_break_jump) )
3499 : {
3500 : #if !defined(AE_NO_EXCEPTIONS)
3501 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3502 : #else
3503 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3504 : return;
3505 : #endif
3506 : }
3507 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3508 0 : if( _xparams.flags!=0x0 )
3509 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3510 0 : alglib_impl::linlsqrresults(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::linlsqrreport*>(rep.c_ptr()), &_alglib_env_state);
3511 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3512 0 : return;
3513 : }
3514 :
3515 : /*************************************************************************
3516 : This function turns on/off reporting.
3517 :
3518 : INPUT PARAMETERS:
3519 : State - structure which stores algorithm state
3520 : NeedXRep- whether iteration reports are needed or not
3521 :
3522 : If NeedXRep is True, algorithm will call rep() callback function if it is
3523 : provided to MinCGOptimize().
3524 :
3525 : -- ALGLIB --
3526 : Copyright 30.11.2011 by Bochkanov Sergey
3527 : *************************************************************************/
3528 0 : void linlsqrsetxrep(const linlsqrstate &state, const bool needxrep, const xparams _xparams)
3529 : {
3530 : jmp_buf _break_jump;
3531 : alglib_impl::ae_state _alglib_env_state;
3532 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3533 0 : if( setjmp(_break_jump) )
3534 : {
3535 : #if !defined(AE_NO_EXCEPTIONS)
3536 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3537 : #else
3538 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3539 : return;
3540 : #endif
3541 : }
3542 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3543 0 : if( _xparams.flags!=0x0 )
3544 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3545 0 : alglib_impl::linlsqrsetxrep(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
3546 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3547 0 : return;
3548 : }
3549 :
3550 : /*************************************************************************
3551 : This function is used to peek into LSQR solver and get current iteration
3552 : counter. You can safely "peek" into the solver from another thread.
3553 :
3554 : INPUT PARAMETERS:
3555 : S - solver object
3556 :
3557 : RESULT:
3558 : iteration counter, in [0,INF)
3559 :
3560 : -- ALGLIB --
3561 : Copyright 21.05.2018 by Bochkanov Sergey
3562 : *************************************************************************/
3563 0 : ae_int_t linlsqrpeekiterationscount(const linlsqrstate &s, const xparams _xparams)
3564 : {
3565 : jmp_buf _break_jump;
3566 : alglib_impl::ae_state _alglib_env_state;
3567 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3568 0 : if( setjmp(_break_jump) )
3569 : {
3570 : #if !defined(AE_NO_EXCEPTIONS)
3571 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3572 : #else
3573 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3574 : return 0;
3575 : #endif
3576 : }
3577 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3578 0 : if( _xparams.flags!=0x0 )
3579 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3580 0 : alglib_impl::ae_int_t result = alglib_impl::linlsqrpeekiterationscount(const_cast<alglib_impl::linlsqrstate*>(s.c_ptr()), &_alglib_env_state);
3581 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3582 0 : return *(reinterpret_cast<ae_int_t*>(&result));
3583 : }
3584 :
3585 : /*************************************************************************
3586 : This subroutine submits request for termination of the running solver. It
3587 : can be called from some other thread which wants LSQR solver to terminate
3588 : (obviously, the thread running LSQR solver can not request termination
3589 : because it is already busy working on LSQR).
3590 :
3591 : As result, solver stops at point which was "current accepted" when
3592 : termination request was submitted and returns error code 8 (successful
3593 : termination). Such termination is a smooth process which properly
3594 : deallocates all temporaries.
3595 :
3596 : INPUT PARAMETERS:
3597 : State - solver structure
3598 :
3599 : NOTE: calling this function on solver which is NOT running will have no
3600 : effect.
3601 :
3602 : NOTE: multiple calls to this function are possible. First call is counted,
3603 : subsequent calls are silently ignored.
3604 :
3605 : NOTE: solver clears termination flag on its start, it means that if some
3606 : other thread will request termination too soon, its request will went
3607 : unnoticed.
3608 :
3609 : -- ALGLIB --
3610 : Copyright 08.10.2014 by Bochkanov Sergey
3611 : *************************************************************************/
3612 0 : void linlsqrrequesttermination(const linlsqrstate &state, const xparams _xparams)
3613 : {
3614 : jmp_buf _break_jump;
3615 : alglib_impl::ae_state _alglib_env_state;
3616 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3617 0 : if( setjmp(_break_jump) )
3618 : {
3619 : #if !defined(AE_NO_EXCEPTIONS)
3620 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3621 : #else
3622 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3623 : return;
3624 : #endif
3625 : }
3626 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3627 0 : if( _xparams.flags!=0x0 )
3628 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3629 0 : alglib_impl::linlsqrrequesttermination(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
3630 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3631 0 : return;
3632 : }
3633 : #endif
3634 :
3635 : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
3636 : /*************************************************************************
3637 :
3638 : *************************************************************************/
3639 0 : _polynomialsolverreport_owner::_polynomialsolverreport_owner()
3640 : {
3641 : jmp_buf _break_jump;
3642 : alglib_impl::ae_state _state;
3643 :
3644 0 : alglib_impl::ae_state_init(&_state);
3645 0 : if( setjmp(_break_jump) )
3646 : {
3647 0 : if( p_struct!=NULL )
3648 : {
3649 0 : alglib_impl::_polynomialsolverreport_destroy(p_struct);
3650 0 : alglib_impl::ae_free(p_struct);
3651 : }
3652 0 : p_struct = NULL;
3653 : #if !defined(AE_NO_EXCEPTIONS)
3654 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3655 : #else
3656 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3657 : return;
3658 : #endif
3659 : }
3660 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3661 0 : p_struct = NULL;
3662 0 : p_struct = (alglib_impl::polynomialsolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::polynomialsolverreport), &_state);
3663 0 : memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
3664 0 : alglib_impl::_polynomialsolverreport_init(p_struct, &_state, ae_false);
3665 0 : ae_state_clear(&_state);
3666 0 : }
3667 :
3668 0 : _polynomialsolverreport_owner::_polynomialsolverreport_owner(const _polynomialsolverreport_owner &rhs)
3669 : {
3670 : jmp_buf _break_jump;
3671 : alglib_impl::ae_state _state;
3672 :
3673 0 : alglib_impl::ae_state_init(&_state);
3674 0 : if( setjmp(_break_jump) )
3675 : {
3676 0 : if( p_struct!=NULL )
3677 : {
3678 0 : alglib_impl::_polynomialsolverreport_destroy(p_struct);
3679 0 : alglib_impl::ae_free(p_struct);
3680 : }
3681 0 : p_struct = NULL;
3682 : #if !defined(AE_NO_EXCEPTIONS)
3683 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3684 : #else
3685 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3686 : return;
3687 : #endif
3688 : }
3689 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3690 0 : p_struct = NULL;
3691 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: polynomialsolverreport copy constructor failure (source is not initialized)", &_state);
3692 0 : p_struct = (alglib_impl::polynomialsolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::polynomialsolverreport), &_state);
3693 0 : memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
3694 0 : alglib_impl::_polynomialsolverreport_init_copy(p_struct, const_cast<alglib_impl::polynomialsolverreport*>(rhs.p_struct), &_state, ae_false);
3695 0 : ae_state_clear(&_state);
3696 0 : }
3697 :
3698 0 : _polynomialsolverreport_owner& _polynomialsolverreport_owner::operator=(const _polynomialsolverreport_owner &rhs)
3699 : {
3700 0 : if( this==&rhs )
3701 0 : return *this;
3702 : jmp_buf _break_jump;
3703 : alglib_impl::ae_state _state;
3704 :
3705 0 : alglib_impl::ae_state_init(&_state);
3706 0 : if( setjmp(_break_jump) )
3707 : {
3708 : #if !defined(AE_NO_EXCEPTIONS)
3709 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3710 : #else
3711 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3712 : return *this;
3713 : #endif
3714 : }
3715 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3716 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: polynomialsolverreport assignment constructor failure (destination is not initialized)", &_state);
3717 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: polynomialsolverreport assignment constructor failure (source is not initialized)", &_state);
3718 0 : alglib_impl::_polynomialsolverreport_destroy(p_struct);
3719 0 : memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
3720 0 : alglib_impl::_polynomialsolverreport_init_copy(p_struct, const_cast<alglib_impl::polynomialsolverreport*>(rhs.p_struct), &_state, ae_false);
3721 0 : ae_state_clear(&_state);
3722 0 : return *this;
3723 : }
3724 :
3725 0 : _polynomialsolverreport_owner::~_polynomialsolverreport_owner()
3726 : {
3727 0 : if( p_struct!=NULL )
3728 : {
3729 0 : alglib_impl::_polynomialsolverreport_destroy(p_struct);
3730 0 : ae_free(p_struct);
3731 : }
3732 0 : }
3733 :
3734 0 : alglib_impl::polynomialsolverreport* _polynomialsolverreport_owner::c_ptr()
3735 : {
3736 0 : return p_struct;
3737 : }
3738 :
3739 0 : alglib_impl::polynomialsolverreport* _polynomialsolverreport_owner::c_ptr() const
3740 : {
3741 0 : return const_cast<alglib_impl::polynomialsolverreport*>(p_struct);
3742 : }
3743 0 : polynomialsolverreport::polynomialsolverreport() : _polynomialsolverreport_owner() ,maxerr(p_struct->maxerr)
3744 : {
3745 0 : }
3746 :
3747 0 : polynomialsolverreport::polynomialsolverreport(const polynomialsolverreport &rhs):_polynomialsolverreport_owner(rhs) ,maxerr(p_struct->maxerr)
3748 : {
3749 0 : }
3750 :
3751 0 : polynomialsolverreport& polynomialsolverreport::operator=(const polynomialsolverreport &rhs)
3752 : {
3753 0 : if( this==&rhs )
3754 0 : return *this;
3755 0 : _polynomialsolverreport_owner::operator=(rhs);
3756 0 : return *this;
3757 : }
3758 :
3759 0 : polynomialsolverreport::~polynomialsolverreport()
3760 : {
3761 0 : }
3762 :
3763 : /*************************************************************************
3764 : Polynomial root finding.
3765 :
3766 : This function returns all roots of the polynomial
3767 : P(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
3768 : Both real and complex roots are returned (see below).
3769 :
3770 : INPUT PARAMETERS:
3771 : A - array[N+1], polynomial coefficients:
3772 : * A[0] is constant term
3773 : * A[N] is a coefficient of X^N
3774 : N - polynomial degree
3775 :
3776 : OUTPUT PARAMETERS:
3777 : X - array of complex roots:
3778 : * for isolated real root, X[I] is strictly real: IMAGE(X[I])=0
3779 : * complex roots are always returned in pairs - roots occupy
3780 : positions I and I+1, with:
3781 : * X[I+1]=Conj(X[I])
3782 : * IMAGE(X[I]) > 0
3783 : * IMAGE(X[I+1]) = -IMAGE(X[I]) < 0
3784 : * multiple real roots may have non-zero imaginary part due
3785 : to roundoff errors. There is no reliable way to distinguish
3786 : real root of multiplicity 2 from two complex roots in
3787 : the presence of roundoff errors.
3788 : Rep - report, additional information, following fields are set:
3789 : * Rep.MaxErr - max( |P(xi)| ) for i=0..N-1. This field
3790 : allows to quickly estimate "quality" of the roots being
3791 : returned.
3792 :
3793 : NOTE: this function uses companion matrix method to find roots. In case
3794 : internal EVD solver fails do find eigenvalues, exception is
3795 : generated.
3796 :
3797 : NOTE: roots are not "polished" and no matrix balancing is performed
3798 : for them.
3799 :
3800 : -- ALGLIB --
3801 : Copyright 24.02.2014 by Bochkanov Sergey
3802 : *************************************************************************/
3803 0 : void polynomialsolve(const real_1d_array &a, const ae_int_t n, complex_1d_array &x, polynomialsolverreport &rep, const xparams _xparams)
3804 : {
3805 : jmp_buf _break_jump;
3806 : alglib_impl::ae_state _alglib_env_state;
3807 0 : alglib_impl::ae_state_init(&_alglib_env_state);
3808 0 : if( setjmp(_break_jump) )
3809 : {
3810 : #if !defined(AE_NO_EXCEPTIONS)
3811 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
3812 : #else
3813 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
3814 : return;
3815 : #endif
3816 : }
3817 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
3818 0 : if( _xparams.flags!=0x0 )
3819 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
3820 0 : alglib_impl::polynomialsolve(const_cast<alglib_impl::ae_vector*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::polynomialsolverreport*>(rep.c_ptr()), &_alglib_env_state);
3821 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
3822 0 : return;
3823 : }
3824 : #endif
3825 :
3826 : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
3827 : /*************************************************************************
3828 :
3829 : *************************************************************************/
3830 0 : _nleqstate_owner::_nleqstate_owner()
3831 : {
3832 : jmp_buf _break_jump;
3833 : alglib_impl::ae_state _state;
3834 :
3835 0 : alglib_impl::ae_state_init(&_state);
3836 0 : if( setjmp(_break_jump) )
3837 : {
3838 0 : if( p_struct!=NULL )
3839 : {
3840 0 : alglib_impl::_nleqstate_destroy(p_struct);
3841 0 : alglib_impl::ae_free(p_struct);
3842 : }
3843 0 : p_struct = NULL;
3844 : #if !defined(AE_NO_EXCEPTIONS)
3845 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3846 : #else
3847 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3848 : return;
3849 : #endif
3850 : }
3851 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3852 0 : p_struct = NULL;
3853 0 : p_struct = (alglib_impl::nleqstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqstate), &_state);
3854 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
3855 0 : alglib_impl::_nleqstate_init(p_struct, &_state, ae_false);
3856 0 : ae_state_clear(&_state);
3857 0 : }
3858 :
3859 0 : _nleqstate_owner::_nleqstate_owner(const _nleqstate_owner &rhs)
3860 : {
3861 : jmp_buf _break_jump;
3862 : alglib_impl::ae_state _state;
3863 :
3864 0 : alglib_impl::ae_state_init(&_state);
3865 0 : if( setjmp(_break_jump) )
3866 : {
3867 0 : if( p_struct!=NULL )
3868 : {
3869 0 : alglib_impl::_nleqstate_destroy(p_struct);
3870 0 : alglib_impl::ae_free(p_struct);
3871 : }
3872 0 : p_struct = NULL;
3873 : #if !defined(AE_NO_EXCEPTIONS)
3874 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3875 : #else
3876 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3877 : return;
3878 : #endif
3879 : }
3880 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3881 0 : p_struct = NULL;
3882 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqstate copy constructor failure (source is not initialized)", &_state);
3883 0 : p_struct = (alglib_impl::nleqstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqstate), &_state);
3884 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
3885 0 : alglib_impl::_nleqstate_init_copy(p_struct, const_cast<alglib_impl::nleqstate*>(rhs.p_struct), &_state, ae_false);
3886 0 : ae_state_clear(&_state);
3887 0 : }
3888 :
3889 0 : _nleqstate_owner& _nleqstate_owner::operator=(const _nleqstate_owner &rhs)
3890 : {
3891 0 : if( this==&rhs )
3892 0 : return *this;
3893 : jmp_buf _break_jump;
3894 : alglib_impl::ae_state _state;
3895 :
3896 0 : alglib_impl::ae_state_init(&_state);
3897 0 : if( setjmp(_break_jump) )
3898 : {
3899 : #if !defined(AE_NO_EXCEPTIONS)
3900 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3901 : #else
3902 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3903 : return *this;
3904 : #endif
3905 : }
3906 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3907 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: nleqstate assignment constructor failure (destination is not initialized)", &_state);
3908 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqstate assignment constructor failure (source is not initialized)", &_state);
3909 0 : alglib_impl::_nleqstate_destroy(p_struct);
3910 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
3911 0 : alglib_impl::_nleqstate_init_copy(p_struct, const_cast<alglib_impl::nleqstate*>(rhs.p_struct), &_state, ae_false);
3912 0 : ae_state_clear(&_state);
3913 0 : return *this;
3914 : }
3915 :
3916 0 : _nleqstate_owner::~_nleqstate_owner()
3917 : {
3918 0 : if( p_struct!=NULL )
3919 : {
3920 0 : alglib_impl::_nleqstate_destroy(p_struct);
3921 0 : ae_free(p_struct);
3922 : }
3923 0 : }
3924 :
3925 0 : alglib_impl::nleqstate* _nleqstate_owner::c_ptr()
3926 : {
3927 0 : return p_struct;
3928 : }
3929 :
3930 0 : alglib_impl::nleqstate* _nleqstate_owner::c_ptr() const
3931 : {
3932 0 : return const_cast<alglib_impl::nleqstate*>(p_struct);
3933 : }
3934 0 : nleqstate::nleqstate() : _nleqstate_owner() ,needf(p_struct->needf),needfij(p_struct->needfij),xupdated(p_struct->xupdated),f(p_struct->f),fi(&p_struct->fi),j(&p_struct->j),x(&p_struct->x)
3935 : {
3936 0 : }
3937 :
3938 0 : nleqstate::nleqstate(const nleqstate &rhs):_nleqstate_owner(rhs) ,needf(p_struct->needf),needfij(p_struct->needfij),xupdated(p_struct->xupdated),f(p_struct->f),fi(&p_struct->fi),j(&p_struct->j),x(&p_struct->x)
3939 : {
3940 0 : }
3941 :
3942 0 : nleqstate& nleqstate::operator=(const nleqstate &rhs)
3943 : {
3944 0 : if( this==&rhs )
3945 0 : return *this;
3946 0 : _nleqstate_owner::operator=(rhs);
3947 0 : return *this;
3948 : }
3949 :
3950 0 : nleqstate::~nleqstate()
3951 : {
3952 0 : }
3953 :
3954 :
3955 : /*************************************************************************
3956 :
3957 : *************************************************************************/
3958 0 : _nleqreport_owner::_nleqreport_owner()
3959 : {
3960 : jmp_buf _break_jump;
3961 : alglib_impl::ae_state _state;
3962 :
3963 0 : alglib_impl::ae_state_init(&_state);
3964 0 : if( setjmp(_break_jump) )
3965 : {
3966 0 : if( p_struct!=NULL )
3967 : {
3968 0 : alglib_impl::_nleqreport_destroy(p_struct);
3969 0 : alglib_impl::ae_free(p_struct);
3970 : }
3971 0 : p_struct = NULL;
3972 : #if !defined(AE_NO_EXCEPTIONS)
3973 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
3974 : #else
3975 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
3976 : return;
3977 : #endif
3978 : }
3979 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
3980 0 : p_struct = NULL;
3981 0 : p_struct = (alglib_impl::nleqreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqreport), &_state);
3982 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
3983 0 : alglib_impl::_nleqreport_init(p_struct, &_state, ae_false);
3984 0 : ae_state_clear(&_state);
3985 0 : }
3986 :
3987 0 : _nleqreport_owner::_nleqreport_owner(const _nleqreport_owner &rhs)
3988 : {
3989 : jmp_buf _break_jump;
3990 : alglib_impl::ae_state _state;
3991 :
3992 0 : alglib_impl::ae_state_init(&_state);
3993 0 : if( setjmp(_break_jump) )
3994 : {
3995 0 : if( p_struct!=NULL )
3996 : {
3997 0 : alglib_impl::_nleqreport_destroy(p_struct);
3998 0 : alglib_impl::ae_free(p_struct);
3999 : }
4000 0 : p_struct = NULL;
4001 : #if !defined(AE_NO_EXCEPTIONS)
4002 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4003 : #else
4004 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4005 : return;
4006 : #endif
4007 : }
4008 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4009 0 : p_struct = NULL;
4010 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqreport copy constructor failure (source is not initialized)", &_state);
4011 0 : p_struct = (alglib_impl::nleqreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqreport), &_state);
4012 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
4013 0 : alglib_impl::_nleqreport_init_copy(p_struct, const_cast<alglib_impl::nleqreport*>(rhs.p_struct), &_state, ae_false);
4014 0 : ae_state_clear(&_state);
4015 0 : }
4016 :
4017 0 : _nleqreport_owner& _nleqreport_owner::operator=(const _nleqreport_owner &rhs)
4018 : {
4019 0 : if( this==&rhs )
4020 0 : return *this;
4021 : jmp_buf _break_jump;
4022 : alglib_impl::ae_state _state;
4023 :
4024 0 : alglib_impl::ae_state_init(&_state);
4025 0 : if( setjmp(_break_jump) )
4026 : {
4027 : #if !defined(AE_NO_EXCEPTIONS)
4028 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4029 : #else
4030 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4031 : return *this;
4032 : #endif
4033 : }
4034 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4035 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: nleqreport assignment constructor failure (destination is not initialized)", &_state);
4036 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqreport assignment constructor failure (source is not initialized)", &_state);
4037 0 : alglib_impl::_nleqreport_destroy(p_struct);
4038 0 : memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
4039 0 : alglib_impl::_nleqreport_init_copy(p_struct, const_cast<alglib_impl::nleqreport*>(rhs.p_struct), &_state, ae_false);
4040 0 : ae_state_clear(&_state);
4041 0 : return *this;
4042 : }
4043 :
4044 0 : _nleqreport_owner::~_nleqreport_owner()
4045 : {
4046 0 : if( p_struct!=NULL )
4047 : {
4048 0 : alglib_impl::_nleqreport_destroy(p_struct);
4049 0 : ae_free(p_struct);
4050 : }
4051 0 : }
4052 :
4053 0 : alglib_impl::nleqreport* _nleqreport_owner::c_ptr()
4054 : {
4055 0 : return p_struct;
4056 : }
4057 :
4058 0 : alglib_impl::nleqreport* _nleqreport_owner::c_ptr() const
4059 : {
4060 0 : return const_cast<alglib_impl::nleqreport*>(p_struct);
4061 : }
4062 0 : nleqreport::nleqreport() : _nleqreport_owner() ,iterationscount(p_struct->iterationscount),nfunc(p_struct->nfunc),njac(p_struct->njac),terminationtype(p_struct->terminationtype)
4063 : {
4064 0 : }
4065 :
4066 0 : nleqreport::nleqreport(const nleqreport &rhs):_nleqreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nfunc(p_struct->nfunc),njac(p_struct->njac),terminationtype(p_struct->terminationtype)
4067 : {
4068 0 : }
4069 :
4070 0 : nleqreport& nleqreport::operator=(const nleqreport &rhs)
4071 : {
4072 0 : if( this==&rhs )
4073 0 : return *this;
4074 0 : _nleqreport_owner::operator=(rhs);
4075 0 : return *this;
4076 : }
4077 :
4078 0 : nleqreport::~nleqreport()
4079 : {
4080 0 : }
4081 :
4082 : /*************************************************************************
4083 : LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
4084 :
4085 : DESCRIPTION:
4086 : This algorithm solves system of nonlinear equations
4087 : F[0](x[0], ..., x[n-1]) = 0
4088 : F[1](x[0], ..., x[n-1]) = 0
4089 : ...
4090 : F[M-1](x[0], ..., x[n-1]) = 0
4091 : with M/N do not necessarily coincide. Algorithm converges quadratically
4092 : under following conditions:
4093 : * the solution set XS is nonempty
4094 : * for some xs in XS there exist such neighbourhood N(xs) that:
4095 : * vector function F(x) and its Jacobian J(x) are continuously
4096 : differentiable on N
4097 : * ||F(x)|| provides local error bound on N, i.e. there exists such
4098 : c1, that ||F(x)||>c1*distance(x,XS)
4099 : Note that these conditions are much more weaker than usual non-singularity
4100 : conditions. For example, algorithm will converge for any affine function
4101 : F (whether its Jacobian singular or not).
4102 :
4103 :
4104 : REQUIREMENTS:
4105 : Algorithm will request following information during its operation:
4106 : * function vector F[] and Jacobian matrix at given point X
4107 : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
4108 :
4109 :
4110 : USAGE:
4111 : 1. User initializes algorithm state with NLEQCreateLM() call
4112 : 2. User tunes solver parameters with NLEQSetCond(), NLEQSetStpMax() and
4113 : other functions
4114 : 3. User calls NLEQSolve() function which takes algorithm state and
4115 : pointers (delegates, etc.) to callback functions which calculate merit
4116 : function value and Jacobian.
4117 : 4. User calls NLEQResults() to get solution
4118 : 5. Optionally, user may call NLEQRestartFrom() to solve another problem
4119 : with same parameters (N/M) but another starting point and/or another
4120 : function vector. NLEQRestartFrom() allows to reuse already initialized
4121 : structure.
4122 :
4123 :
4124 : INPUT PARAMETERS:
4125 : N - space dimension, N>1:
4126 : * if provided, only leading N elements of X are used
4127 : * if not provided, determined automatically from size of X
4128 : M - system size
4129 : X - starting point
4130 :
4131 :
4132 : OUTPUT PARAMETERS:
4133 : State - structure which stores algorithm state
4134 :
4135 :
4136 : NOTES:
4137 : 1. you may tune stopping conditions with NLEQSetCond() function
4138 : 2. if target function contains exp() or other fast growing functions, and
4139 : optimization algorithm makes too large steps which leads to overflow,
4140 : use NLEQSetStpMax() function to bound algorithm's steps.
4141 : 3. this algorithm is a slightly modified implementation of the method
4142 : described in 'Levenberg-Marquardt method for constrained nonlinear
4143 : equations with strong local convergence properties' by Christian Kanzow
4144 : Nobuo Yamashita and Masao Fukushima and further developed in 'On the
4145 : convergence of a New Levenberg-Marquardt Method' by Jin-yan Fan and
4146 : Ya-Xiang Yuan.
4147 :
4148 :
4149 : -- ALGLIB --
4150 : Copyright 20.08.2009 by Bochkanov Sergey
4151 : *************************************************************************/
4152 0 : void nleqcreatelm(const ae_int_t n, const ae_int_t m, const real_1d_array &x, nleqstate &state, const xparams _xparams)
4153 : {
4154 : jmp_buf _break_jump;
4155 : alglib_impl::ae_state _alglib_env_state;
4156 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4157 0 : if( setjmp(_break_jump) )
4158 : {
4159 : #if !defined(AE_NO_EXCEPTIONS)
4160 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4161 : #else
4162 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4163 : return;
4164 : #endif
4165 : }
4166 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4167 0 : if( _xparams.flags!=0x0 )
4168 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4169 0 : alglib_impl::nleqcreatelm(n, m, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
4170 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4171 0 : return;
4172 : }
4173 :
4174 : /*************************************************************************
4175 : LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
4176 :
4177 : DESCRIPTION:
4178 : This algorithm solves system of nonlinear equations
4179 : F[0](x[0], ..., x[n-1]) = 0
4180 : F[1](x[0], ..., x[n-1]) = 0
4181 : ...
4182 : F[M-1](x[0], ..., x[n-1]) = 0
4183 : with M/N do not necessarily coincide. Algorithm converges quadratically
4184 : under following conditions:
4185 : * the solution set XS is nonempty
4186 : * for some xs in XS there exist such neighbourhood N(xs) that:
4187 : * vector function F(x) and its Jacobian J(x) are continuously
4188 : differentiable on N
4189 : * ||F(x)|| provides local error bound on N, i.e. there exists such
4190 : c1, that ||F(x)||>c1*distance(x,XS)
4191 : Note that these conditions are much more weaker than usual non-singularity
4192 : conditions. For example, algorithm will converge for any affine function
4193 : F (whether its Jacobian singular or not).
4194 :
4195 :
4196 : REQUIREMENTS:
4197 : Algorithm will request following information during its operation:
4198 : * function vector F[] and Jacobian matrix at given point X
4199 : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
4200 :
4201 :
4202 : USAGE:
4203 : 1. User initializes algorithm state with NLEQCreateLM() call
4204 : 2. User tunes solver parameters with NLEQSetCond(), NLEQSetStpMax() and
4205 : other functions
4206 : 3. User calls NLEQSolve() function which takes algorithm state and
4207 : pointers (delegates, etc.) to callback functions which calculate merit
4208 : function value and Jacobian.
4209 : 4. User calls NLEQResults() to get solution
4210 : 5. Optionally, user may call NLEQRestartFrom() to solve another problem
4211 : with same parameters (N/M) but another starting point and/or another
4212 : function vector. NLEQRestartFrom() allows to reuse already initialized
4213 : structure.
4214 :
4215 :
4216 : INPUT PARAMETERS:
4217 : N - space dimension, N>1:
4218 : * if provided, only leading N elements of X are used
4219 : * if not provided, determined automatically from size of X
4220 : M - system size
4221 : X - starting point
4222 :
4223 :
4224 : OUTPUT PARAMETERS:
4225 : State - structure which stores algorithm state
4226 :
4227 :
4228 : NOTES:
4229 : 1. you may tune stopping conditions with NLEQSetCond() function
4230 : 2. if target function contains exp() or other fast growing functions, and
4231 : optimization algorithm makes too large steps which leads to overflow,
4232 : use NLEQSetStpMax() function to bound algorithm's steps.
4233 : 3. this algorithm is a slightly modified implementation of the method
4234 : described in 'Levenberg-Marquardt method for constrained nonlinear
4235 : equations with strong local convergence properties' by Christian Kanzow
4236 : Nobuo Yamashita and Masao Fukushima and further developed in 'On the
4237 : convergence of a New Levenberg-Marquardt Method' by Jin-yan Fan and
4238 : Ya-Xiang Yuan.
4239 :
4240 :
4241 : -- ALGLIB --
4242 : Copyright 20.08.2009 by Bochkanov Sergey
4243 : *************************************************************************/
4244 : #if !defined(AE_NO_EXCEPTIONS)
4245 0 : void nleqcreatelm(const ae_int_t m, const real_1d_array &x, nleqstate &state, const xparams _xparams)
4246 : {
4247 : jmp_buf _break_jump;
4248 : alglib_impl::ae_state _alglib_env_state;
4249 : ae_int_t n;
4250 :
4251 0 : n = x.length();
4252 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4253 0 : if( setjmp(_break_jump) )
4254 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4255 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4256 0 : if( _xparams.flags!=0x0 )
4257 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4258 0 : alglib_impl::nleqcreatelm(n, m, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
4259 :
4260 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4261 0 : return;
4262 : }
4263 : #endif
4264 :
4265 : /*************************************************************************
4266 : This function sets stopping conditions for the nonlinear solver
4267 :
4268 : INPUT PARAMETERS:
4269 : State - structure which stores algorithm state
4270 : EpsF - >=0
4271 : The subroutine finishes its work if on k+1-th iteration
4272 : the condition ||F||<=EpsF is satisfied
4273 : MaxIts - maximum number of iterations. If MaxIts=0, the number of
4274 : iterations is unlimited.
4275 :
4276 : Passing EpsF=0 and MaxIts=0 simultaneously will lead to automatic
4277 : stopping criterion selection (small EpsF).
4278 :
4279 : NOTES:
4280 :
4281 : -- ALGLIB --
4282 : Copyright 20.08.2010 by Bochkanov Sergey
4283 : *************************************************************************/
4284 0 : void nleqsetcond(const nleqstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams)
4285 : {
4286 : jmp_buf _break_jump;
4287 : alglib_impl::ae_state _alglib_env_state;
4288 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4289 0 : if( setjmp(_break_jump) )
4290 : {
4291 : #if !defined(AE_NO_EXCEPTIONS)
4292 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4293 : #else
4294 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4295 : return;
4296 : #endif
4297 : }
4298 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4299 0 : if( _xparams.flags!=0x0 )
4300 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4301 0 : alglib_impl::nleqsetcond(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), epsf, maxits, &_alglib_env_state);
4302 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4303 0 : return;
4304 : }
4305 :
4306 : /*************************************************************************
4307 : This function turns on/off reporting.
4308 :
4309 : INPUT PARAMETERS:
4310 : State - structure which stores algorithm state
4311 : NeedXRep- whether iteration reports are needed or not
4312 :
4313 : If NeedXRep is True, algorithm will call rep() callback function if it is
4314 : provided to NLEQSolve().
4315 :
4316 : -- ALGLIB --
4317 : Copyright 20.08.2010 by Bochkanov Sergey
4318 : *************************************************************************/
4319 0 : void nleqsetxrep(const nleqstate &state, const bool needxrep, const xparams _xparams)
4320 : {
4321 : jmp_buf _break_jump;
4322 : alglib_impl::ae_state _alglib_env_state;
4323 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4324 0 : if( setjmp(_break_jump) )
4325 : {
4326 : #if !defined(AE_NO_EXCEPTIONS)
4327 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4328 : #else
4329 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4330 : return;
4331 : #endif
4332 : }
4333 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4334 0 : if( _xparams.flags!=0x0 )
4335 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4336 0 : alglib_impl::nleqsetxrep(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
4337 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4338 0 : return;
4339 : }
4340 :
4341 : /*************************************************************************
4342 : This function sets maximum step length
4343 :
4344 : INPUT PARAMETERS:
4345 : State - structure which stores algorithm state
4346 : StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't
4347 : want to limit step length.
4348 :
4349 : Use this subroutine when target function contains exp() or other fast
4350 : growing functions, and algorithm makes too large steps which lead to
4351 : overflow. This function allows us to reject steps that are too large (and
4352 : therefore expose us to the possible overflow) without actually calculating
4353 : function value at the x+stp*d.
4354 :
4355 : -- ALGLIB --
4356 : Copyright 20.08.2010 by Bochkanov Sergey
4357 : *************************************************************************/
4358 0 : void nleqsetstpmax(const nleqstate &state, const double stpmax, const xparams _xparams)
4359 : {
4360 : jmp_buf _break_jump;
4361 : alglib_impl::ae_state _alglib_env_state;
4362 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4363 0 : if( setjmp(_break_jump) )
4364 : {
4365 : #if !defined(AE_NO_EXCEPTIONS)
4366 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4367 : #else
4368 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4369 : return;
4370 : #endif
4371 : }
4372 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4373 0 : if( _xparams.flags!=0x0 )
4374 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4375 0 : alglib_impl::nleqsetstpmax(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), stpmax, &_alglib_env_state);
4376 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4377 0 : return;
4378 : }
4379 :
4380 : /*************************************************************************
4381 : This function provides reverse communication interface
4382 : Reverse communication interface is not documented or recommended to use.
4383 : See below for functions which provide better documented API
4384 : *************************************************************************/
4385 0 : bool nleqiteration(const nleqstate &state, const xparams _xparams)
4386 : {
4387 : jmp_buf _break_jump;
4388 : alglib_impl::ae_state _alglib_env_state;
4389 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4390 0 : if( setjmp(_break_jump) )
4391 : {
4392 : #if !defined(AE_NO_EXCEPTIONS)
4393 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4394 : #else
4395 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4396 : return 0;
4397 : #endif
4398 : }
4399 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4400 0 : if( _xparams.flags!=0x0 )
4401 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4402 0 : ae_bool result = alglib_impl::nleqiteration(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
4403 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4404 0 : return *(reinterpret_cast<bool*>(&result));
4405 : }
4406 :
4407 :
4408 0 : void nleqsolve(nleqstate &state,
4409 : void (*func)(const real_1d_array &x, double &func, void *ptr),
4410 : void (*jac)(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr),
4411 : void (*rep)(const real_1d_array &x, double func, void *ptr),
4412 : void *ptr,
4413 : const xparams _xparams)
4414 : {
4415 : jmp_buf _break_jump;
4416 : alglib_impl::ae_state _alglib_env_state;
4417 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4418 0 : if( setjmp(_break_jump) )
4419 : {
4420 : #if !defined(AE_NO_EXCEPTIONS)
4421 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4422 : #else
4423 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4424 : return;
4425 : #endif
4426 : }
4427 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4428 0 : if( _xparams.flags!=0x0 )
4429 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4430 0 : alglib_impl::ae_assert(func!=NULL, "ALGLIB: error in 'nleqsolve()' (func is NULL)", &_alglib_env_state);
4431 0 : alglib_impl::ae_assert(jac!=NULL, "ALGLIB: error in 'nleqsolve()' (jac is NULL)", &_alglib_env_state);
4432 0 : while( alglib_impl::nleqiteration(state.c_ptr(), &_alglib_env_state) )
4433 : {
4434 : _ALGLIB_CALLBACK_EXCEPTION_GUARD_BEGIN
4435 0 : if( state.needf )
4436 : {
4437 0 : func(state.x, state.f, ptr);
4438 0 : continue;
4439 : }
4440 0 : if( state.needfij )
4441 : {
4442 0 : jac(state.x, state.fi, state.j, ptr);
4443 0 : continue;
4444 : }
4445 0 : if( state.xupdated )
4446 : {
4447 0 : if( rep!=NULL )
4448 0 : rep(state.x, state.f, ptr);
4449 0 : continue;
4450 : }
4451 0 : goto lbl_no_callback;
4452 0 : _ALGLIB_CALLBACK_EXCEPTION_GUARD_END
4453 0 : lbl_no_callback:
4454 0 : alglib_impl::ae_assert(ae_false, "ALGLIB: error in 'nleqsolve' (some derivatives were not provided?)", &_alglib_env_state);
4455 : }
4456 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4457 0 : }
4458 :
4459 :
4460 :
4461 : /*************************************************************************
4462 : NLEQ solver results
4463 :
4464 : INPUT PARAMETERS:
4465 : State - algorithm state.
4466 :
4467 : OUTPUT PARAMETERS:
4468 : X - array[0..N-1], solution
4469 : Rep - optimization report:
4470 : * Rep.TerminationType completetion code:
4471 : * -4 ERROR: algorithm has converged to the
4472 : stationary point Xf which is local minimum of
4473 : f=F[0]^2+...+F[m-1]^2, but is not solution of
4474 : nonlinear system.
4475 : * 1 sqrt(f)<=EpsF.
4476 : * 5 MaxIts steps was taken
4477 : * 7 stopping conditions are too stringent,
4478 : further improvement is impossible
4479 : * Rep.IterationsCount contains iterations count
4480 : * NFEV countains number of function calculations
4481 : * ActiveConstraints contains number of active constraints
4482 :
4483 : -- ALGLIB --
4484 : Copyright 20.08.2009 by Bochkanov Sergey
4485 : *************************************************************************/
4486 0 : void nleqresults(const nleqstate &state, real_1d_array &x, nleqreport &rep, const xparams _xparams)
4487 : {
4488 : jmp_buf _break_jump;
4489 : alglib_impl::ae_state _alglib_env_state;
4490 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4491 0 : if( setjmp(_break_jump) )
4492 : {
4493 : #if !defined(AE_NO_EXCEPTIONS)
4494 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4495 : #else
4496 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4497 : return;
4498 : #endif
4499 : }
4500 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4501 0 : if( _xparams.flags!=0x0 )
4502 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4503 0 : alglib_impl::nleqresults(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqreport*>(rep.c_ptr()), &_alglib_env_state);
4504 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4505 0 : return;
4506 : }
4507 :
4508 : /*************************************************************************
4509 : NLEQ solver results
4510 :
4511 : Buffered implementation of NLEQResults(), which uses pre-allocated buffer
4512 : to store X[]. If buffer size is too small, it resizes buffer. It is
4513 : intended to be used in the inner cycles of performance critical algorithms
4514 : where array reallocation penalty is too large to be ignored.
4515 :
4516 : -- ALGLIB --
4517 : Copyright 20.08.2009 by Bochkanov Sergey
4518 : *************************************************************************/
4519 0 : void nleqresultsbuf(const nleqstate &state, real_1d_array &x, nleqreport &rep, const xparams _xparams)
4520 : {
4521 : jmp_buf _break_jump;
4522 : alglib_impl::ae_state _alglib_env_state;
4523 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4524 0 : if( setjmp(_break_jump) )
4525 : {
4526 : #if !defined(AE_NO_EXCEPTIONS)
4527 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4528 : #else
4529 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4530 : return;
4531 : #endif
4532 : }
4533 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4534 0 : if( _xparams.flags!=0x0 )
4535 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4536 0 : alglib_impl::nleqresultsbuf(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqreport*>(rep.c_ptr()), &_alglib_env_state);
4537 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4538 0 : return;
4539 : }
4540 :
4541 : /*************************************************************************
4542 : This subroutine restarts CG algorithm from new point. All optimization
4543 : parameters are left unchanged.
4544 :
4545 : This function allows to solve multiple optimization problems (which
4546 : must have same number of dimensions) without object reallocation penalty.
4547 :
4548 : INPUT PARAMETERS:
4549 : State - structure used for reverse communication previously
4550 : allocated with MinCGCreate call.
4551 : X - new starting point.
4552 : BndL - new lower bounds
4553 : BndU - new upper bounds
4554 :
4555 : -- ALGLIB --
4556 : Copyright 30.07.2010 by Bochkanov Sergey
4557 : *************************************************************************/
4558 0 : void nleqrestartfrom(const nleqstate &state, const real_1d_array &x, const xparams _xparams)
4559 : {
4560 : jmp_buf _break_jump;
4561 : alglib_impl::ae_state _alglib_env_state;
4562 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4563 0 : if( setjmp(_break_jump) )
4564 : {
4565 : #if !defined(AE_NO_EXCEPTIONS)
4566 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4567 : #else
4568 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4569 : return;
4570 : #endif
4571 : }
4572 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4573 0 : if( _xparams.flags!=0x0 )
4574 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4575 0 : alglib_impl::nleqrestartfrom(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
4576 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4577 0 : return;
4578 : }
4579 : #endif
4580 :
4581 : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
4582 : /*************************************************************************
4583 : This structure is a sparse solver report.
4584 :
4585 : Following fields can be accessed by users:
4586 : *************************************************************************/
4587 0 : _sparsesolverreport_owner::_sparsesolverreport_owner()
4588 : {
4589 : jmp_buf _break_jump;
4590 : alglib_impl::ae_state _state;
4591 :
4592 0 : alglib_impl::ae_state_init(&_state);
4593 0 : if( setjmp(_break_jump) )
4594 : {
4595 0 : if( p_struct!=NULL )
4596 : {
4597 0 : alglib_impl::_sparsesolverreport_destroy(p_struct);
4598 0 : alglib_impl::ae_free(p_struct);
4599 : }
4600 0 : p_struct = NULL;
4601 : #if !defined(AE_NO_EXCEPTIONS)
4602 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4603 : #else
4604 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4605 : return;
4606 : #endif
4607 : }
4608 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4609 0 : p_struct = NULL;
4610 0 : p_struct = (alglib_impl::sparsesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::sparsesolverreport), &_state);
4611 0 : memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
4612 0 : alglib_impl::_sparsesolverreport_init(p_struct, &_state, ae_false);
4613 0 : ae_state_clear(&_state);
4614 0 : }
4615 :
4616 0 : _sparsesolverreport_owner::_sparsesolverreport_owner(const _sparsesolverreport_owner &rhs)
4617 : {
4618 : jmp_buf _break_jump;
4619 : alglib_impl::ae_state _state;
4620 :
4621 0 : alglib_impl::ae_state_init(&_state);
4622 0 : if( setjmp(_break_jump) )
4623 : {
4624 0 : if( p_struct!=NULL )
4625 : {
4626 0 : alglib_impl::_sparsesolverreport_destroy(p_struct);
4627 0 : alglib_impl::ae_free(p_struct);
4628 : }
4629 0 : p_struct = NULL;
4630 : #if !defined(AE_NO_EXCEPTIONS)
4631 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4632 : #else
4633 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4634 : return;
4635 : #endif
4636 : }
4637 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4638 0 : p_struct = NULL;
4639 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: sparsesolverreport copy constructor failure (source is not initialized)", &_state);
4640 0 : p_struct = (alglib_impl::sparsesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::sparsesolverreport), &_state);
4641 0 : memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
4642 0 : alglib_impl::_sparsesolverreport_init_copy(p_struct, const_cast<alglib_impl::sparsesolverreport*>(rhs.p_struct), &_state, ae_false);
4643 0 : ae_state_clear(&_state);
4644 0 : }
4645 :
4646 0 : _sparsesolverreport_owner& _sparsesolverreport_owner::operator=(const _sparsesolverreport_owner &rhs)
4647 : {
4648 0 : if( this==&rhs )
4649 0 : return *this;
4650 : jmp_buf _break_jump;
4651 : alglib_impl::ae_state _state;
4652 :
4653 0 : alglib_impl::ae_state_init(&_state);
4654 0 : if( setjmp(_break_jump) )
4655 : {
4656 : #if !defined(AE_NO_EXCEPTIONS)
4657 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4658 : #else
4659 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4660 : return *this;
4661 : #endif
4662 : }
4663 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4664 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: sparsesolverreport assignment constructor failure (destination is not initialized)", &_state);
4665 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: sparsesolverreport assignment constructor failure (source is not initialized)", &_state);
4666 0 : alglib_impl::_sparsesolverreport_destroy(p_struct);
4667 0 : memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
4668 0 : alglib_impl::_sparsesolverreport_init_copy(p_struct, const_cast<alglib_impl::sparsesolverreport*>(rhs.p_struct), &_state, ae_false);
4669 0 : ae_state_clear(&_state);
4670 0 : return *this;
4671 : }
4672 :
4673 0 : _sparsesolverreport_owner::~_sparsesolverreport_owner()
4674 : {
4675 0 : if( p_struct!=NULL )
4676 : {
4677 0 : alglib_impl::_sparsesolverreport_destroy(p_struct);
4678 0 : ae_free(p_struct);
4679 : }
4680 0 : }
4681 :
4682 0 : alglib_impl::sparsesolverreport* _sparsesolverreport_owner::c_ptr()
4683 : {
4684 0 : return p_struct;
4685 : }
4686 :
4687 0 : alglib_impl::sparsesolverreport* _sparsesolverreport_owner::c_ptr() const
4688 : {
4689 0 : return const_cast<alglib_impl::sparsesolverreport*>(p_struct);
4690 : }
4691 0 : sparsesolverreport::sparsesolverreport() : _sparsesolverreport_owner() ,terminationtype(p_struct->terminationtype)
4692 : {
4693 0 : }
4694 :
4695 0 : sparsesolverreport::sparsesolverreport(const sparsesolverreport &rhs):_sparsesolverreport_owner(rhs) ,terminationtype(p_struct->terminationtype)
4696 : {
4697 0 : }
4698 :
4699 0 : sparsesolverreport& sparsesolverreport::operator=(const sparsesolverreport &rhs)
4700 : {
4701 0 : if( this==&rhs )
4702 0 : return *this;
4703 0 : _sparsesolverreport_owner::operator=(rhs);
4704 0 : return *this;
4705 : }
4706 :
4707 0 : sparsesolverreport::~sparsesolverreport()
4708 : {
4709 0 : }
4710 :
4711 : /*************************************************************************
4712 : Sparse linear solver for A*x=b with N*N sparse real symmetric positive
4713 : definite matrix A, N*1 vectors x and b.
4714 :
4715 : This solver converts input matrix to SKS format, performs Cholesky
4716 : factorization using SKS Cholesky subroutine (works well for limited
4717 : bandwidth matrices) and uses sparse triangular solvers to get solution of
4718 : the original system.
4719 :
4720 : INPUT PARAMETERS
4721 : A - sparse matrix, must be NxN exactly
4722 : IsUpper - which half of A is provided (another half is ignored)
4723 : B - array[0..N-1], right part
4724 :
4725 : OUTPUT PARAMETERS
4726 : X - array[N], it contains:
4727 : * rep.terminationtype>0 => solution
4728 : * rep.terminationtype=-3 => filled by zeros
4729 : Rep - solver report, following fields are set:
4730 : * rep.terminationtype - solver status; >0 for success,
4731 : set to -3 on failure (degenerate or non-SPD system).
4732 :
4733 : -- ALGLIB --
4734 : Copyright 26.12.2017 by Bochkanov Sergey
4735 : *************************************************************************/
4736 0 : void sparsespdsolvesks(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
4737 : {
4738 : jmp_buf _break_jump;
4739 : alglib_impl::ae_state _alglib_env_state;
4740 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4741 0 : if( setjmp(_break_jump) )
4742 : {
4743 : #if !defined(AE_NO_EXCEPTIONS)
4744 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4745 : #else
4746 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4747 : return;
4748 : #endif
4749 : }
4750 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4751 0 : if( _xparams.flags!=0x0 )
4752 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4753 0 : alglib_impl::sparsespdsolvesks(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
4754 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4755 0 : return;
4756 : }
4757 :
4758 : /*************************************************************************
4759 : Sparse linear solver for A*x=b with N*N sparse real symmetric positive
4760 : definite matrix A, N*1 vectors x and b.
4761 :
4762 : This solver converts input matrix to CRS format, performs Cholesky
4763 : factorization using supernodal Cholesky decomposition with permutation-
4764 : reducing ordering and uses sparse triangular solver to get solution of the
4765 : original system.
4766 :
4767 : INPUT PARAMETERS
4768 : A - sparse matrix, must be NxN exactly
4769 : IsUpper - which half of A is provided (another half is ignored)
4770 : B - array[N], right part
4771 :
4772 : OUTPUT PARAMETERS
4773 : X - array[N], it contains:
4774 : * rep.terminationtype>0 => solution
4775 : * rep.terminationtype=-3 => filled by zeros
4776 : Rep - solver report, following fields are set:
4777 : * rep.terminationtype - solver status; >0 for success,
4778 : set to -3 on failure (degenerate or non-SPD system).
4779 :
4780 : -- ALGLIB --
4781 : Copyright 26.12.2017 by Bochkanov Sergey
4782 : *************************************************************************/
4783 0 : void sparsespdsolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
4784 : {
4785 : jmp_buf _break_jump;
4786 : alglib_impl::ae_state _alglib_env_state;
4787 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4788 0 : if( setjmp(_break_jump) )
4789 : {
4790 : #if !defined(AE_NO_EXCEPTIONS)
4791 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4792 : #else
4793 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4794 : return;
4795 : #endif
4796 : }
4797 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4798 0 : if( _xparams.flags!=0x0 )
4799 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4800 0 : alglib_impl::sparsespdsolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
4801 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4802 0 : return;
4803 : }
4804 :
4805 : /*************************************************************************
4806 : Sparse linear solver for A*x=b with N*N real symmetric positive definite
4807 : matrix A given by its Cholesky decomposition, and N*1 vectors x and b.
4808 :
4809 : IMPORTANT: this solver requires input matrix to be in the SKS (Skyline)
4810 : or CRS (compressed row storage) format. An exception will be
4811 : generated if you pass matrix in some other format.
4812 :
4813 : INPUT PARAMETERS
4814 : A - sparse NxN matrix stored in CRs or SKS format, must be NxN
4815 : exactly
4816 : IsUpper - which half of A is provided (another half is ignored)
4817 : B - array[N], right part
4818 :
4819 : OUTPUT PARAMETERS
4820 : X - array[N], it contains:
4821 : * rep.terminationtype>0 => solution
4822 : * rep.terminationtype=-3 => filled by zeros
4823 : Rep - solver report, following fields are set:
4824 : * rep.terminationtype - solver status; >0 for success,
4825 : set to -3 on failure (degenerate or non-SPD system).
4826 :
4827 : -- ALGLIB --
4828 : Copyright 26.12.2017 by Bochkanov Sergey
4829 : *************************************************************************/
4830 0 : void sparsespdcholeskysolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
4831 : {
4832 : jmp_buf _break_jump;
4833 : alglib_impl::ae_state _alglib_env_state;
4834 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4835 0 : if( setjmp(_break_jump) )
4836 : {
4837 : #if !defined(AE_NO_EXCEPTIONS)
4838 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4839 : #else
4840 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4841 : return;
4842 : #endif
4843 : }
4844 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4845 0 : if( _xparams.flags!=0x0 )
4846 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4847 0 : alglib_impl::sparsespdcholeskysolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
4848 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4849 0 : return;
4850 : }
4851 :
4852 : /*************************************************************************
4853 : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
4854 : matrix A, N*1 vectors x and b.
4855 :
4856 : This solver converts input matrix to CRS format, performs LU factorization
4857 : and uses sparse triangular solvers to get solution of the original system.
4858 :
4859 : INPUT PARAMETERS
4860 : A - sparse matrix, must be NxN exactly, any storage format
4861 : N - size of A, N>0
4862 : B - array[0..N-1], right part
4863 :
4864 : OUTPUT PARAMETERS
4865 : X - array[N], it contains:
4866 : * rep.terminationtype>0 => solution
4867 : * rep.terminationtype=-3 => filled by zeros
4868 : Rep - solver report, following fields are set:
4869 : * rep.terminationtype - solver status; >0 for success,
4870 : set to -3 on failure (degenerate system).
4871 :
4872 : -- ALGLIB --
4873 : Copyright 26.12.2017 by Bochkanov Sergey
4874 : *************************************************************************/
4875 0 : void sparsesolve(const sparsematrix &a, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
4876 : {
4877 : jmp_buf _break_jump;
4878 : alglib_impl::ae_state _alglib_env_state;
4879 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4880 0 : if( setjmp(_break_jump) )
4881 : {
4882 : #if !defined(AE_NO_EXCEPTIONS)
4883 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4884 : #else
4885 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4886 : return;
4887 : #endif
4888 : }
4889 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4890 0 : if( _xparams.flags!=0x0 )
4891 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4892 0 : alglib_impl::sparsesolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
4893 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4894 0 : return;
4895 : }
4896 :
4897 : /*************************************************************************
4898 : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
4899 : matrix A given by its LU factorization, N*1 vectors x and b.
4900 :
4901 : IMPORTANT: this solver requires input matrix to be in the CRS sparse
4902 : storage format. An exception will be generated if you pass
4903 : matrix in some other format (HASH or SKS).
4904 :
4905 : INPUT PARAMETERS
4906 : A - LU factorization of the sparse matrix, must be NxN exactly
4907 : in CRS storage format
4908 : P, Q - pivot indexes from LU factorization
4909 : N - size of A, N>0
4910 : B - array[0..N-1], right part
4911 :
4912 : OUTPUT PARAMETERS
4913 : X - array[N], it contains:
4914 : * rep.terminationtype>0 => solution
4915 : * rep.terminationtype=-3 => filled by zeros
4916 : Rep - solver report, following fields are set:
4917 : * rep.terminationtype - solver status; >0 for success,
4918 : set to -3 on failure (degenerate system).
4919 :
4920 : -- ALGLIB --
4921 : Copyright 26.12.2017 by Bochkanov Sergey
4922 : *************************************************************************/
4923 0 : void sparselusolve(const sparsematrix &a, const integer_1d_array &p, const integer_1d_array &q, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
4924 : {
4925 : jmp_buf _break_jump;
4926 : alglib_impl::ae_state _alglib_env_state;
4927 0 : alglib_impl::ae_state_init(&_alglib_env_state);
4928 0 : if( setjmp(_break_jump) )
4929 : {
4930 : #if !defined(AE_NO_EXCEPTIONS)
4931 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
4932 : #else
4933 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
4934 : return;
4935 : #endif
4936 : }
4937 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
4938 0 : if( _xparams.flags!=0x0 )
4939 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
4940 0 : alglib_impl::sparselusolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), const_cast<alglib_impl::ae_vector*>(q.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
4941 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
4942 0 : return;
4943 : }
4944 : #endif
4945 :
4946 : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
4947 : /*************************************************************************
4948 : This object stores state of the linear CG method.
4949 :
4950 : You should use ALGLIB functions to work with this object.
4951 : Never try to access its fields directly!
4952 : *************************************************************************/
4953 0 : _lincgstate_owner::_lincgstate_owner()
4954 : {
4955 : jmp_buf _break_jump;
4956 : alglib_impl::ae_state _state;
4957 :
4958 0 : alglib_impl::ae_state_init(&_state);
4959 0 : if( setjmp(_break_jump) )
4960 : {
4961 0 : if( p_struct!=NULL )
4962 : {
4963 0 : alglib_impl::_lincgstate_destroy(p_struct);
4964 0 : alglib_impl::ae_free(p_struct);
4965 : }
4966 0 : p_struct = NULL;
4967 : #if !defined(AE_NO_EXCEPTIONS)
4968 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4969 : #else
4970 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
4971 : return;
4972 : #endif
4973 : }
4974 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
4975 0 : p_struct = NULL;
4976 0 : p_struct = (alglib_impl::lincgstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgstate), &_state);
4977 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
4978 0 : alglib_impl::_lincgstate_init(p_struct, &_state, ae_false);
4979 0 : ae_state_clear(&_state);
4980 0 : }
4981 :
4982 0 : _lincgstate_owner::_lincgstate_owner(const _lincgstate_owner &rhs)
4983 : {
4984 : jmp_buf _break_jump;
4985 : alglib_impl::ae_state _state;
4986 :
4987 0 : alglib_impl::ae_state_init(&_state);
4988 0 : if( setjmp(_break_jump) )
4989 : {
4990 0 : if( p_struct!=NULL )
4991 : {
4992 0 : alglib_impl::_lincgstate_destroy(p_struct);
4993 0 : alglib_impl::ae_free(p_struct);
4994 : }
4995 0 : p_struct = NULL;
4996 : #if !defined(AE_NO_EXCEPTIONS)
4997 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
4998 : #else
4999 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
5000 : return;
5001 : #endif
5002 : }
5003 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
5004 0 : p_struct = NULL;
5005 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgstate copy constructor failure (source is not initialized)", &_state);
5006 0 : p_struct = (alglib_impl::lincgstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgstate), &_state);
5007 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
5008 0 : alglib_impl::_lincgstate_init_copy(p_struct, const_cast<alglib_impl::lincgstate*>(rhs.p_struct), &_state, ae_false);
5009 0 : ae_state_clear(&_state);
5010 0 : }
5011 :
5012 0 : _lincgstate_owner& _lincgstate_owner::operator=(const _lincgstate_owner &rhs)
5013 : {
5014 0 : if( this==&rhs )
5015 0 : return *this;
5016 : jmp_buf _break_jump;
5017 : alglib_impl::ae_state _state;
5018 :
5019 0 : alglib_impl::ae_state_init(&_state);
5020 0 : if( setjmp(_break_jump) )
5021 : {
5022 : #if !defined(AE_NO_EXCEPTIONS)
5023 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
5024 : #else
5025 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
5026 : return *this;
5027 : #endif
5028 : }
5029 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
5030 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: lincgstate assignment constructor failure (destination is not initialized)", &_state);
5031 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgstate assignment constructor failure (source is not initialized)", &_state);
5032 0 : alglib_impl::_lincgstate_destroy(p_struct);
5033 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
5034 0 : alglib_impl::_lincgstate_init_copy(p_struct, const_cast<alglib_impl::lincgstate*>(rhs.p_struct), &_state, ae_false);
5035 0 : ae_state_clear(&_state);
5036 0 : return *this;
5037 : }
5038 :
5039 0 : _lincgstate_owner::~_lincgstate_owner()
5040 : {
5041 0 : if( p_struct!=NULL )
5042 : {
5043 0 : alglib_impl::_lincgstate_destroy(p_struct);
5044 0 : ae_free(p_struct);
5045 : }
5046 0 : }
5047 :
5048 0 : alglib_impl::lincgstate* _lincgstate_owner::c_ptr()
5049 : {
5050 0 : return p_struct;
5051 : }
5052 :
5053 0 : alglib_impl::lincgstate* _lincgstate_owner::c_ptr() const
5054 : {
5055 0 : return const_cast<alglib_impl::lincgstate*>(p_struct);
5056 : }
5057 0 : lincgstate::lincgstate() : _lincgstate_owner()
5058 : {
5059 0 : }
5060 :
5061 0 : lincgstate::lincgstate(const lincgstate &rhs):_lincgstate_owner(rhs)
5062 : {
5063 0 : }
5064 :
5065 0 : lincgstate& lincgstate::operator=(const lincgstate &rhs)
5066 : {
5067 0 : if( this==&rhs )
5068 0 : return *this;
5069 0 : _lincgstate_owner::operator=(rhs);
5070 0 : return *this;
5071 : }
5072 :
5073 0 : lincgstate::~lincgstate()
5074 : {
5075 0 : }
5076 :
5077 :
5078 : /*************************************************************************
5079 :
5080 : *************************************************************************/
5081 0 : _lincgreport_owner::_lincgreport_owner()
5082 : {
5083 : jmp_buf _break_jump;
5084 : alglib_impl::ae_state _state;
5085 :
5086 0 : alglib_impl::ae_state_init(&_state);
5087 0 : if( setjmp(_break_jump) )
5088 : {
5089 0 : if( p_struct!=NULL )
5090 : {
5091 0 : alglib_impl::_lincgreport_destroy(p_struct);
5092 0 : alglib_impl::ae_free(p_struct);
5093 : }
5094 0 : p_struct = NULL;
5095 : #if !defined(AE_NO_EXCEPTIONS)
5096 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
5097 : #else
5098 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
5099 : return;
5100 : #endif
5101 : }
5102 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
5103 0 : p_struct = NULL;
5104 0 : p_struct = (alglib_impl::lincgreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgreport), &_state);
5105 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
5106 0 : alglib_impl::_lincgreport_init(p_struct, &_state, ae_false);
5107 0 : ae_state_clear(&_state);
5108 0 : }
5109 :
5110 0 : _lincgreport_owner::_lincgreport_owner(const _lincgreport_owner &rhs)
5111 : {
5112 : jmp_buf _break_jump;
5113 : alglib_impl::ae_state _state;
5114 :
5115 0 : alglib_impl::ae_state_init(&_state);
5116 0 : if( setjmp(_break_jump) )
5117 : {
5118 0 : if( p_struct!=NULL )
5119 : {
5120 0 : alglib_impl::_lincgreport_destroy(p_struct);
5121 0 : alglib_impl::ae_free(p_struct);
5122 : }
5123 0 : p_struct = NULL;
5124 : #if !defined(AE_NO_EXCEPTIONS)
5125 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
5126 : #else
5127 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
5128 : return;
5129 : #endif
5130 : }
5131 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
5132 0 : p_struct = NULL;
5133 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgreport copy constructor failure (source is not initialized)", &_state);
5134 0 : p_struct = (alglib_impl::lincgreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgreport), &_state);
5135 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
5136 0 : alglib_impl::_lincgreport_init_copy(p_struct, const_cast<alglib_impl::lincgreport*>(rhs.p_struct), &_state, ae_false);
5137 0 : ae_state_clear(&_state);
5138 0 : }
5139 :
5140 0 : _lincgreport_owner& _lincgreport_owner::operator=(const _lincgreport_owner &rhs)
5141 : {
5142 0 : if( this==&rhs )
5143 0 : return *this;
5144 : jmp_buf _break_jump;
5145 : alglib_impl::ae_state _state;
5146 :
5147 0 : alglib_impl::ae_state_init(&_state);
5148 0 : if( setjmp(_break_jump) )
5149 : {
5150 : #if !defined(AE_NO_EXCEPTIONS)
5151 0 : _ALGLIB_CPP_EXCEPTION(_state.error_msg);
5152 : #else
5153 : _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
5154 : return *this;
5155 : #endif
5156 : }
5157 0 : alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
5158 0 : alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: lincgreport assignment constructor failure (destination is not initialized)", &_state);
5159 0 : alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgreport assignment constructor failure (source is not initialized)", &_state);
5160 0 : alglib_impl::_lincgreport_destroy(p_struct);
5161 0 : memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
5162 0 : alglib_impl::_lincgreport_init_copy(p_struct, const_cast<alglib_impl::lincgreport*>(rhs.p_struct), &_state, ae_false);
5163 0 : ae_state_clear(&_state);
5164 0 : return *this;
5165 : }
5166 :
5167 0 : _lincgreport_owner::~_lincgreport_owner()
5168 : {
5169 0 : if( p_struct!=NULL )
5170 : {
5171 0 : alglib_impl::_lincgreport_destroy(p_struct);
5172 0 : ae_free(p_struct);
5173 : }
5174 0 : }
5175 :
5176 0 : alglib_impl::lincgreport* _lincgreport_owner::c_ptr()
5177 : {
5178 0 : return p_struct;
5179 : }
5180 :
5181 0 : alglib_impl::lincgreport* _lincgreport_owner::c_ptr() const
5182 : {
5183 0 : return const_cast<alglib_impl::lincgreport*>(p_struct);
5184 : }
5185 0 : lincgreport::lincgreport() : _lincgreport_owner() ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype),r2(p_struct->r2)
5186 : {
5187 0 : }
5188 :
5189 0 : lincgreport::lincgreport(const lincgreport &rhs):_lincgreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype),r2(p_struct->r2)
5190 : {
5191 0 : }
5192 :
5193 0 : lincgreport& lincgreport::operator=(const lincgreport &rhs)
5194 : {
5195 0 : if( this==&rhs )
5196 0 : return *this;
5197 0 : _lincgreport_owner::operator=(rhs);
5198 0 : return *this;
5199 : }
5200 :
5201 0 : lincgreport::~lincgreport()
5202 : {
5203 0 : }
5204 :
5205 : /*************************************************************************
5206 : This function initializes linear CG Solver. This solver is used to solve
5207 : symmetric positive definite problems. If you want to solve nonsymmetric
5208 : (or non-positive definite) problem you may use LinLSQR solver provided by
5209 : ALGLIB.
5210 :
5211 : USAGE:
5212 : 1. User initializes algorithm state with LinCGCreate() call
5213 : 2. User tunes solver parameters with LinCGSetCond() and other functions
5214 : 3. Optionally, user sets starting point with LinCGSetStartingPoint()
5215 : 4. User calls LinCGSolveSparse() function which takes algorithm state and
5216 : SparseMatrix object.
5217 : 5. User calls LinCGResults() to get solution
5218 : 6. Optionally, user may call LinCGSolveSparse() again to solve another
5219 : problem with different matrix and/or right part without reinitializing
5220 : LinCGState structure.
5221 :
5222 : INPUT PARAMETERS:
5223 : N - problem dimension, N>0
5224 :
5225 : OUTPUT PARAMETERS:
5226 : State - structure which stores algorithm state
5227 :
5228 : -- ALGLIB --
5229 : Copyright 14.11.2011 by Bochkanov Sergey
5230 : *************************************************************************/
5231 0 : void lincgcreate(const ae_int_t n, lincgstate &state, const xparams _xparams)
5232 : {
5233 : jmp_buf _break_jump;
5234 : alglib_impl::ae_state _alglib_env_state;
5235 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5236 0 : if( setjmp(_break_jump) )
5237 : {
5238 : #if !defined(AE_NO_EXCEPTIONS)
5239 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5240 : #else
5241 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5242 : return;
5243 : #endif
5244 : }
5245 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5246 0 : if( _xparams.flags!=0x0 )
5247 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5248 0 : alglib_impl::lincgcreate(n, const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
5249 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5250 0 : return;
5251 : }
5252 :
5253 : /*************************************************************************
5254 : This function sets starting point.
5255 : By default, zero starting point is used.
5256 :
5257 : INPUT PARAMETERS:
5258 : X - starting point, array[N]
5259 :
5260 : OUTPUT PARAMETERS:
5261 : State - structure which stores algorithm state
5262 :
5263 : -- ALGLIB --
5264 : Copyright 14.11.2011 by Bochkanov Sergey
5265 : *************************************************************************/
5266 0 : void lincgsetstartingpoint(const lincgstate &state, const real_1d_array &x, const xparams _xparams)
5267 : {
5268 : jmp_buf _break_jump;
5269 : alglib_impl::ae_state _alglib_env_state;
5270 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5271 0 : if( setjmp(_break_jump) )
5272 : {
5273 : #if !defined(AE_NO_EXCEPTIONS)
5274 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5275 : #else
5276 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5277 : return;
5278 : #endif
5279 : }
5280 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5281 0 : if( _xparams.flags!=0x0 )
5282 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5283 0 : alglib_impl::lincgsetstartingpoint(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
5284 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5285 0 : return;
5286 : }
5287 :
5288 : /*************************************************************************
5289 : This function changes preconditioning settings of LinCGSolveSparse()
5290 : function. By default, SolveSparse() uses diagonal preconditioner, but if
5291 : you want to use solver without preconditioning, you can call this function
5292 : which forces solver to use unit matrix for preconditioning.
5293 :
5294 : INPUT PARAMETERS:
5295 : State - structure which stores algorithm state
5296 :
5297 : -- ALGLIB --
5298 : Copyright 19.11.2012 by Bochkanov Sergey
5299 : *************************************************************************/
5300 0 : void lincgsetprecunit(const lincgstate &state, const xparams _xparams)
5301 : {
5302 : jmp_buf _break_jump;
5303 : alglib_impl::ae_state _alglib_env_state;
5304 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5305 0 : if( setjmp(_break_jump) )
5306 : {
5307 : #if !defined(AE_NO_EXCEPTIONS)
5308 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5309 : #else
5310 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5311 : return;
5312 : #endif
5313 : }
5314 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5315 0 : if( _xparams.flags!=0x0 )
5316 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5317 0 : alglib_impl::lincgsetprecunit(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
5318 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5319 0 : return;
5320 : }
5321 :
5322 : /*************************************************************************
5323 : This function changes preconditioning settings of LinCGSolveSparse()
5324 : function. LinCGSolveSparse() will use diagonal of the system matrix as
5325 : preconditioner. This preconditioning mode is active by default.
5326 :
5327 : INPUT PARAMETERS:
5328 : State - structure which stores algorithm state
5329 :
5330 : -- ALGLIB --
5331 : Copyright 19.11.2012 by Bochkanov Sergey
5332 : *************************************************************************/
5333 0 : void lincgsetprecdiag(const lincgstate &state, const xparams _xparams)
5334 : {
5335 : jmp_buf _break_jump;
5336 : alglib_impl::ae_state _alglib_env_state;
5337 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5338 0 : if( setjmp(_break_jump) )
5339 : {
5340 : #if !defined(AE_NO_EXCEPTIONS)
5341 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5342 : #else
5343 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5344 : return;
5345 : #endif
5346 : }
5347 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5348 0 : if( _xparams.flags!=0x0 )
5349 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5350 0 : alglib_impl::lincgsetprecdiag(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
5351 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5352 0 : return;
5353 : }
5354 :
5355 : /*************************************************************************
5356 : This function sets stopping criteria.
5357 :
5358 : INPUT PARAMETERS:
5359 : EpsF - algorithm will be stopped if norm of residual is less than
5360 : EpsF*||b||.
5361 : MaxIts - algorithm will be stopped if number of iterations is more
5362 : than MaxIts.
5363 :
5364 : OUTPUT PARAMETERS:
5365 : State - structure which stores algorithm state
5366 :
5367 : NOTES:
5368 : If both EpsF and MaxIts are zero then small EpsF will be set to small
5369 : value.
5370 :
5371 : -- ALGLIB --
5372 : Copyright 14.11.2011 by Bochkanov Sergey
5373 : *************************************************************************/
5374 0 : void lincgsetcond(const lincgstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams)
5375 : {
5376 : jmp_buf _break_jump;
5377 : alglib_impl::ae_state _alglib_env_state;
5378 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5379 0 : if( setjmp(_break_jump) )
5380 : {
5381 : #if !defined(AE_NO_EXCEPTIONS)
5382 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5383 : #else
5384 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5385 : return;
5386 : #endif
5387 : }
5388 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5389 0 : if( _xparams.flags!=0x0 )
5390 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5391 0 : alglib_impl::lincgsetcond(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), epsf, maxits, &_alglib_env_state);
5392 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5393 0 : return;
5394 : }
5395 :
5396 : /*************************************************************************
5397 : Procedure for solution of A*x=b with sparse A.
5398 :
5399 : INPUT PARAMETERS:
5400 : State - algorithm state
5401 : A - sparse matrix in the CRS format (you MUST contvert it to
5402 : CRS format by calling SparseConvertToCRS() function).
5403 : IsUpper - whether upper or lower triangle of A is used:
5404 : * IsUpper=True => only upper triangle is used and lower
5405 : triangle is not referenced at all
5406 : * IsUpper=False => only lower triangle is used and upper
5407 : triangle is not referenced at all
5408 : B - right part, array[N]
5409 :
5410 : RESULT:
5411 : This function returns no result.
5412 : You can get solution by calling LinCGResults()
5413 :
5414 : NOTE: this function uses lightweight preconditioning - multiplication by
5415 : inverse of diag(A). If you want, you can turn preconditioning off by
5416 : calling LinCGSetPrecUnit(). However, preconditioning cost is low and
5417 : preconditioner is very important for solution of badly scaled
5418 : problems.
5419 :
5420 : -- ALGLIB --
5421 : Copyright 14.11.2011 by Bochkanov Sergey
5422 : *************************************************************************/
5423 0 : void lincgsolvesparse(const lincgstate &state, const sparsematrix &a, const bool isupper, const real_1d_array &b, const xparams _xparams)
5424 : {
5425 : jmp_buf _break_jump;
5426 : alglib_impl::ae_state _alglib_env_state;
5427 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5428 0 : if( setjmp(_break_jump) )
5429 : {
5430 : #if !defined(AE_NO_EXCEPTIONS)
5431 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5432 : #else
5433 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5434 : return;
5435 : #endif
5436 : }
5437 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5438 0 : if( _xparams.flags!=0x0 )
5439 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5440 0 : alglib_impl::lincgsolvesparse(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &_alglib_env_state);
5441 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5442 0 : return;
5443 : }
5444 :
5445 : /*************************************************************************
5446 : CG-solver: results.
5447 :
5448 : This function must be called after LinCGSolve
5449 :
5450 : INPUT PARAMETERS:
5451 : State - algorithm state
5452 :
5453 : OUTPUT PARAMETERS:
5454 : X - array[N], solution
5455 : Rep - optimization report:
5456 : * Rep.TerminationType completetion code:
5457 : * -5 input matrix is either not positive definite,
5458 : too large or too small
5459 : * -4 overflow/underflow during solution
5460 : (ill conditioned problem)
5461 : * 1 ||residual||<=EpsF*||b||
5462 : * 5 MaxIts steps was taken
5463 : * 7 rounding errors prevent further progress,
5464 : best point found is returned
5465 : * Rep.IterationsCount contains iterations count
5466 : * NMV countains number of matrix-vector calculations
5467 :
5468 : -- ALGLIB --
5469 : Copyright 14.11.2011 by Bochkanov Sergey
5470 : *************************************************************************/
5471 0 : void lincgresults(const lincgstate &state, real_1d_array &x, lincgreport &rep, const xparams _xparams)
5472 : {
5473 : jmp_buf _break_jump;
5474 : alglib_impl::ae_state _alglib_env_state;
5475 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5476 0 : if( setjmp(_break_jump) )
5477 : {
5478 : #if !defined(AE_NO_EXCEPTIONS)
5479 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5480 : #else
5481 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5482 : return;
5483 : #endif
5484 : }
5485 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5486 0 : if( _xparams.flags!=0x0 )
5487 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5488 0 : alglib_impl::lincgresults(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::lincgreport*>(rep.c_ptr()), &_alglib_env_state);
5489 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5490 0 : return;
5491 : }
5492 :
5493 : /*************************************************************************
5494 : This function sets restart frequency. By default, algorithm is restarted
5495 : after N subsequent iterations.
5496 :
5497 : -- ALGLIB --
5498 : Copyright 14.11.2011 by Bochkanov Sergey
5499 : *************************************************************************/
5500 0 : void lincgsetrestartfreq(const lincgstate &state, const ae_int_t srf, const xparams _xparams)
5501 : {
5502 : jmp_buf _break_jump;
5503 : alglib_impl::ae_state _alglib_env_state;
5504 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5505 0 : if( setjmp(_break_jump) )
5506 : {
5507 : #if !defined(AE_NO_EXCEPTIONS)
5508 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5509 : #else
5510 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5511 : return;
5512 : #endif
5513 : }
5514 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5515 0 : if( _xparams.flags!=0x0 )
5516 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5517 0 : alglib_impl::lincgsetrestartfreq(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), srf, &_alglib_env_state);
5518 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5519 0 : return;
5520 : }
5521 :
5522 : /*************************************************************************
5523 : This function sets frequency of residual recalculations.
5524 :
5525 : Algorithm updates residual r_k using iterative formula, but recalculates
5526 : it from scratch after each 10 iterations. It is done to avoid accumulation
5527 : of numerical errors and to stop algorithm when r_k starts to grow.
5528 :
5529 : Such low update frequence (1/10) gives very little overhead, but makes
5530 : algorithm a bit more robust against numerical errors. However, you may
5531 : change it
5532 :
5533 : INPUT PARAMETERS:
5534 : Freq - desired update frequency, Freq>=0.
5535 : Zero value means that no updates will be done.
5536 :
5537 : -- ALGLIB --
5538 : Copyright 14.11.2011 by Bochkanov Sergey
5539 : *************************************************************************/
5540 0 : void lincgsetrupdatefreq(const lincgstate &state, const ae_int_t freq, const xparams _xparams)
5541 : {
5542 : jmp_buf _break_jump;
5543 : alglib_impl::ae_state _alglib_env_state;
5544 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5545 0 : if( setjmp(_break_jump) )
5546 : {
5547 : #if !defined(AE_NO_EXCEPTIONS)
5548 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5549 : #else
5550 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5551 : return;
5552 : #endif
5553 : }
5554 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5555 0 : if( _xparams.flags!=0x0 )
5556 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5557 0 : alglib_impl::lincgsetrupdatefreq(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), freq, &_alglib_env_state);
5558 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5559 0 : return;
5560 : }
5561 :
5562 : /*************************************************************************
5563 : This function turns on/off reporting.
5564 :
5565 : INPUT PARAMETERS:
5566 : State - structure which stores algorithm state
5567 : NeedXRep- whether iteration reports are needed or not
5568 :
5569 : If NeedXRep is True, algorithm will call rep() callback function if it is
5570 : provided to MinCGOptimize().
5571 :
5572 : -- ALGLIB --
5573 : Copyright 14.11.2011 by Bochkanov Sergey
5574 : *************************************************************************/
5575 0 : void lincgsetxrep(const lincgstate &state, const bool needxrep, const xparams _xparams)
5576 : {
5577 : jmp_buf _break_jump;
5578 : alglib_impl::ae_state _alglib_env_state;
5579 0 : alglib_impl::ae_state_init(&_alglib_env_state);
5580 0 : if( setjmp(_break_jump) )
5581 : {
5582 : #if !defined(AE_NO_EXCEPTIONS)
5583 0 : _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
5584 : #else
5585 : _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
5586 : return;
5587 : #endif
5588 : }
5589 0 : ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
5590 0 : if( _xparams.flags!=0x0 )
5591 0 : ae_state_set_flags(&_alglib_env_state, _xparams.flags);
5592 0 : alglib_impl::lincgsetxrep(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
5593 0 : alglib_impl::ae_state_clear(&_alglib_env_state);
5594 0 : return;
5595 : }
5596 : #endif
5597 : }
5598 :
5599 : /////////////////////////////////////////////////////////////////////////
5600 : //
5601 : // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE
5602 : //
5603 : /////////////////////////////////////////////////////////////////////////
5604 : namespace alglib_impl
5605 : {
5606 : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
5607 : static void directdensesolvers_rmatrixlusolveinternal(/* Real */ ae_matrix* lua,
5608 : /* Integer */ ae_vector* p,
5609 : ae_int_t n,
5610 : /* Real */ ae_matrix* a,
5611 : ae_bool havea,
5612 : /* Real */ ae_matrix* b,
5613 : ae_int_t m,
5614 : ae_int_t* info,
5615 : densesolverreport* rep,
5616 : /* Real */ ae_matrix* x,
5617 : ae_state *_state);
5618 : static void directdensesolvers_spdmatrixcholeskysolveinternal(/* Real */ ae_matrix* cha,
5619 : ae_int_t n,
5620 : ae_bool isupper,
5621 : /* Real */ ae_matrix* a,
5622 : ae_bool havea,
5623 : /* Real */ ae_matrix* b,
5624 : ae_int_t m,
5625 : ae_int_t* info,
5626 : densesolverreport* rep,
5627 : /* Real */ ae_matrix* x,
5628 : ae_state *_state);
5629 : static void directdensesolvers_cmatrixlusolveinternal(/* Complex */ ae_matrix* lua,
5630 : /* Integer */ ae_vector* p,
5631 : ae_int_t n,
5632 : /* Complex */ ae_matrix* a,
5633 : ae_bool havea,
5634 : /* Complex */ ae_matrix* b,
5635 : ae_int_t m,
5636 : ae_int_t* info,
5637 : densesolverreport* rep,
5638 : /* Complex */ ae_matrix* x,
5639 : ae_state *_state);
5640 : static void directdensesolvers_hpdmatrixcholeskysolveinternal(/* Complex */ ae_matrix* cha,
5641 : ae_int_t n,
5642 : ae_bool isupper,
5643 : /* Complex */ ae_matrix* a,
5644 : ae_bool havea,
5645 : /* Complex */ ae_matrix* b,
5646 : ae_int_t m,
5647 : ae_int_t* info,
5648 : densesolverreport* rep,
5649 : /* Complex */ ae_matrix* x,
5650 : ae_state *_state);
5651 : static ae_int_t directdensesolvers_densesolverrfsmax(ae_int_t n,
5652 : double r1,
5653 : double rinf,
5654 : ae_state *_state);
5655 : static ae_int_t directdensesolvers_densesolverrfsmaxv2(ae_int_t n,
5656 : double r2,
5657 : ae_state *_state);
5658 : static void directdensesolvers_rbasiclusolve(/* Real */ ae_matrix* lua,
5659 : /* Integer */ ae_vector* p,
5660 : ae_int_t n,
5661 : /* Real */ ae_vector* xb,
5662 : ae_state *_state);
5663 : static void directdensesolvers_spdbasiccholeskysolve(/* Real */ ae_matrix* cha,
5664 : ae_int_t n,
5665 : ae_bool isupper,
5666 : /* Real */ ae_vector* xb,
5667 : ae_state *_state);
5668 : static void directdensesolvers_cbasiclusolve(/* Complex */ ae_matrix* lua,
5669 : /* Integer */ ae_vector* p,
5670 : ae_int_t n,
5671 : /* Complex */ ae_vector* xb,
5672 : ae_state *_state);
5673 : static void directdensesolvers_hpdbasiccholeskysolve(/* Complex */ ae_matrix* cha,
5674 : ae_int_t n,
5675 : ae_bool isupper,
5676 : /* Complex */ ae_vector* xb,
5677 : ae_state *_state);
5678 :
5679 :
5680 : #endif
5681 : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
5682 : static double linlsqr_atol = 1.0E-6;
5683 : static double linlsqr_btol = 1.0E-6;
5684 : static void linlsqr_clearrfields(linlsqrstate* state, ae_state *_state);
5685 :
5686 :
5687 : #endif
5688 : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
5689 :
5690 :
5691 : #endif
5692 : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
5693 : static void nleq_clearrequestfields(nleqstate* state, ae_state *_state);
5694 : static ae_bool nleq_increaselambda(double* lambdav,
5695 : double* nu,
5696 : double lambdaup,
5697 : ae_state *_state);
5698 : static void nleq_decreaselambda(double* lambdav,
5699 : double* nu,
5700 : double lambdadown,
5701 : ae_state *_state);
5702 :
5703 :
5704 : #endif
5705 : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
5706 : static void directsparsesolvers_initreport(sparsesolverreport* rep,
5707 : ae_state *_state);
5708 :
5709 :
5710 : #endif
5711 : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
5712 : static double lincg_defaultprecision = 1.0E-6;
5713 : static void lincg_clearrfields(lincgstate* state, ae_state *_state);
5714 : static void lincg_updateitersdata(lincgstate* state, ae_state *_state);
5715 :
5716 :
5717 : #endif
5718 :
5719 : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
5720 :
5721 :
5722 : /*************************************************************************
5723 : Dense solver for A*x=b with N*N real matrix A and N*1 real vectorx x and
5724 : b. This is "slow-but-feature rich" version of the linear solver. Faster
5725 : version is RMatrixSolveFast() function.
5726 :
5727 : Algorithm features:
5728 : * automatic detection of degenerate cases
5729 : * condition number estimation
5730 : * iterative refinement
5731 : * O(N^3) complexity
5732 :
5733 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
5734 : ! by ALGLIB. It estimates condition number of linear system
5735 : ! and performs iterative refinement, which results in
5736 : ! significant performance penalty when compared with "fast"
5737 : ! version which just performs LU decomposition and calls
5738 : ! triangular solver.
5739 : !
5740 : ! This performance penalty is especially visible in the
5741 : ! multithreaded mode, because both condition number estimation
5742 : ! and iterative refinement are inherently sequential
5743 : ! calculations. It is also very significant on small matrices.
5744 : !
5745 : ! Thus, if you need high performance and if you are pretty sure
5746 : ! that your system is well conditioned, we strongly recommend
5747 : ! you to use faster solver, RMatrixSolveFast() function.
5748 :
5749 : ! COMMERCIAL EDITION OF ALGLIB:
5750 : !
5751 : ! Commercial Edition of ALGLIB includes following important improvements
5752 : ! of this function:
5753 : ! * high-performance native backend with same C# interface (C# version)
5754 : ! * multithreading support (C++ and C# versions)
5755 : ! * hardware vendor (Intel) implementations of linear algebra primitives
5756 : ! (C++ and C# versions, x86/x64 platform)
5757 : !
5758 : ! We recommend you to read 'Working with commercial version' section of
5759 : ! ALGLIB Reference Manual in order to find out how to use performance-
5760 : ! related features provided by commercial edition of ALGLIB.
5761 :
5762 : INPUT PARAMETERS
5763 : A - array[0..N-1,0..N-1], system matrix
5764 : N - size of A
5765 : B - array[0..N-1], right part
5766 :
5767 : OUTPUT PARAMETERS
5768 : Info - return code:
5769 : * -3 matrix is very badly conditioned or exactly singular.
5770 : * -1 N<=0 was passed
5771 : * 1 task is solved (but matrix A may be ill-conditioned,
5772 : check R1/RInf parameters for condition numbers).
5773 : Rep - additional report, following fields are set:
5774 : * rep.r1 condition number in 1-norm
5775 : * rep.rinf condition number in inf-norm
5776 : X - array[N], it contains:
5777 : * info>0 => solution
5778 : * info=-3 => filled by zeros
5779 :
5780 : -- ALGLIB --
5781 : Copyright 27.01.2010 by Bochkanov Sergey
5782 : *************************************************************************/
5783 0 : void rmatrixsolve(/* Real */ ae_matrix* a,
5784 : ae_int_t n,
5785 : /* Real */ ae_vector* b,
5786 : ae_int_t* info,
5787 : densesolverreport* rep,
5788 : /* Real */ ae_vector* x,
5789 : ae_state *_state)
5790 : {
5791 : ae_frame _frame_block;
5792 : ae_matrix bm;
5793 : ae_matrix xm;
5794 :
5795 0 : ae_frame_make(_state, &_frame_block);
5796 0 : memset(&bm, 0, sizeof(bm));
5797 0 : memset(&xm, 0, sizeof(xm));
5798 0 : *info = 0;
5799 0 : _densesolverreport_clear(rep);
5800 0 : ae_vector_clear(x);
5801 0 : ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
5802 0 : ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
5803 :
5804 0 : if( n<=0 )
5805 : {
5806 0 : *info = -1;
5807 0 : ae_frame_leave(_state);
5808 0 : return;
5809 : }
5810 0 : ae_matrix_set_length(&bm, n, 1, _state);
5811 0 : ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
5812 0 : rmatrixsolvem(a, n, &bm, 1, ae_true, info, rep, &xm, _state);
5813 0 : ae_vector_set_length(x, n, _state);
5814 0 : ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
5815 0 : ae_frame_leave(_state);
5816 : }
5817 :
5818 :
5819 : /*************************************************************************
5820 : Dense solver.
5821 :
5822 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
5823 : real matrix, x and b are vectors. This is a "fast" version of linear
5824 : solver which does NOT provide any additional functions like condition
5825 : number estimation or iterative refinement.
5826 :
5827 : Algorithm features:
5828 : * efficient algorithm O(N^3) complexity
5829 : * no performance overhead from additional functionality
5830 :
5831 : If you need condition number estimation or iterative refinement, use more
5832 : feature-rich version - RMatrixSolve().
5833 :
5834 : ! COMMERCIAL EDITION OF ALGLIB:
5835 : !
5836 : ! Commercial Edition of ALGLIB includes following important improvements
5837 : ! of this function:
5838 : ! * high-performance native backend with same C# interface (C# version)
5839 : ! * multithreading support (C++ and C# versions)
5840 : ! * hardware vendor (Intel) implementations of linear algebra primitives
5841 : ! (C++ and C# versions, x86/x64 platform)
5842 : !
5843 : ! We recommend you to read 'Working with commercial version' section of
5844 : ! ALGLIB Reference Manual in order to find out how to use performance-
5845 : ! related features provided by commercial edition of ALGLIB.
5846 :
5847 : INPUT PARAMETERS
5848 : A - array[0..N-1,0..N-1], system matrix
5849 : N - size of A
5850 : B - array[0..N-1], right part
5851 :
5852 : OUTPUT PARAMETERS
5853 : Info - return code:
5854 : * -3 matrix is exactly singular (ill conditioned matrices
5855 : are not recognized).
5856 : * -1 N<=0 was passed
5857 : * 1 task is solved
5858 : B - array[N]:
5859 : * info>0 => overwritten by solution
5860 : * info=-3 => filled by zeros
5861 :
5862 : -- ALGLIB --
5863 : Copyright 16.03.2015 by Bochkanov Sergey
5864 : *************************************************************************/
5865 0 : void rmatrixsolvefast(/* Real */ ae_matrix* a,
5866 : ae_int_t n,
5867 : /* Real */ ae_vector* b,
5868 : ae_int_t* info,
5869 : ae_state *_state)
5870 : {
5871 : ae_frame _frame_block;
5872 : ae_matrix _a;
5873 : ae_int_t i;
5874 : ae_int_t j;
5875 : ae_vector p;
5876 :
5877 0 : ae_frame_make(_state, &_frame_block);
5878 0 : memset(&_a, 0, sizeof(_a));
5879 0 : memset(&p, 0, sizeof(p));
5880 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
5881 0 : a = &_a;
5882 0 : *info = 0;
5883 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
5884 :
5885 0 : if( n<=0 )
5886 : {
5887 0 : *info = -1;
5888 0 : ae_frame_leave(_state);
5889 0 : return;
5890 : }
5891 0 : rmatrixlu(a, n, n, &p, _state);
5892 0 : for(i=0; i<=n-1; i++)
5893 : {
5894 0 : if( ae_fp_eq(a->ptr.pp_double[i][i],(double)(0)) )
5895 : {
5896 0 : for(j=0; j<=n-1; j++)
5897 : {
5898 0 : b->ptr.p_double[j] = 0.0;
5899 : }
5900 0 : *info = -3;
5901 0 : ae_frame_leave(_state);
5902 0 : return;
5903 : }
5904 : }
5905 0 : directdensesolvers_rbasiclusolve(a, &p, n, b, _state);
5906 0 : *info = 1;
5907 0 : ae_frame_leave(_state);
5908 : }
5909 :
5910 :
5911 : /*************************************************************************
5912 : Dense solver.
5913 :
5914 : Similar to RMatrixSolve() but solves task with multiple right parts (where
5915 : b and x are NxM matrices). This is "slow-but-robust" version of linear
5916 : solver with additional functionality like condition number estimation.
5917 : There also exists faster version - RMatrixSolveMFast().
5918 :
5919 : Algorithm features:
5920 : * automatic detection of degenerate cases
5921 : * condition number estimation
5922 : * optional iterative refinement
5923 : * O(N^3+M*N^2) complexity
5924 :
5925 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
5926 : ! by ALGLIB. It estimates condition number of linear system
5927 : ! and performs iterative refinement, which results in
5928 : ! significant performance penalty when compared with "fast"
5929 : ! version which just performs LU decomposition and calls
5930 : ! triangular solver.
5931 : !
5932 : ! This performance penalty is especially visible in the
5933 : ! multithreaded mode, because both condition number estimation
5934 : ! and iterative refinement are inherently sequential
5935 : ! calculations. It also very significant on small matrices.
5936 : !
5937 : ! Thus, if you need high performance and if you are pretty sure
5938 : ! that your system is well conditioned, we strongly recommend
5939 : ! you to use faster solver, RMatrixSolveMFast() function.
5940 :
5941 : ! COMMERCIAL EDITION OF ALGLIB:
5942 : !
5943 : ! Commercial Edition of ALGLIB includes following important improvements
5944 : ! of this function:
5945 : ! * high-performance native backend with same C# interface (C# version)
5946 : ! * multithreading support (C++ and C# versions)
5947 : ! * hardware vendor (Intel) implementations of linear algebra primitives
5948 : ! (C++ and C# versions, x86/x64 platform)
5949 : !
5950 : ! We recommend you to read 'Working with commercial version' section of
5951 : ! ALGLIB Reference Manual in order to find out how to use performance-
5952 : ! related features provided by commercial edition of ALGLIB.
5953 :
5954 : INPUT PARAMETERS
5955 : A - array[0..N-1,0..N-1], system matrix
5956 : N - size of A
5957 : B - array[0..N-1,0..M-1], right part
5958 : M - right part size
5959 : RFS - iterative refinement switch:
5960 : * True - refinement is used.
5961 : Less performance, more precision.
5962 : * False - refinement is not used.
5963 : More performance, less precision.
5964 :
5965 : OUTPUT PARAMETERS
5966 : Info - return code:
5967 : * -3 A is ill conditioned or singular.
5968 : X is filled by zeros in such cases.
5969 : * -1 N<=0 was passed
5970 : * 1 task is solved (but matrix A may be ill-conditioned,
5971 : check R1/RInf parameters for condition numbers).
5972 : Rep - additional report, following fields are set:
5973 : * rep.r1 condition number in 1-norm
5974 : * rep.rinf condition number in inf-norm
5975 : X - array[N], it contains:
5976 : * info>0 => solution
5977 : * info=-3 => filled by zeros
5978 :
5979 :
5980 : -- ALGLIB --
5981 : Copyright 27.01.2010 by Bochkanov Sergey
5982 : *************************************************************************/
5983 0 : void rmatrixsolvem(/* Real */ ae_matrix* a,
5984 : ae_int_t n,
5985 : /* Real */ ae_matrix* b,
5986 : ae_int_t m,
5987 : ae_bool rfs,
5988 : ae_int_t* info,
5989 : densesolverreport* rep,
5990 : /* Real */ ae_matrix* x,
5991 : ae_state *_state)
5992 : {
5993 : ae_frame _frame_block;
5994 : ae_matrix da;
5995 : ae_matrix emptya;
5996 : ae_vector p;
5997 : ae_int_t i;
5998 :
5999 0 : ae_frame_make(_state, &_frame_block);
6000 0 : memset(&da, 0, sizeof(da));
6001 0 : memset(&emptya, 0, sizeof(emptya));
6002 0 : memset(&p, 0, sizeof(p));
6003 0 : *info = 0;
6004 0 : _densesolverreport_clear(rep);
6005 0 : ae_matrix_clear(x);
6006 0 : ae_matrix_init(&da, 0, 0, DT_REAL, _state, ae_true);
6007 0 : ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
6008 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
6009 :
6010 :
6011 : /*
6012 : * prepare: check inputs, allocate space...
6013 : */
6014 0 : if( n<=0||m<=0 )
6015 : {
6016 0 : *info = -1;
6017 0 : ae_frame_leave(_state);
6018 0 : return;
6019 : }
6020 0 : ae_matrix_set_length(&da, n, n, _state);
6021 :
6022 : /*
6023 : * 1. factorize matrix
6024 : * 3. solve
6025 : */
6026 0 : for(i=0; i<=n-1; i++)
6027 : {
6028 0 : ae_v_move(&da.ptr.pp_double[i][0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,n-1));
6029 : }
6030 0 : rmatrixlu(&da, n, n, &p, _state);
6031 0 : if( rfs )
6032 : {
6033 0 : directdensesolvers_rmatrixlusolveinternal(&da, &p, n, a, ae_true, b, m, info, rep, x, _state);
6034 : }
6035 : else
6036 : {
6037 0 : directdensesolvers_rmatrixlusolveinternal(&da, &p, n, &emptya, ae_false, b, m, info, rep, x, _state);
6038 : }
6039 0 : ae_frame_leave(_state);
6040 : }
6041 :
6042 :
6043 : /*************************************************************************
6044 : Dense solver.
6045 :
6046 : Similar to RMatrixSolve() but solves task with multiple right parts (where
6047 : b and x are NxM matrices). This is "fast" version of linear solver which
6048 : does NOT offer additional functions like condition number estimation or
6049 : iterative refinement.
6050 :
6051 : Algorithm features:
6052 : * O(N^3+M*N^2) complexity
6053 : * no additional functionality, highest performance
6054 :
6055 : ! COMMERCIAL EDITION OF ALGLIB:
6056 : !
6057 : ! Commercial Edition of ALGLIB includes following important improvements
6058 : ! of this function:
6059 : ! * high-performance native backend with same C# interface (C# version)
6060 : ! * multithreading support (C++ and C# versions)
6061 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6062 : ! (C++ and C# versions, x86/x64 platform)
6063 : !
6064 : ! We recommend you to read 'Working with commercial version' section of
6065 : ! ALGLIB Reference Manual in order to find out how to use performance-
6066 : ! related features provided by commercial edition of ALGLIB.
6067 :
6068 : INPUT PARAMETERS
6069 : A - array[0..N-1,0..N-1], system matrix
6070 : N - size of A
6071 : B - array[0..N-1,0..M-1], right part
6072 : M - right part size
6073 : RFS - iterative refinement switch:
6074 : * True - refinement is used.
6075 : Less performance, more precision.
6076 : * False - refinement is not used.
6077 : More performance, less precision.
6078 :
6079 : OUTPUT PARAMETERS
6080 : Info - return code:
6081 : * -3 matrix is exactly singular (ill conditioned matrices
6082 : are not recognized).
6083 : X is filled by zeros in such cases.
6084 : * -1 N<=0 was passed
6085 : * 1 task is solved
6086 : Rep - additional report, following fields are set:
6087 : * rep.r1 condition number in 1-norm
6088 : * rep.rinf condition number in inf-norm
6089 : B - array[N]:
6090 : * info>0 => overwritten by solution
6091 : * info=-3 => filled by zeros
6092 :
6093 :
6094 : -- ALGLIB --
6095 : Copyright 27.01.2010 by Bochkanov Sergey
6096 : *************************************************************************/
6097 0 : void rmatrixsolvemfast(/* Real */ ae_matrix* a,
6098 : ae_int_t n,
6099 : /* Real */ ae_matrix* b,
6100 : ae_int_t m,
6101 : ae_int_t* info,
6102 : ae_state *_state)
6103 : {
6104 : ae_frame _frame_block;
6105 : ae_matrix _a;
6106 : double v;
6107 : ae_int_t i;
6108 : ae_int_t j;
6109 : ae_int_t k;
6110 : ae_vector p;
6111 :
6112 0 : ae_frame_make(_state, &_frame_block);
6113 0 : memset(&_a, 0, sizeof(_a));
6114 0 : memset(&p, 0, sizeof(p));
6115 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
6116 0 : a = &_a;
6117 0 : *info = 0;
6118 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
6119 :
6120 :
6121 : /*
6122 : * Check for exact degeneracy
6123 : */
6124 0 : if( n<=0||m<=0 )
6125 : {
6126 0 : *info = -1;
6127 0 : ae_frame_leave(_state);
6128 0 : return;
6129 : }
6130 0 : rmatrixlu(a, n, n, &p, _state);
6131 0 : for(i=0; i<=n-1; i++)
6132 : {
6133 0 : if( ae_fp_eq(a->ptr.pp_double[i][i],(double)(0)) )
6134 : {
6135 0 : for(j=0; j<=n-1; j++)
6136 : {
6137 0 : for(k=0; k<=m-1; k++)
6138 : {
6139 0 : b->ptr.pp_double[j][k] = 0.0;
6140 : }
6141 : }
6142 0 : *info = -3;
6143 0 : ae_frame_leave(_state);
6144 0 : return;
6145 : }
6146 : }
6147 :
6148 : /*
6149 : * Solve with TRSM()
6150 : */
6151 0 : for(i=0; i<=n-1; i++)
6152 : {
6153 0 : if( p.ptr.p_int[i]!=i )
6154 : {
6155 0 : for(j=0; j<=m-1; j++)
6156 : {
6157 0 : v = b->ptr.pp_double[i][j];
6158 0 : b->ptr.pp_double[i][j] = b->ptr.pp_double[p.ptr.p_int[i]][j];
6159 0 : b->ptr.pp_double[p.ptr.p_int[i]][j] = v;
6160 : }
6161 : }
6162 : }
6163 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
6164 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
6165 0 : *info = 1;
6166 0 : ae_frame_leave(_state);
6167 : }
6168 :
6169 :
6170 : /*************************************************************************
6171 : Dense solver.
6172 :
6173 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
6174 : real matrix given by its LU decomposition, x and b are real vectors. This
6175 : is "slow-but-robust" version of the linear LU-based solver. Faster version
6176 : is RMatrixLUSolveFast() function.
6177 :
6178 : Algorithm features:
6179 : * automatic detection of degenerate cases
6180 : * O(N^2) complexity
6181 : * condition number estimation
6182 :
6183 : No iterative refinement is provided because exact form of original matrix
6184 : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you
6185 : need iterative refinement.
6186 :
6187 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
6188 : ! by ALGLIB. It estimates condition number of linear system,
6189 : ! which results in 10-15x performance penalty when compared
6190 : ! with "fast" version which just calls triangular solver.
6191 : !
6192 : ! This performance penalty is insignificant when compared with
6193 : ! cost of large LU decomposition. However, if you call this
6194 : ! function many times for the same left side, this overhead
6195 : ! BECOMES significant. It also becomes significant for small-
6196 : ! scale problems.
6197 : !
6198 : ! In such cases we strongly recommend you to use faster solver,
6199 : ! RMatrixLUSolveFast() function.
6200 :
6201 : INPUT PARAMETERS
6202 : LUA - array[N,N], LU decomposition, RMatrixLU result
6203 : P - array[N], pivots array, RMatrixLU result
6204 : N - size of A
6205 : B - array[N], right part
6206 :
6207 : OUTPUT PARAMETERS
6208 : Info - return code:
6209 : * -3 matrix is very badly conditioned or exactly singular.
6210 : * -1 N<=0 was passed
6211 : * 1 task is solved (but matrix A may be ill-conditioned,
6212 : check R1/RInf parameters for condition numbers).
6213 : Rep - additional report, following fields are set:
6214 : * rep.r1 condition number in 1-norm
6215 : * rep.rinf condition number in inf-norm
6216 : X - array[N], it contains:
6217 : * info>0 => solution
6218 : * info=-3 => filled by zeros
6219 :
6220 :
6221 : -- ALGLIB --
6222 : Copyright 27.01.2010 by Bochkanov Sergey
6223 : *************************************************************************/
6224 0 : void rmatrixlusolve(/* Real */ ae_matrix* lua,
6225 : /* Integer */ ae_vector* p,
6226 : ae_int_t n,
6227 : /* Real */ ae_vector* b,
6228 : ae_int_t* info,
6229 : densesolverreport* rep,
6230 : /* Real */ ae_vector* x,
6231 : ae_state *_state)
6232 : {
6233 : ae_frame _frame_block;
6234 : ae_matrix bm;
6235 : ae_matrix xm;
6236 :
6237 0 : ae_frame_make(_state, &_frame_block);
6238 0 : memset(&bm, 0, sizeof(bm));
6239 0 : memset(&xm, 0, sizeof(xm));
6240 0 : *info = 0;
6241 0 : _densesolverreport_clear(rep);
6242 0 : ae_vector_clear(x);
6243 0 : ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
6244 0 : ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
6245 :
6246 0 : if( n<=0 )
6247 : {
6248 0 : *info = -1;
6249 0 : ae_frame_leave(_state);
6250 0 : return;
6251 : }
6252 0 : ae_matrix_set_length(&bm, n, 1, _state);
6253 0 : ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
6254 0 : rmatrixlusolvem(lua, p, n, &bm, 1, info, rep, &xm, _state);
6255 0 : ae_vector_set_length(x, n, _state);
6256 0 : ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
6257 0 : ae_frame_leave(_state);
6258 : }
6259 :
6260 :
6261 : /*************************************************************************
6262 : Dense solver.
6263 :
6264 : This subroutine solves a system A*x=b, where A is NxN non-denegerate
6265 : real matrix given by its LU decomposition, x and b are real vectors. This
6266 : is "fast-without-any-checks" version of the linear LU-based solver. Slower
6267 : but more robust version is RMatrixLUSolve() function.
6268 :
6269 : Algorithm features:
6270 : * O(N^2) complexity
6271 : * fast algorithm without ANY additional checks, just triangular solver
6272 :
6273 : INPUT PARAMETERS
6274 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
6275 : P - array[0..N-1], pivots array, RMatrixLU result
6276 : N - size of A
6277 : B - array[0..N-1], right part
6278 :
6279 : OUTPUT PARAMETERS
6280 : Info - return code:
6281 : * -3 matrix is exactly singular (ill conditioned matrices
6282 : are not recognized).
6283 : X is filled by zeros in such cases.
6284 : * -1 N<=0 was passed
6285 : * 1 task is solved
6286 : B - array[N]:
6287 : * info>0 => overwritten by solution
6288 : * info=-3 => filled by zeros
6289 :
6290 : -- ALGLIB --
6291 : Copyright 18.03.2015 by Bochkanov Sergey
6292 : *************************************************************************/
6293 0 : void rmatrixlusolvefast(/* Real */ ae_matrix* lua,
6294 : /* Integer */ ae_vector* p,
6295 : ae_int_t n,
6296 : /* Real */ ae_vector* b,
6297 : ae_int_t* info,
6298 : ae_state *_state)
6299 : {
6300 : ae_int_t i;
6301 : ae_int_t j;
6302 :
6303 0 : *info = 0;
6304 :
6305 0 : if( n<=0 )
6306 : {
6307 0 : *info = -1;
6308 0 : return;
6309 : }
6310 0 : for(i=0; i<=n-1; i++)
6311 : {
6312 0 : if( ae_fp_eq(lua->ptr.pp_double[i][i],(double)(0)) )
6313 : {
6314 0 : for(j=0; j<=n-1; j++)
6315 : {
6316 0 : b->ptr.p_double[j] = 0.0;
6317 : }
6318 0 : *info = -3;
6319 0 : return;
6320 : }
6321 : }
6322 0 : directdensesolvers_rbasiclusolve(lua, p, n, b, _state);
6323 0 : *info = 1;
6324 : }
6325 :
6326 :
6327 : /*************************************************************************
6328 : Dense solver.
6329 :
6330 : Similar to RMatrixLUSolve() but solves task with multiple right parts
6331 : (where b and x are NxM matrices). This is "robust-but-slow" version of
6332 : LU-based solver which performs additional checks for non-degeneracy of
6333 : inputs (condition number estimation). If you need best performance, use
6334 : "fast-without-any-checks" version, RMatrixLUSolveMFast().
6335 :
6336 : Algorithm features:
6337 : * automatic detection of degenerate cases
6338 : * O(M*N^2) complexity
6339 : * condition number estimation
6340 :
6341 : No iterative refinement is provided because exact form of original matrix
6342 : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve if you
6343 : need iterative refinement.
6344 :
6345 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
6346 : ! by ALGLIB. It estimates condition number of linear system,
6347 : ! which results in significant performance penalty when
6348 : ! compared with "fast" version which just calls triangular
6349 : ! solver.
6350 : !
6351 : ! This performance penalty is especially apparent when you use
6352 : ! ALGLIB parallel capabilities (condition number estimation is
6353 : ! inherently sequential). It also becomes significant for
6354 : ! small-scale problems.
6355 : !
6356 : ! In such cases we strongly recommend you to use faster solver,
6357 : ! RMatrixLUSolveMFast() function.
6358 :
6359 : ! COMMERCIAL EDITION OF ALGLIB:
6360 : !
6361 : ! Commercial Edition of ALGLIB includes following important improvements
6362 : ! of this function:
6363 : ! * high-performance native backend with same C# interface (C# version)
6364 : ! * multithreading support (C++ and C# versions)
6365 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6366 : ! (C++ and C# versions, x86/x64 platform)
6367 : !
6368 : ! We recommend you to read 'Working with commercial version' section of
6369 : ! ALGLIB Reference Manual in order to find out how to use performance-
6370 : ! related features provided by commercial edition of ALGLIB.
6371 :
6372 : INPUT PARAMETERS
6373 : LUA - array[N,N], LU decomposition, RMatrixLU result
6374 : P - array[N], pivots array, RMatrixLU result
6375 : N - size of A
6376 : B - array[0..N-1,0..M-1], right part
6377 : M - right part size
6378 :
6379 : OUTPUT PARAMETERS
6380 : Info - return code:
6381 : * -3 matrix is very badly conditioned or exactly singular.
6382 : X is filled by zeros in such cases.
6383 : * -1 N<=0 was passed
6384 : * 1 task is solved (but matrix A may be ill-conditioned,
6385 : check R1/RInf parameters for condition numbers).
6386 : Rep - additional report, following fields are set:
6387 : * rep.r1 condition number in 1-norm
6388 : * rep.rinf condition number in inf-norm
6389 : X - array[N,M], it contains:
6390 : * info>0 => solution
6391 : * info=-3 => filled by zeros
6392 :
6393 :
6394 : -- ALGLIB --
6395 : Copyright 27.01.2010 by Bochkanov Sergey
6396 : *************************************************************************/
6397 0 : void rmatrixlusolvem(/* Real */ ae_matrix* lua,
6398 : /* Integer */ ae_vector* p,
6399 : ae_int_t n,
6400 : /* Real */ ae_matrix* b,
6401 : ae_int_t m,
6402 : ae_int_t* info,
6403 : densesolverreport* rep,
6404 : /* Real */ ae_matrix* x,
6405 : ae_state *_state)
6406 : {
6407 : ae_frame _frame_block;
6408 : ae_matrix emptya;
6409 :
6410 0 : ae_frame_make(_state, &_frame_block);
6411 0 : memset(&emptya, 0, sizeof(emptya));
6412 0 : *info = 0;
6413 0 : _densesolverreport_clear(rep);
6414 0 : ae_matrix_clear(x);
6415 0 : ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
6416 :
6417 :
6418 : /*
6419 : * prepare: check inputs, allocate space...
6420 : */
6421 0 : if( n<=0||m<=0 )
6422 : {
6423 0 : *info = -1;
6424 0 : ae_frame_leave(_state);
6425 0 : return;
6426 : }
6427 :
6428 : /*
6429 : * solve
6430 : */
6431 0 : directdensesolvers_rmatrixlusolveinternal(lua, p, n, &emptya, ae_false, b, m, info, rep, x, _state);
6432 0 : ae_frame_leave(_state);
6433 : }
6434 :
6435 :
6436 : /*************************************************************************
6437 : Dense solver.
6438 :
6439 : Similar to RMatrixLUSolve() but solves task with multiple right parts,
6440 : where b and x are NxM matrices. This is "fast-without-any-checks" version
6441 : of LU-based solver. It does not estimate condition number of a system,
6442 : so it is extremely fast. If you need better detection of near-degenerate
6443 : cases, use RMatrixLUSolveM() function.
6444 :
6445 : Algorithm features:
6446 : * O(M*N^2) complexity
6447 : * fast algorithm without ANY additional checks, just triangular solver
6448 :
6449 : ! COMMERCIAL EDITION OF ALGLIB:
6450 : !
6451 : ! Commercial Edition of ALGLIB includes following important improvements
6452 : ! of this function:
6453 : ! * high-performance native backend with same C# interface (C# version)
6454 : ! * multithreading support (C++ and C# versions)
6455 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6456 : ! (C++ and C# versions, x86/x64 platform)
6457 : !
6458 : ! We recommend you to read 'Working with commercial version' section of
6459 : ! ALGLIB Reference Manual in order to find out how to use performance-
6460 : ! related features provided by commercial edition of ALGLIB.
6461 :
6462 : INPUT PARAMETERS:
6463 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
6464 : P - array[0..N-1], pivots array, RMatrixLU result
6465 : N - size of A
6466 : B - array[0..N-1,0..M-1], right part
6467 : M - right part size
6468 :
6469 : OUTPUT PARAMETERS:
6470 : Info - return code:
6471 : * -3 matrix is exactly singular (ill conditioned matrices
6472 : are not recognized).
6473 : * -1 N<=0 was passed
6474 : * 1 task is solved
6475 : B - array[N,M]:
6476 : * info>0 => overwritten by solution
6477 : * info=-3 => filled by zeros
6478 :
6479 : -- ALGLIB --
6480 : Copyright 18.03.2015 by Bochkanov Sergey
6481 : *************************************************************************/
6482 0 : void rmatrixlusolvemfast(/* Real */ ae_matrix* lua,
6483 : /* Integer */ ae_vector* p,
6484 : ae_int_t n,
6485 : /* Real */ ae_matrix* b,
6486 : ae_int_t m,
6487 : ae_int_t* info,
6488 : ae_state *_state)
6489 : {
6490 : double v;
6491 : ae_int_t i;
6492 : ae_int_t j;
6493 : ae_int_t k;
6494 :
6495 0 : *info = 0;
6496 :
6497 :
6498 : /*
6499 : * Check for exact degeneracy
6500 : */
6501 0 : if( n<=0||m<=0 )
6502 : {
6503 0 : *info = -1;
6504 0 : return;
6505 : }
6506 0 : for(i=0; i<=n-1; i++)
6507 : {
6508 0 : if( ae_fp_eq(lua->ptr.pp_double[i][i],(double)(0)) )
6509 : {
6510 0 : for(j=0; j<=n-1; j++)
6511 : {
6512 0 : for(k=0; k<=m-1; k++)
6513 : {
6514 0 : b->ptr.pp_double[j][k] = 0.0;
6515 : }
6516 : }
6517 0 : *info = -3;
6518 0 : return;
6519 : }
6520 : }
6521 :
6522 : /*
6523 : * Solve with TRSM()
6524 : */
6525 0 : for(i=0; i<=n-1; i++)
6526 : {
6527 0 : if( p->ptr.p_int[i]!=i )
6528 : {
6529 0 : for(j=0; j<=m-1; j++)
6530 : {
6531 0 : v = b->ptr.pp_double[i][j];
6532 0 : b->ptr.pp_double[i][j] = b->ptr.pp_double[p->ptr.p_int[i]][j];
6533 0 : b->ptr.pp_double[p->ptr.p_int[i]][j] = v;
6534 : }
6535 : }
6536 : }
6537 0 : rmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
6538 0 : rmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
6539 0 : *info = 1;
6540 : }
6541 :
6542 :
6543 : /*************************************************************************
6544 : Dense solver.
6545 :
6546 : This subroutine solves a system A*x=b, where BOTH ORIGINAL A AND ITS
6547 : LU DECOMPOSITION ARE KNOWN. You can use it if for some reasons you have
6548 : both A and its LU decomposition.
6549 :
6550 : Algorithm features:
6551 : * automatic detection of degenerate cases
6552 : * condition number estimation
6553 : * iterative refinement
6554 : * O(N^2) complexity
6555 :
6556 : INPUT PARAMETERS
6557 : A - array[0..N-1,0..N-1], system matrix
6558 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
6559 : P - array[0..N-1], pivots array, RMatrixLU result
6560 : N - size of A
6561 : B - array[0..N-1], right part
6562 :
6563 : OUTPUT PARAMETERS
6564 : Info - return code:
6565 : * -3 matrix is very badly conditioned or exactly singular.
6566 : * -1 N<=0 was passed
6567 : * 1 task is solved (but matrix A may be ill-conditioned,
6568 : check R1/RInf parameters for condition numbers).
6569 : Rep - additional report, following fields are set:
6570 : * rep.r1 condition number in 1-norm
6571 : * rep.rinf condition number in inf-norm
6572 : X - array[N], it contains:
6573 : * info>0 => solution
6574 : * info=-3 => filled by zeros
6575 :
6576 : -- ALGLIB --
6577 : Copyright 27.01.2010 by Bochkanov Sergey
6578 : *************************************************************************/
6579 0 : void rmatrixmixedsolve(/* Real */ ae_matrix* a,
6580 : /* Real */ ae_matrix* lua,
6581 : /* Integer */ ae_vector* p,
6582 : ae_int_t n,
6583 : /* Real */ ae_vector* b,
6584 : ae_int_t* info,
6585 : densesolverreport* rep,
6586 : /* Real */ ae_vector* x,
6587 : ae_state *_state)
6588 : {
6589 : ae_frame _frame_block;
6590 : ae_matrix bm;
6591 : ae_matrix xm;
6592 :
6593 0 : ae_frame_make(_state, &_frame_block);
6594 0 : memset(&bm, 0, sizeof(bm));
6595 0 : memset(&xm, 0, sizeof(xm));
6596 0 : *info = 0;
6597 0 : _densesolverreport_clear(rep);
6598 0 : ae_vector_clear(x);
6599 0 : ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
6600 0 : ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
6601 :
6602 0 : if( n<=0 )
6603 : {
6604 0 : *info = -1;
6605 0 : ae_frame_leave(_state);
6606 0 : return;
6607 : }
6608 0 : ae_matrix_set_length(&bm, n, 1, _state);
6609 0 : ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
6610 0 : rmatrixmixedsolvem(a, lua, p, n, &bm, 1, info, rep, &xm, _state);
6611 0 : ae_vector_set_length(x, n, _state);
6612 0 : ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
6613 0 : ae_frame_leave(_state);
6614 : }
6615 :
6616 :
6617 : /*************************************************************************
6618 : Dense solver.
6619 :
6620 : Similar to RMatrixMixedSolve() but solves task with multiple right parts
6621 : (where b and x are NxM matrices).
6622 :
6623 : Algorithm features:
6624 : * automatic detection of degenerate cases
6625 : * condition number estimation
6626 : * iterative refinement
6627 : * O(M*N^2) complexity
6628 :
6629 : INPUT PARAMETERS
6630 : A - array[0..N-1,0..N-1], system matrix
6631 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
6632 : P - array[0..N-1], pivots array, RMatrixLU result
6633 : N - size of A
6634 : B - array[0..N-1,0..M-1], right part
6635 : M - right part size
6636 :
6637 : OUTPUT PARAMETERS
6638 : Info - return code:
6639 : * -3 matrix is very badly conditioned or exactly singular.
6640 : * -1 N<=0 was passed
6641 : * 1 task is solved (but matrix A may be ill-conditioned,
6642 : check R1/RInf parameters for condition numbers).
6643 : Rep - additional report, following fields are set:
6644 : * rep.r1 condition number in 1-norm
6645 : * rep.rinf condition number in inf-norm
6646 : X - array[N,M], it contains:
6647 : * info>0 => solution
6648 : * info=-3 => filled by zeros
6649 :
6650 : -- ALGLIB --
6651 : Copyright 27.01.2010 by Bochkanov Sergey
6652 : *************************************************************************/
6653 0 : void rmatrixmixedsolvem(/* Real */ ae_matrix* a,
6654 : /* Real */ ae_matrix* lua,
6655 : /* Integer */ ae_vector* p,
6656 : ae_int_t n,
6657 : /* Real */ ae_matrix* b,
6658 : ae_int_t m,
6659 : ae_int_t* info,
6660 : densesolverreport* rep,
6661 : /* Real */ ae_matrix* x,
6662 : ae_state *_state)
6663 : {
6664 :
6665 0 : *info = 0;
6666 0 : _densesolverreport_clear(rep);
6667 0 : ae_matrix_clear(x);
6668 :
6669 :
6670 : /*
6671 : * prepare: check inputs, allocate space...
6672 : */
6673 0 : if( n<=0||m<=0 )
6674 : {
6675 0 : *info = -1;
6676 0 : return;
6677 : }
6678 :
6679 : /*
6680 : * solve
6681 : */
6682 0 : directdensesolvers_rmatrixlusolveinternal(lua, p, n, a, ae_true, b, m, info, rep, x, _state);
6683 : }
6684 :
6685 :
6686 : /*************************************************************************
6687 : Complex dense solver for A*X=B with N*N complex matrix A, N*M complex
6688 : matrices X and B. "Slow-but-feature-rich" version which provides
6689 : additional functions, at the cost of slower performance. Faster version
6690 : may be invoked with CMatrixSolveMFast() function.
6691 :
6692 : Algorithm features:
6693 : * automatic detection of degenerate cases
6694 : * condition number estimation
6695 : * iterative refinement
6696 : * O(N^3+M*N^2) complexity
6697 :
6698 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
6699 : ! by ALGLIB. It estimates condition number of linear system
6700 : ! and performs iterative refinement, which results in
6701 : ! significant performance penalty when compared with "fast"
6702 : ! version which just performs LU decomposition and calls
6703 : ! triangular solver.
6704 : !
6705 : ! This performance penalty is especially visible in the
6706 : ! multithreaded mode, because both condition number estimation
6707 : ! and iterative refinement are inherently sequential
6708 : ! calculations.
6709 : !
6710 : ! Thus, if you need high performance and if you are pretty sure
6711 : ! that your system is well conditioned, we strongly recommend
6712 : ! you to use faster solver, CMatrixSolveMFast() function.
6713 :
6714 : ! COMMERCIAL EDITION OF ALGLIB:
6715 : !
6716 : ! Commercial Edition of ALGLIB includes following important improvements
6717 : ! of this function:
6718 : ! * high-performance native backend with same C# interface (C# version)
6719 : ! * multithreading support (C++ and C# versions)
6720 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6721 : ! (C++ and C# versions, x86/x64 platform)
6722 : !
6723 : ! We recommend you to read 'Working with commercial version' section of
6724 : ! ALGLIB Reference Manual in order to find out how to use performance-
6725 : ! related features provided by commercial edition of ALGLIB.
6726 :
6727 : INPUT PARAMETERS
6728 : A - array[0..N-1,0..N-1], system matrix
6729 : N - size of A
6730 : B - array[0..N-1,0..M-1], right part
6731 : M - right part size
6732 : RFS - iterative refinement switch:
6733 : * True - refinement is used.
6734 : Less performance, more precision.
6735 : * False - refinement is not used.
6736 : More performance, less precision.
6737 :
6738 : OUTPUT PARAMETERS
6739 : Info - return code:
6740 : * -3 matrix is very badly conditioned or exactly singular.
6741 : X is filled by zeros in such cases.
6742 : * -1 N<=0 was passed
6743 : * 1 task is solved (but matrix A may be ill-conditioned,
6744 : check R1/RInf parameters for condition numbers).
6745 : Rep - additional report, following fields are set:
6746 : * rep.r1 condition number in 1-norm
6747 : * rep.rinf condition number in inf-norm
6748 : X - array[N,M], it contains:
6749 : * info>0 => solution
6750 : * info=-3 => filled by zeros
6751 :
6752 : -- ALGLIB --
6753 : Copyright 27.01.2010 by Bochkanov Sergey
6754 : *************************************************************************/
6755 0 : void cmatrixsolvem(/* Complex */ ae_matrix* a,
6756 : ae_int_t n,
6757 : /* Complex */ ae_matrix* b,
6758 : ae_int_t m,
6759 : ae_bool rfs,
6760 : ae_int_t* info,
6761 : densesolverreport* rep,
6762 : /* Complex */ ae_matrix* x,
6763 : ae_state *_state)
6764 : {
6765 : ae_frame _frame_block;
6766 : ae_matrix da;
6767 : ae_matrix emptya;
6768 : ae_vector p;
6769 : ae_int_t i;
6770 :
6771 0 : ae_frame_make(_state, &_frame_block);
6772 0 : memset(&da, 0, sizeof(da));
6773 0 : memset(&emptya, 0, sizeof(emptya));
6774 0 : memset(&p, 0, sizeof(p));
6775 0 : *info = 0;
6776 0 : _densesolverreport_clear(rep);
6777 0 : ae_matrix_clear(x);
6778 0 : ae_matrix_init(&da, 0, 0, DT_COMPLEX, _state, ae_true);
6779 0 : ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
6780 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
6781 :
6782 :
6783 : /*
6784 : * prepare: check inputs, allocate space...
6785 : */
6786 0 : if( n<=0||m<=0 )
6787 : {
6788 0 : *info = -1;
6789 0 : ae_frame_leave(_state);
6790 0 : return;
6791 : }
6792 0 : ae_matrix_set_length(&da, n, n, _state);
6793 :
6794 : /*
6795 : * factorize, solve
6796 : */
6797 0 : for(i=0; i<=n-1; i++)
6798 : {
6799 0 : ae_v_cmove(&da.ptr.pp_complex[i][0], 1, &a->ptr.pp_complex[i][0], 1, "N", ae_v_len(0,n-1));
6800 : }
6801 0 : cmatrixlu(&da, n, n, &p, _state);
6802 0 : if( rfs )
6803 : {
6804 0 : directdensesolvers_cmatrixlusolveinternal(&da, &p, n, a, ae_true, b, m, info, rep, x, _state);
6805 : }
6806 : else
6807 : {
6808 0 : directdensesolvers_cmatrixlusolveinternal(&da, &p, n, &emptya, ae_false, b, m, info, rep, x, _state);
6809 : }
6810 0 : ae_frame_leave(_state);
6811 : }
6812 :
6813 :
6814 : /*************************************************************************
6815 : Complex dense solver for A*X=B with N*N complex matrix A, N*M complex
6816 : matrices X and B. "Fast-but-lightweight" version which provides just
6817 : triangular solver - and no additional functions like iterative refinement
6818 : or condition number estimation.
6819 :
6820 : Algorithm features:
6821 : * O(N^3+M*N^2) complexity
6822 : * no additional time consuming functions
6823 :
6824 : ! COMMERCIAL EDITION OF ALGLIB:
6825 : !
6826 : ! Commercial Edition of ALGLIB includes following important improvements
6827 : ! of this function:
6828 : ! * high-performance native backend with same C# interface (C# version)
6829 : ! * multithreading support (C++ and C# versions)
6830 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6831 : ! (C++ and C# versions, x86/x64 platform)
6832 : !
6833 : ! We recommend you to read 'Working with commercial version' section of
6834 : ! ALGLIB Reference Manual in order to find out how to use performance-
6835 : ! related features provided by commercial edition of ALGLIB.
6836 :
6837 : INPUT PARAMETERS
6838 : A - array[0..N-1,0..N-1], system matrix
6839 : N - size of A
6840 : B - array[0..N-1,0..M-1], right part
6841 : M - right part size
6842 :
6843 : OUTPUT PARAMETERS:
6844 : Info - return code:
6845 : * -3 matrix is exactly singular (ill conditioned matrices
6846 : are not recognized).
6847 : * -1 N<=0 was passed
6848 : * 1 task is solved
6849 : B - array[N,M]:
6850 : * info>0 => overwritten by solution
6851 : * info=-3 => filled by zeros
6852 :
6853 : -- ALGLIB --
6854 : Copyright 16.03.2015 by Bochkanov Sergey
6855 : *************************************************************************/
6856 0 : void cmatrixsolvemfast(/* Complex */ ae_matrix* a,
6857 : ae_int_t n,
6858 : /* Complex */ ae_matrix* b,
6859 : ae_int_t m,
6860 : ae_int_t* info,
6861 : ae_state *_state)
6862 : {
6863 : ae_frame _frame_block;
6864 : ae_matrix _a;
6865 : ae_complex v;
6866 : ae_int_t i;
6867 : ae_int_t j;
6868 : ae_int_t k;
6869 : ae_vector p;
6870 :
6871 0 : ae_frame_make(_state, &_frame_block);
6872 0 : memset(&_a, 0, sizeof(_a));
6873 0 : memset(&p, 0, sizeof(p));
6874 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
6875 0 : a = &_a;
6876 0 : *info = 0;
6877 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
6878 :
6879 :
6880 : /*
6881 : * Check for exact degeneracy
6882 : */
6883 0 : if( n<=0||m<=0 )
6884 : {
6885 0 : *info = -1;
6886 0 : ae_frame_leave(_state);
6887 0 : return;
6888 : }
6889 0 : cmatrixlu(a, n, n, &p, _state);
6890 0 : for(i=0; i<=n-1; i++)
6891 : {
6892 0 : if( ae_c_eq_d(a->ptr.pp_complex[i][i],(double)(0)) )
6893 : {
6894 0 : for(j=0; j<=n-1; j++)
6895 : {
6896 0 : for(k=0; k<=m-1; k++)
6897 : {
6898 0 : b->ptr.pp_complex[j][k] = ae_complex_from_d(0.0);
6899 : }
6900 : }
6901 0 : *info = -3;
6902 0 : ae_frame_leave(_state);
6903 0 : return;
6904 : }
6905 : }
6906 :
6907 : /*
6908 : * Solve with TRSM()
6909 : */
6910 0 : for(i=0; i<=n-1; i++)
6911 : {
6912 0 : if( p.ptr.p_int[i]!=i )
6913 : {
6914 0 : for(j=0; j<=m-1; j++)
6915 : {
6916 0 : v = b->ptr.pp_complex[i][j];
6917 0 : b->ptr.pp_complex[i][j] = b->ptr.pp_complex[p.ptr.p_int[i]][j];
6918 0 : b->ptr.pp_complex[p.ptr.p_int[i]][j] = v;
6919 : }
6920 : }
6921 : }
6922 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
6923 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
6924 0 : *info = 1;
6925 0 : ae_frame_leave(_state);
6926 : }
6927 :
6928 :
6929 : /*************************************************************************
6930 : Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex
6931 : vectors x and b. "Slow-but-feature-rich" version of the solver.
6932 :
6933 : Algorithm features:
6934 : * automatic detection of degenerate cases
6935 : * condition number estimation
6936 : * iterative refinement
6937 : * O(N^3) complexity
6938 :
6939 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
6940 : ! by ALGLIB. It estimates condition number of linear system
6941 : ! and performs iterative refinement, which results in
6942 : ! significant performance penalty when compared with "fast"
6943 : ! version which just performs LU decomposition and calls
6944 : ! triangular solver.
6945 : !
6946 : ! This performance penalty is especially visible in the
6947 : ! multithreaded mode, because both condition number estimation
6948 : ! and iterative refinement are inherently sequential
6949 : ! calculations.
6950 : !
6951 : ! Thus, if you need high performance and if you are pretty sure
6952 : ! that your system is well conditioned, we strongly recommend
6953 : ! you to use faster solver, CMatrixSolveFast() function.
6954 :
6955 : ! COMMERCIAL EDITION OF ALGLIB:
6956 : !
6957 : ! Commercial Edition of ALGLIB includes following important improvements
6958 : ! of this function:
6959 : ! * high-performance native backend with same C# interface (C# version)
6960 : ! * multithreading support (C++ and C# versions)
6961 : ! * hardware vendor (Intel) implementations of linear algebra primitives
6962 : ! (C++ and C# versions, x86/x64 platform)
6963 : !
6964 : ! We recommend you to read 'Working with commercial version' section of
6965 : ! ALGLIB Reference Manual in order to find out how to use performance-
6966 : ! related features provided by commercial edition of ALGLIB.
6967 :
6968 : INPUT PARAMETERS
6969 : A - array[0..N-1,0..N-1], system matrix
6970 : N - size of A
6971 : B - array[0..N-1], right part
6972 :
6973 : OUTPUT PARAMETERS
6974 : Info - return code:
6975 : * -3 matrix is very badly conditioned or exactly singular.
6976 : * -1 N<=0 was passed
6977 : * 1 task is solved (but matrix A may be ill-conditioned,
6978 : check R1/RInf parameters for condition numbers).
6979 : Rep - additional report, following fields are set:
6980 : * rep.r1 condition number in 1-norm
6981 : * rep.rinf condition number in inf-norm
6982 : X - array[N], it contains:
6983 : * info>0 => solution
6984 : * info=-3 => filled by zeros
6985 :
6986 : -- ALGLIB --
6987 : Copyright 27.01.2010 by Bochkanov Sergey
6988 : *************************************************************************/
6989 0 : void cmatrixsolve(/* Complex */ ae_matrix* a,
6990 : ae_int_t n,
6991 : /* Complex */ ae_vector* b,
6992 : ae_int_t* info,
6993 : densesolverreport* rep,
6994 : /* Complex */ ae_vector* x,
6995 : ae_state *_state)
6996 : {
6997 : ae_frame _frame_block;
6998 : ae_matrix bm;
6999 : ae_matrix xm;
7000 :
7001 0 : ae_frame_make(_state, &_frame_block);
7002 0 : memset(&bm, 0, sizeof(bm));
7003 0 : memset(&xm, 0, sizeof(xm));
7004 0 : *info = 0;
7005 0 : _densesolverreport_clear(rep);
7006 0 : ae_vector_clear(x);
7007 0 : ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
7008 0 : ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
7009 :
7010 0 : if( n<=0 )
7011 : {
7012 0 : *info = -1;
7013 0 : ae_frame_leave(_state);
7014 0 : return;
7015 : }
7016 0 : ae_matrix_set_length(&bm, n, 1, _state);
7017 0 : ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
7018 0 : cmatrixsolvem(a, n, &bm, 1, ae_true, info, rep, &xm, _state);
7019 0 : ae_vector_set_length(x, n, _state);
7020 0 : ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
7021 0 : ae_frame_leave(_state);
7022 : }
7023 :
7024 :
7025 : /*************************************************************************
7026 : Complex dense solver for A*x=B with N*N complex matrix A and N*1 complex
7027 : vectors x and b. "Fast-but-lightweight" version of the solver.
7028 :
7029 : Algorithm features:
7030 : * O(N^3) complexity
7031 : * no additional time consuming features, just triangular solver
7032 :
7033 : ! COMMERCIAL EDITION OF ALGLIB:
7034 : !
7035 : ! Commercial Edition of ALGLIB includes following important improvements
7036 : ! of this function:
7037 : ! * high-performance native backend with same C# interface (C# version)
7038 : ! * multithreading support (C++ and C# versions)
7039 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7040 : ! (C++ and C# versions, x86/x64 platform)
7041 : !
7042 : ! We recommend you to read 'Working with commercial version' section of
7043 : ! ALGLIB Reference Manual in order to find out how to use performance-
7044 : ! related features provided by commercial edition of ALGLIB.
7045 :
7046 : INPUT PARAMETERS:
7047 : A - array[0..N-1,0..N-1], system matrix
7048 : N - size of A
7049 : B - array[0..N-1], right part
7050 :
7051 : OUTPUT PARAMETERS:
7052 : Info - return code:
7053 : * -3 matrix is exactly singular (ill conditioned matrices
7054 : are not recognized).
7055 : * -1 N<=0 was passed
7056 : * 1 task is solved
7057 : B - array[N]:
7058 : * info>0 => overwritten by solution
7059 : * info=-3 => filled by zeros
7060 :
7061 : -- ALGLIB --
7062 : Copyright 27.01.2010 by Bochkanov Sergey
7063 : *************************************************************************/
7064 0 : void cmatrixsolvefast(/* Complex */ ae_matrix* a,
7065 : ae_int_t n,
7066 : /* Complex */ ae_vector* b,
7067 : ae_int_t* info,
7068 : ae_state *_state)
7069 : {
7070 : ae_frame _frame_block;
7071 : ae_matrix _a;
7072 : ae_int_t i;
7073 : ae_int_t j;
7074 : ae_vector p;
7075 :
7076 0 : ae_frame_make(_state, &_frame_block);
7077 0 : memset(&_a, 0, sizeof(_a));
7078 0 : memset(&p, 0, sizeof(p));
7079 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
7080 0 : a = &_a;
7081 0 : *info = 0;
7082 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
7083 :
7084 0 : if( n<=0 )
7085 : {
7086 0 : *info = -1;
7087 0 : ae_frame_leave(_state);
7088 0 : return;
7089 : }
7090 0 : cmatrixlu(a, n, n, &p, _state);
7091 0 : for(i=0; i<=n-1; i++)
7092 : {
7093 0 : if( ae_c_eq_d(a->ptr.pp_complex[i][i],(double)(0)) )
7094 : {
7095 0 : for(j=0; j<=n-1; j++)
7096 : {
7097 0 : b->ptr.p_complex[j] = ae_complex_from_d(0.0);
7098 : }
7099 0 : *info = -3;
7100 0 : ae_frame_leave(_state);
7101 0 : return;
7102 : }
7103 : }
7104 0 : directdensesolvers_cbasiclusolve(a, &p, n, b, _state);
7105 0 : *info = 1;
7106 0 : ae_frame_leave(_state);
7107 : }
7108 :
7109 :
7110 : /*************************************************************************
7111 : Dense solver for A*X=B with N*N complex A given by its LU decomposition,
7112 : and N*M matrices X and B (multiple right sides). "Slow-but-feature-rich"
7113 : version of the solver.
7114 :
7115 : Algorithm features:
7116 : * automatic detection of degenerate cases
7117 : * O(M*N^2) complexity
7118 : * condition number estimation
7119 :
7120 : No iterative refinement is provided because exact form of original matrix
7121 : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you
7122 : need iterative refinement.
7123 :
7124 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
7125 : ! by ALGLIB. It estimates condition number of linear system,
7126 : ! which results in significant performance penalty when
7127 : ! compared with "fast" version which just calls triangular
7128 : ! solver.
7129 : !
7130 : ! This performance penalty is especially apparent when you use
7131 : ! ALGLIB parallel capabilities (condition number estimation is
7132 : ! inherently sequential). It also becomes significant for
7133 : ! small-scale problems.
7134 : !
7135 : ! In such cases we strongly recommend you to use faster solver,
7136 : ! CMatrixLUSolveMFast() function.
7137 :
7138 : ! COMMERCIAL EDITION OF ALGLIB:
7139 : !
7140 : ! Commercial Edition of ALGLIB includes following important improvements
7141 : ! of this function:
7142 : ! * high-performance native backend with same C# interface (C# version)
7143 : ! * multithreading support (C++ and C# versions)
7144 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7145 : ! (C++ and C# versions, x86/x64 platform)
7146 : !
7147 : ! We recommend you to read 'Working with commercial version' section of
7148 : ! ALGLIB Reference Manual in order to find out how to use performance-
7149 : ! related features provided by commercial edition of ALGLIB.
7150 :
7151 : INPUT PARAMETERS
7152 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
7153 : P - array[0..N-1], pivots array, RMatrixLU result
7154 : N - size of A
7155 : B - array[0..N-1,0..M-1], right part
7156 : M - right part size
7157 :
7158 : OUTPUT PARAMETERS
7159 : Info - return code:
7160 : * -3 matrix is very badly conditioned or exactly singular.
7161 : * -1 N<=0 was passed
7162 : * 1 task is solved (but matrix A may be ill-conditioned,
7163 : check R1/RInf parameters for condition numbers).
7164 : Rep - additional report, following fields are set:
7165 : * rep.r1 condition number in 1-norm
7166 : * rep.rinf condition number in inf-norm
7167 : X - array[N,M], it contains:
7168 : * info>0 => solution
7169 : * info=-3 => filled by zeros
7170 :
7171 : -- ALGLIB --
7172 : Copyright 27.01.2010 by Bochkanov Sergey
7173 : *************************************************************************/
7174 0 : void cmatrixlusolvem(/* Complex */ ae_matrix* lua,
7175 : /* Integer */ ae_vector* p,
7176 : ae_int_t n,
7177 : /* Complex */ ae_matrix* b,
7178 : ae_int_t m,
7179 : ae_int_t* info,
7180 : densesolverreport* rep,
7181 : /* Complex */ ae_matrix* x,
7182 : ae_state *_state)
7183 : {
7184 : ae_frame _frame_block;
7185 : ae_matrix emptya;
7186 :
7187 0 : ae_frame_make(_state, &_frame_block);
7188 0 : memset(&emptya, 0, sizeof(emptya));
7189 0 : *info = 0;
7190 0 : _densesolverreport_clear(rep);
7191 0 : ae_matrix_clear(x);
7192 0 : ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
7193 :
7194 :
7195 : /*
7196 : * prepare: check inputs, allocate space...
7197 : */
7198 0 : if( n<=0||m<=0 )
7199 : {
7200 0 : *info = -1;
7201 0 : ae_frame_leave(_state);
7202 0 : return;
7203 : }
7204 :
7205 : /*
7206 : * solve
7207 : */
7208 0 : directdensesolvers_cmatrixlusolveinternal(lua, p, n, &emptya, ae_false, b, m, info, rep, x, _state);
7209 0 : ae_frame_leave(_state);
7210 : }
7211 :
7212 :
7213 : /*************************************************************************
7214 : Dense solver for A*X=B with N*N complex A given by its LU decomposition,
7215 : and N*M matrices X and B (multiple right sides). "Fast-but-lightweight"
7216 : version of the solver.
7217 :
7218 : Algorithm features:
7219 : * O(M*N^2) complexity
7220 : * no additional time-consuming features
7221 :
7222 : ! COMMERCIAL EDITION OF ALGLIB:
7223 : !
7224 : ! Commercial Edition of ALGLIB includes following important improvements
7225 : ! of this function:
7226 : ! * high-performance native backend with same C# interface (C# version)
7227 : ! * multithreading support (C++ and C# versions)
7228 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7229 : ! (C++ and C# versions, x86/x64 platform)
7230 : !
7231 : ! We recommend you to read 'Working with commercial version' section of
7232 : ! ALGLIB Reference Manual in order to find out how to use performance-
7233 : ! related features provided by commercial edition of ALGLIB.
7234 :
7235 : INPUT PARAMETERS
7236 : LUA - array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
7237 : P - array[0..N-1], pivots array, RMatrixLU result
7238 : N - size of A
7239 : B - array[0..N-1,0..M-1], right part
7240 : M - right part size
7241 :
7242 : OUTPUT PARAMETERS
7243 : Info - return code:
7244 : * -3 matrix is exactly singular (ill conditioned matrices
7245 : are not recognized).
7246 : * -1 N<=0 was passed
7247 : * 1 task is solved
7248 : B - array[N,M]:
7249 : * info>0 => overwritten by solution
7250 : * info=-3 => filled by zeros
7251 :
7252 :
7253 : -- ALGLIB --
7254 : Copyright 27.01.2010 by Bochkanov Sergey
7255 : *************************************************************************/
7256 0 : void cmatrixlusolvemfast(/* Complex */ ae_matrix* lua,
7257 : /* Integer */ ae_vector* p,
7258 : ae_int_t n,
7259 : /* Complex */ ae_matrix* b,
7260 : ae_int_t m,
7261 : ae_int_t* info,
7262 : ae_state *_state)
7263 : {
7264 : ae_complex v;
7265 : ae_int_t i;
7266 : ae_int_t j;
7267 : ae_int_t k;
7268 :
7269 0 : *info = 0;
7270 :
7271 :
7272 : /*
7273 : * Check for exact degeneracy
7274 : */
7275 0 : if( n<=0||m<=0 )
7276 : {
7277 0 : *info = -1;
7278 0 : return;
7279 : }
7280 0 : for(i=0; i<=n-1; i++)
7281 : {
7282 0 : if( ae_c_eq_d(lua->ptr.pp_complex[i][i],(double)(0)) )
7283 : {
7284 0 : for(j=0; j<=n-1; j++)
7285 : {
7286 0 : for(k=0; k<=m-1; k++)
7287 : {
7288 0 : b->ptr.pp_complex[j][k] = ae_complex_from_d(0.0);
7289 : }
7290 : }
7291 0 : *info = -3;
7292 0 : return;
7293 : }
7294 : }
7295 :
7296 : /*
7297 : * Solve with TRSM()
7298 : */
7299 0 : for(i=0; i<=n-1; i++)
7300 : {
7301 0 : if( p->ptr.p_int[i]!=i )
7302 : {
7303 0 : for(j=0; j<=m-1; j++)
7304 : {
7305 0 : v = b->ptr.pp_complex[i][j];
7306 0 : b->ptr.pp_complex[i][j] = b->ptr.pp_complex[p->ptr.p_int[i]][j];
7307 0 : b->ptr.pp_complex[p->ptr.p_int[i]][j] = v;
7308 : }
7309 : }
7310 : }
7311 0 : cmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
7312 0 : cmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
7313 0 : *info = 1;
7314 : }
7315 :
7316 :
7317 : /*************************************************************************
7318 : Complex dense linear solver for A*x=b with complex N*N A given by its LU
7319 : decomposition and N*1 vectors x and b. This is "slow-but-robust" version
7320 : of the complex linear solver with additional features which add
7321 : significant performance overhead. Faster version is CMatrixLUSolveFast()
7322 : function.
7323 :
7324 : Algorithm features:
7325 : * automatic detection of degenerate cases
7326 : * O(N^2) complexity
7327 : * condition number estimation
7328 :
7329 : No iterative refinement is provided because exact form of original matrix
7330 : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve if you
7331 : need iterative refinement.
7332 :
7333 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
7334 : ! by ALGLIB. It estimates condition number of linear system,
7335 : ! which results in 10-15x performance penalty when compared
7336 : ! with "fast" version which just calls triangular solver.
7337 : !
7338 : ! This performance penalty is insignificant when compared with
7339 : ! cost of large LU decomposition. However, if you call this
7340 : ! function many times for the same left side, this overhead
7341 : ! BECOMES significant. It also becomes significant for small-
7342 : ! scale problems.
7343 : !
7344 : ! In such cases we strongly recommend you to use faster solver,
7345 : ! CMatrixLUSolveFast() function.
7346 :
7347 : INPUT PARAMETERS
7348 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
7349 : P - array[0..N-1], pivots array, CMatrixLU result
7350 : N - size of A
7351 : B - array[0..N-1], right part
7352 :
7353 : OUTPUT PARAMETERS
7354 : Info - return code:
7355 : * -3 matrix is very badly conditioned or exactly singular.
7356 : * -1 N<=0 was passed
7357 : * 1 task is solved (but matrix A may be ill-conditioned,
7358 : check R1/RInf parameters for condition numbers).
7359 : Rep - additional report, following fields are set:
7360 : * rep.r1 condition number in 1-norm
7361 : * rep.rinf condition number in inf-norm
7362 : X - array[N], it contains:
7363 : * info>0 => solution
7364 : * info=-3 => filled by zeros
7365 :
7366 : -- ALGLIB --
7367 : Copyright 27.01.2010 by Bochkanov Sergey
7368 : *************************************************************************/
7369 0 : void cmatrixlusolve(/* Complex */ ae_matrix* lua,
7370 : /* Integer */ ae_vector* p,
7371 : ae_int_t n,
7372 : /* Complex */ ae_vector* b,
7373 : ae_int_t* info,
7374 : densesolverreport* rep,
7375 : /* Complex */ ae_vector* x,
7376 : ae_state *_state)
7377 : {
7378 : ae_frame _frame_block;
7379 : ae_matrix bm;
7380 : ae_matrix xm;
7381 :
7382 0 : ae_frame_make(_state, &_frame_block);
7383 0 : memset(&bm, 0, sizeof(bm));
7384 0 : memset(&xm, 0, sizeof(xm));
7385 0 : *info = 0;
7386 0 : _densesolverreport_clear(rep);
7387 0 : ae_vector_clear(x);
7388 0 : ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
7389 0 : ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
7390 :
7391 0 : if( n<=0 )
7392 : {
7393 0 : *info = -1;
7394 0 : ae_frame_leave(_state);
7395 0 : return;
7396 : }
7397 0 : ae_matrix_set_length(&bm, n, 1, _state);
7398 0 : ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
7399 0 : cmatrixlusolvem(lua, p, n, &bm, 1, info, rep, &xm, _state);
7400 0 : ae_vector_set_length(x, n, _state);
7401 0 : ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
7402 0 : ae_frame_leave(_state);
7403 : }
7404 :
7405 :
7406 : /*************************************************************************
7407 : Complex dense linear solver for A*x=b with N*N complex A given by its LU
7408 : decomposition and N*1 vectors x and b. This is fast lightweight version
7409 : of solver, which is significantly faster than CMatrixLUSolve(), but does
7410 : not provide additional information (like condition numbers).
7411 :
7412 : Algorithm features:
7413 : * O(N^2) complexity
7414 : * no additional time-consuming features, just triangular solver
7415 :
7416 : INPUT PARAMETERS
7417 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
7418 : P - array[0..N-1], pivots array, CMatrixLU result
7419 : N - size of A
7420 : B - array[0..N-1], right part
7421 :
7422 : OUTPUT PARAMETERS
7423 : Info - return code:
7424 : * -3 matrix is exactly singular (ill conditioned matrices
7425 : are not recognized).
7426 : * -1 N<=0 was passed
7427 : * 1 task is solved
7428 : B - array[N]:
7429 : * info>0 => overwritten by solution
7430 : * info=-3 => filled by zeros
7431 :
7432 : NOTE: unlike CMatrixLUSolve(), this function does NOT check for
7433 : near-degeneracy of input matrix. It checks for EXACT degeneracy,
7434 : because this check is easy to do. However, very badly conditioned
7435 : matrices may went unnoticed.
7436 :
7437 :
7438 : -- ALGLIB --
7439 : Copyright 27.01.2010 by Bochkanov Sergey
7440 : *************************************************************************/
7441 0 : void cmatrixlusolvefast(/* Complex */ ae_matrix* lua,
7442 : /* Integer */ ae_vector* p,
7443 : ae_int_t n,
7444 : /* Complex */ ae_vector* b,
7445 : ae_int_t* info,
7446 : ae_state *_state)
7447 : {
7448 : ae_int_t i;
7449 : ae_int_t j;
7450 :
7451 0 : *info = 0;
7452 :
7453 0 : if( n<=0 )
7454 : {
7455 0 : *info = -1;
7456 0 : return;
7457 : }
7458 0 : for(i=0; i<=n-1; i++)
7459 : {
7460 0 : if( ae_c_eq_d(lua->ptr.pp_complex[i][i],(double)(0)) )
7461 : {
7462 0 : for(j=0; j<=n-1; j++)
7463 : {
7464 0 : b->ptr.p_complex[j] = ae_complex_from_d(0.0);
7465 : }
7466 0 : *info = -3;
7467 0 : return;
7468 : }
7469 : }
7470 0 : directdensesolvers_cbasiclusolve(lua, p, n, b, _state);
7471 0 : *info = 1;
7472 : }
7473 :
7474 :
7475 : /*************************************************************************
7476 : Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
7477 :
7478 : Algorithm features:
7479 : * automatic detection of degenerate cases
7480 : * condition number estimation
7481 : * iterative refinement
7482 : * O(M*N^2) complexity
7483 :
7484 : INPUT PARAMETERS
7485 : A - array[0..N-1,0..N-1], system matrix
7486 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
7487 : P - array[0..N-1], pivots array, CMatrixLU result
7488 : N - size of A
7489 : B - array[0..N-1,0..M-1], right part
7490 : M - right part size
7491 :
7492 : OUTPUT PARAMETERS
7493 : Info - return code:
7494 : * -3 matrix is very badly conditioned or exactly singular.
7495 : * -1 N<=0 was passed
7496 : * 1 task is solved (but matrix A may be ill-conditioned,
7497 : check R1/RInf parameters for condition numbers).
7498 : Rep - additional report, following fields are set:
7499 : * rep.r1 condition number in 1-norm
7500 : * rep.rinf condition number in inf-norm
7501 : X - array[N,M], it contains:
7502 : * info>0 => solution
7503 : * info=-3 => filled by zeros
7504 :
7505 : -- ALGLIB --
7506 : Copyright 27.01.2010 by Bochkanov Sergey
7507 : *************************************************************************/
7508 0 : void cmatrixmixedsolvem(/* Complex */ ae_matrix* a,
7509 : /* Complex */ ae_matrix* lua,
7510 : /* Integer */ ae_vector* p,
7511 : ae_int_t n,
7512 : /* Complex */ ae_matrix* b,
7513 : ae_int_t m,
7514 : ae_int_t* info,
7515 : densesolverreport* rep,
7516 : /* Complex */ ae_matrix* x,
7517 : ae_state *_state)
7518 : {
7519 :
7520 0 : *info = 0;
7521 0 : _densesolverreport_clear(rep);
7522 0 : ae_matrix_clear(x);
7523 :
7524 :
7525 : /*
7526 : * prepare: check inputs, allocate space...
7527 : */
7528 0 : if( n<=0||m<=0 )
7529 : {
7530 0 : *info = -1;
7531 0 : return;
7532 : }
7533 :
7534 : /*
7535 : * solve
7536 : */
7537 0 : directdensesolvers_cmatrixlusolveinternal(lua, p, n, a, ae_true, b, m, info, rep, x, _state);
7538 : }
7539 :
7540 :
7541 : /*************************************************************************
7542 : Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
7543 :
7544 : Algorithm features:
7545 : * automatic detection of degenerate cases
7546 : * condition number estimation
7547 : * iterative refinement
7548 : * O(N^2) complexity
7549 :
7550 : INPUT PARAMETERS
7551 : A - array[0..N-1,0..N-1], system matrix
7552 : LUA - array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
7553 : P - array[0..N-1], pivots array, CMatrixLU result
7554 : N - size of A
7555 : B - array[0..N-1], right part
7556 :
7557 : OUTPUT PARAMETERS
7558 : Info - return code:
7559 : * -3 matrix is very badly conditioned or exactly singular.
7560 : * -1 N<=0 was passed
7561 : * 1 task is solved (but matrix A may be ill-conditioned,
7562 : check R1/RInf parameters for condition numbers).
7563 : Rep - additional report, following fields are set:
7564 : * rep.r1 condition number in 1-norm
7565 : * rep.rinf condition number in inf-norm
7566 : X - array[N], it contains:
7567 : * info>0 => solution
7568 : * info=-3 => filled by zeros
7569 :
7570 : -- ALGLIB --
7571 : Copyright 27.01.2010 by Bochkanov Sergey
7572 : *************************************************************************/
7573 0 : void cmatrixmixedsolve(/* Complex */ ae_matrix* a,
7574 : /* Complex */ ae_matrix* lua,
7575 : /* Integer */ ae_vector* p,
7576 : ae_int_t n,
7577 : /* Complex */ ae_vector* b,
7578 : ae_int_t* info,
7579 : densesolverreport* rep,
7580 : /* Complex */ ae_vector* x,
7581 : ae_state *_state)
7582 : {
7583 : ae_frame _frame_block;
7584 : ae_matrix bm;
7585 : ae_matrix xm;
7586 :
7587 0 : ae_frame_make(_state, &_frame_block);
7588 0 : memset(&bm, 0, sizeof(bm));
7589 0 : memset(&xm, 0, sizeof(xm));
7590 0 : *info = 0;
7591 0 : _densesolverreport_clear(rep);
7592 0 : ae_vector_clear(x);
7593 0 : ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
7594 0 : ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
7595 :
7596 0 : if( n<=0 )
7597 : {
7598 0 : *info = -1;
7599 0 : ae_frame_leave(_state);
7600 0 : return;
7601 : }
7602 0 : ae_matrix_set_length(&bm, n, 1, _state);
7603 0 : ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
7604 0 : cmatrixmixedsolvem(a, lua, p, n, &bm, 1, info, rep, &xm, _state);
7605 0 : ae_vector_set_length(x, n, _state);
7606 0 : ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
7607 0 : ae_frame_leave(_state);
7608 : }
7609 :
7610 :
7611 : /*************************************************************************
7612 : Dense solver for A*X=B with N*N symmetric positive definite matrix A, and
7613 : N*M vectors X and B. It is "slow-but-feature-rich" version of the solver.
7614 :
7615 : Algorithm features:
7616 : * automatic detection of degenerate cases
7617 : * condition number estimation
7618 : * O(N^3+M*N^2) complexity
7619 : * matrix is represented by its upper or lower triangle
7620 :
7621 : No iterative refinement is provided because such partial representation of
7622 : matrix does not allow efficient calculation of extra-precise matrix-vector
7623 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
7624 : need iterative refinement.
7625 :
7626 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
7627 : ! by ALGLIB. It estimates condition number of linear system,
7628 : ! which results in significant performance penalty when
7629 : ! compared with "fast" version which just performs Cholesky
7630 : ! decomposition and calls triangular solver.
7631 : !
7632 : ! This performance penalty is especially visible in the
7633 : ! multithreaded mode, because both condition number estimation
7634 : ! and iterative refinement are inherently sequential
7635 : ! calculations.
7636 : !
7637 : ! Thus, if you need high performance and if you are pretty sure
7638 : ! that your system is well conditioned, we strongly recommend
7639 : ! you to use faster solver, SPDMatrixSolveMFast() function.
7640 :
7641 : ! COMMERCIAL EDITION OF ALGLIB:
7642 : !
7643 : ! Commercial Edition of ALGLIB includes following important improvements
7644 : ! of this function:
7645 : ! * high-performance native backend with same C# interface (C# version)
7646 : ! * multithreading support (C++ and C# versions)
7647 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7648 : ! (C++ and C# versions, x86/x64 platform)
7649 : !
7650 : ! We recommend you to read 'Working with commercial version' section of
7651 : ! ALGLIB Reference Manual in order to find out how to use performance-
7652 : ! related features provided by commercial edition of ALGLIB.
7653 :
7654 : INPUT PARAMETERS
7655 : A - array[0..N-1,0..N-1], system matrix
7656 : N - size of A
7657 : IsUpper - what half of A is provided
7658 : B - array[0..N-1,0..M-1], right part
7659 : M - right part size
7660 :
7661 : OUTPUT PARAMETERS
7662 : Info - return code:
7663 : * -3 matrix is very badly conditioned or non-SPD.
7664 : * -1 N<=0 was passed
7665 : * 1 task is solved (but matrix A may be ill-conditioned,
7666 : check R1/RInf parameters for condition numbers).
7667 : Rep - additional report, following fields are set:
7668 : * rep.r1 condition number in 1-norm
7669 : * rep.rinf condition number in inf-norm
7670 : X - array[N,M], it contains:
7671 : * info>0 => solution
7672 : * info=-3 => filled by zeros
7673 :
7674 : -- ALGLIB --
7675 : Copyright 27.01.2010 by Bochkanov Sergey
7676 : *************************************************************************/
7677 0 : void spdmatrixsolvem(/* Real */ ae_matrix* a,
7678 : ae_int_t n,
7679 : ae_bool isupper,
7680 : /* Real */ ae_matrix* b,
7681 : ae_int_t m,
7682 : ae_int_t* info,
7683 : densesolverreport* rep,
7684 : /* Real */ ae_matrix* x,
7685 : ae_state *_state)
7686 : {
7687 : ae_frame _frame_block;
7688 : ae_matrix da;
7689 : ae_int_t i;
7690 : ae_int_t j;
7691 : ae_int_t j1;
7692 : ae_int_t j2;
7693 :
7694 0 : ae_frame_make(_state, &_frame_block);
7695 0 : memset(&da, 0, sizeof(da));
7696 0 : *info = 0;
7697 0 : _densesolverreport_clear(rep);
7698 0 : ae_matrix_clear(x);
7699 0 : ae_matrix_init(&da, 0, 0, DT_REAL, _state, ae_true);
7700 :
7701 :
7702 : /*
7703 : * prepare: check inputs, allocate space...
7704 : */
7705 0 : if( n<=0||m<=0 )
7706 : {
7707 0 : *info = -1;
7708 0 : ae_frame_leave(_state);
7709 0 : return;
7710 : }
7711 0 : ae_matrix_set_length(&da, n, n, _state);
7712 :
7713 : /*
7714 : * factorize
7715 : * solve
7716 : */
7717 0 : for(i=0; i<=n-1; i++)
7718 : {
7719 0 : if( isupper )
7720 : {
7721 0 : j1 = i;
7722 0 : j2 = n-1;
7723 : }
7724 : else
7725 : {
7726 0 : j1 = 0;
7727 0 : j2 = i;
7728 : }
7729 0 : ae_v_move(&da.ptr.pp_double[i][j1], 1, &a->ptr.pp_double[i][j1], 1, ae_v_len(j1,j2));
7730 : }
7731 0 : if( !spdmatrixcholesky(&da, n, isupper, _state) )
7732 : {
7733 0 : ae_matrix_set_length(x, n, m, _state);
7734 0 : for(i=0; i<=n-1; i++)
7735 : {
7736 0 : for(j=0; j<=m-1; j++)
7737 : {
7738 0 : x->ptr.pp_double[i][j] = (double)(0);
7739 : }
7740 : }
7741 0 : rep->r1 = (double)(0);
7742 0 : rep->rinf = (double)(0);
7743 0 : *info = -3;
7744 0 : ae_frame_leave(_state);
7745 0 : return;
7746 : }
7747 0 : *info = 1;
7748 0 : directdensesolvers_spdmatrixcholeskysolveinternal(&da, n, isupper, a, ae_true, b, m, info, rep, x, _state);
7749 0 : ae_frame_leave(_state);
7750 : }
7751 :
7752 :
7753 : /*************************************************************************
7754 : Dense solver for A*X=B with N*N symmetric positive definite matrix A, and
7755 : N*M vectors X and B. It is "fast-but-lightweight" version of the solver.
7756 :
7757 : Algorithm features:
7758 : * O(N^3+M*N^2) complexity
7759 : * matrix is represented by its upper or lower triangle
7760 : * no additional time consuming features
7761 :
7762 : ! COMMERCIAL EDITION OF ALGLIB:
7763 : !
7764 : ! Commercial Edition of ALGLIB includes following important improvements
7765 : ! of this function:
7766 : ! * high-performance native backend with same C# interface (C# version)
7767 : ! * multithreading support (C++ and C# versions)
7768 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7769 : ! (C++ and C# versions, x86/x64 platform)
7770 : !
7771 : ! We recommend you to read 'Working with commercial version' section of
7772 : ! ALGLIB Reference Manual in order to find out how to use performance-
7773 : ! related features provided by commercial edition of ALGLIB.
7774 :
7775 : INPUT PARAMETERS
7776 : A - array[0..N-1,0..N-1], system matrix
7777 : N - size of A
7778 : IsUpper - what half of A is provided
7779 : B - array[0..N-1,0..M-1], right part
7780 : M - right part size
7781 :
7782 : OUTPUT PARAMETERS
7783 : Info - return code:
7784 : * -3 A is is exactly singular
7785 : * -1 N<=0 was passed
7786 : * 1 task was solved
7787 : B - array[N,M], it contains:
7788 : * info>0 => solution
7789 : * info=-3 => filled by zeros
7790 :
7791 : -- ALGLIB --
7792 : Copyright 17.03.2015 by Bochkanov Sergey
7793 : *************************************************************************/
7794 0 : void spdmatrixsolvemfast(/* Real */ ae_matrix* a,
7795 : ae_int_t n,
7796 : ae_bool isupper,
7797 : /* Real */ ae_matrix* b,
7798 : ae_int_t m,
7799 : ae_int_t* info,
7800 : ae_state *_state)
7801 : {
7802 : ae_frame _frame_block;
7803 : ae_matrix _a;
7804 : ae_int_t i;
7805 : ae_int_t j;
7806 :
7807 0 : ae_frame_make(_state, &_frame_block);
7808 0 : memset(&_a, 0, sizeof(_a));
7809 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
7810 0 : a = &_a;
7811 0 : *info = 0;
7812 :
7813 0 : *info = 1;
7814 0 : if( n<=0 )
7815 : {
7816 0 : *info = -1;
7817 0 : ae_frame_leave(_state);
7818 0 : return;
7819 : }
7820 0 : if( !spdmatrixcholesky(a, n, isupper, _state) )
7821 : {
7822 0 : for(i=0; i<=n-1; i++)
7823 : {
7824 0 : for(j=0; j<=m-1; j++)
7825 : {
7826 0 : b->ptr.pp_double[i][j] = 0.0;
7827 : }
7828 : }
7829 0 : *info = -3;
7830 0 : ae_frame_leave(_state);
7831 0 : return;
7832 : }
7833 0 : if( isupper )
7834 : {
7835 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 1, b, 0, 0, _state);
7836 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
7837 : }
7838 : else
7839 : {
7840 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
7841 0 : rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 1, b, 0, 0, _state);
7842 : }
7843 0 : ae_frame_leave(_state);
7844 : }
7845 :
7846 :
7847 : /*************************************************************************
7848 : Dense linear solver for A*x=b with N*N real symmetric positive definite
7849 : matrix A, N*1 vectors x and b. "Slow-but-feature-rich" version of the
7850 : solver.
7851 :
7852 : Algorithm features:
7853 : * automatic detection of degenerate cases
7854 : * condition number estimation
7855 : * O(N^3) complexity
7856 : * matrix is represented by its upper or lower triangle
7857 :
7858 : No iterative refinement is provided because such partial representation of
7859 : matrix does not allow efficient calculation of extra-precise matrix-vector
7860 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
7861 : need iterative refinement.
7862 :
7863 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
7864 : ! by ALGLIB. It estimates condition number of linear system,
7865 : ! which results in significant performance penalty when
7866 : ! compared with "fast" version which just performs Cholesky
7867 : ! decomposition and calls triangular solver.
7868 : !
7869 : ! This performance penalty is especially visible in the
7870 : ! multithreaded mode, because both condition number estimation
7871 : ! and iterative refinement are inherently sequential
7872 : ! calculations.
7873 : !
7874 : ! Thus, if you need high performance and if you are pretty sure
7875 : ! that your system is well conditioned, we strongly recommend
7876 : ! you to use faster solver, SPDMatrixSolveFast() function.
7877 :
7878 : ! COMMERCIAL EDITION OF ALGLIB:
7879 : !
7880 : ! Commercial Edition of ALGLIB includes following important improvements
7881 : ! of this function:
7882 : ! * high-performance native backend with same C# interface (C# version)
7883 : ! * multithreading support (C++ and C# versions)
7884 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7885 : ! (C++ and C# versions, x86/x64 platform)
7886 : !
7887 : ! We recommend you to read 'Working with commercial version' section of
7888 : ! ALGLIB Reference Manual in order to find out how to use performance-
7889 : ! related features provided by commercial edition of ALGLIB.
7890 :
7891 : INPUT PARAMETERS
7892 : A - array[0..N-1,0..N-1], system matrix
7893 : N - size of A
7894 : IsUpper - what half of A is provided
7895 : B - array[0..N-1], right part
7896 :
7897 : OUTPUT PARAMETERS
7898 : Info - return code:
7899 : * -3 matrix is very badly conditioned or non-SPD.
7900 : * -1 N<=0 was passed
7901 : * 1 task is solved (but matrix A may be ill-conditioned,
7902 : check R1/RInf parameters for condition numbers).
7903 : Rep - additional report, following fields are set:
7904 : * rep.r1 condition number in 1-norm
7905 : * rep.rinf condition number in inf-norm
7906 : X - array[N], it contains:
7907 : * info>0 => solution
7908 : * info=-3 => filled by zeros
7909 :
7910 : -- ALGLIB --
7911 : Copyright 27.01.2010 by Bochkanov Sergey
7912 : *************************************************************************/
7913 0 : void spdmatrixsolve(/* Real */ ae_matrix* a,
7914 : ae_int_t n,
7915 : ae_bool isupper,
7916 : /* Real */ ae_vector* b,
7917 : ae_int_t* info,
7918 : densesolverreport* rep,
7919 : /* Real */ ae_vector* x,
7920 : ae_state *_state)
7921 : {
7922 : ae_frame _frame_block;
7923 : ae_matrix bm;
7924 : ae_matrix xm;
7925 :
7926 0 : ae_frame_make(_state, &_frame_block);
7927 0 : memset(&bm, 0, sizeof(bm));
7928 0 : memset(&xm, 0, sizeof(xm));
7929 0 : *info = 0;
7930 0 : _densesolverreport_clear(rep);
7931 0 : ae_vector_clear(x);
7932 0 : ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
7933 0 : ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
7934 :
7935 0 : if( n<=0 )
7936 : {
7937 0 : *info = -1;
7938 0 : ae_frame_leave(_state);
7939 0 : return;
7940 : }
7941 0 : ae_matrix_set_length(&bm, n, 1, _state);
7942 0 : ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
7943 0 : spdmatrixsolvem(a, n, isupper, &bm, 1, info, rep, &xm, _state);
7944 0 : ae_vector_set_length(x, n, _state);
7945 0 : ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
7946 0 : ae_frame_leave(_state);
7947 : }
7948 :
7949 :
7950 : /*************************************************************************
7951 : Dense linear solver for A*x=b with N*N real symmetric positive definite
7952 : matrix A, N*1 vectors x and b. "Fast-but-lightweight" version of the
7953 : solver.
7954 :
7955 : Algorithm features:
7956 : * O(N^3) complexity
7957 : * matrix is represented by its upper or lower triangle
7958 : * no additional time consuming features like condition number estimation
7959 :
7960 : ! COMMERCIAL EDITION OF ALGLIB:
7961 : !
7962 : ! Commercial Edition of ALGLIB includes following important improvements
7963 : ! of this function:
7964 : ! * high-performance native backend with same C# interface (C# version)
7965 : ! * multithreading support (C++ and C# versions)
7966 : ! * hardware vendor (Intel) implementations of linear algebra primitives
7967 : ! (C++ and C# versions, x86/x64 platform)
7968 : !
7969 : ! We recommend you to read 'Working with commercial version' section of
7970 : ! ALGLIB Reference Manual in order to find out how to use performance-
7971 : ! related features provided by commercial edition of ALGLIB.
7972 :
7973 : INPUT PARAMETERS
7974 : A - array[0..N-1,0..N-1], system matrix
7975 : N - size of A
7976 : IsUpper - what half of A is provided
7977 : B - array[0..N-1], right part
7978 :
7979 : OUTPUT PARAMETERS
7980 : Info - return code:
7981 : * -3 A is is exactly singular or non-SPD
7982 : * -1 N<=0 was passed
7983 : * 1 task was solved
7984 : B - array[N], it contains:
7985 : * info>0 => solution
7986 : * info=-3 => filled by zeros
7987 :
7988 : -- ALGLIB --
7989 : Copyright 17.03.2015 by Bochkanov Sergey
7990 : *************************************************************************/
7991 0 : void spdmatrixsolvefast(/* Real */ ae_matrix* a,
7992 : ae_int_t n,
7993 : ae_bool isupper,
7994 : /* Real */ ae_vector* b,
7995 : ae_int_t* info,
7996 : ae_state *_state)
7997 : {
7998 : ae_frame _frame_block;
7999 : ae_matrix _a;
8000 : ae_int_t i;
8001 :
8002 0 : ae_frame_make(_state, &_frame_block);
8003 0 : memset(&_a, 0, sizeof(_a));
8004 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
8005 0 : a = &_a;
8006 0 : *info = 0;
8007 :
8008 0 : *info = 1;
8009 0 : if( n<=0 )
8010 : {
8011 0 : *info = -1;
8012 0 : ae_frame_leave(_state);
8013 0 : return;
8014 : }
8015 0 : if( !spdmatrixcholesky(a, n, isupper, _state) )
8016 : {
8017 0 : for(i=0; i<=n-1; i++)
8018 : {
8019 0 : b->ptr.p_double[i] = 0.0;
8020 : }
8021 0 : *info = -3;
8022 0 : ae_frame_leave(_state);
8023 0 : return;
8024 : }
8025 0 : directdensesolvers_spdbasiccholeskysolve(a, n, isupper, b, _state);
8026 0 : ae_frame_leave(_state);
8027 : }
8028 :
8029 :
8030 : /*************************************************************************
8031 : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
8032 : by its Cholesky decomposition, and N*M vectors X and B. It is "slow-but-
8033 : feature-rich" version of the solver which estimates condition number of
8034 : the system.
8035 :
8036 : Algorithm features:
8037 : * automatic detection of degenerate cases
8038 : * O(M*N^2) complexity
8039 : * condition number estimation
8040 : * matrix is represented by its upper or lower triangle
8041 :
8042 : No iterative refinement is provided because such partial representation of
8043 : matrix does not allow efficient calculation of extra-precise matrix-vector
8044 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8045 : need iterative refinement.
8046 :
8047 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8048 : ! by ALGLIB. It estimates condition number of linear system,
8049 : ! which results in significant performance penalty when
8050 : ! compared with "fast" version which just calls triangular
8051 : ! solver. Amount of overhead introduced depends on M (the
8052 : ! larger - the more efficient).
8053 : !
8054 : ! This performance penalty is insignificant when compared with
8055 : ! cost of large LU decomposition. However, if you call this
8056 : ! function many times for the same left side, this overhead
8057 : ! BECOMES significant. It also becomes significant for small-
8058 : ! scale problems (N<50).
8059 : !
8060 : ! In such cases we strongly recommend you to use faster solver,
8061 : ! SPDMatrixCholeskySolveMFast() function.
8062 :
8063 : INPUT PARAMETERS
8064 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
8065 : SPDMatrixCholesky result
8066 : N - size of CHA
8067 : IsUpper - what half of CHA is provided
8068 : B - array[0..N-1,0..M-1], right part
8069 : M - right part size
8070 :
8071 : OUTPUT PARAMETERS
8072 : Info - return code:
8073 : * -3 A is is exactly singular or badly conditioned
8074 : X is filled by zeros in such cases.
8075 : * -1 N<=0 was passed
8076 : * 1 task was solved
8077 : Rep - additional report, following fields are set:
8078 : * rep.r1 condition number in 1-norm
8079 : * rep.rinf condition number in inf-norm
8080 : X - array[N]:
8081 : * for info>0 contains solution
8082 : * for info=-3 filled by zeros
8083 :
8084 : -- ALGLIB --
8085 : Copyright 27.01.2010 by Bochkanov Sergey
8086 : *************************************************************************/
8087 0 : void spdmatrixcholeskysolvem(/* Real */ ae_matrix* cha,
8088 : ae_int_t n,
8089 : ae_bool isupper,
8090 : /* Real */ ae_matrix* b,
8091 : ae_int_t m,
8092 : ae_int_t* info,
8093 : densesolverreport* rep,
8094 : /* Real */ ae_matrix* x,
8095 : ae_state *_state)
8096 : {
8097 : ae_frame _frame_block;
8098 : ae_matrix emptya;
8099 :
8100 0 : ae_frame_make(_state, &_frame_block);
8101 0 : memset(&emptya, 0, sizeof(emptya));
8102 0 : *info = 0;
8103 0 : _densesolverreport_clear(rep);
8104 0 : ae_matrix_clear(x);
8105 0 : ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
8106 :
8107 :
8108 : /*
8109 : * prepare: check inputs, allocate space...
8110 : */
8111 0 : if( n<=0||m<=0 )
8112 : {
8113 0 : *info = -1;
8114 0 : ae_frame_leave(_state);
8115 0 : return;
8116 : }
8117 :
8118 : /*
8119 : * solve
8120 : */
8121 0 : directdensesolvers_spdmatrixcholeskysolveinternal(cha, n, isupper, &emptya, ae_false, b, m, info, rep, x, _state);
8122 0 : ae_frame_leave(_state);
8123 : }
8124 :
8125 :
8126 : /*************************************************************************
8127 : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
8128 : by its Cholesky decomposition, and N*M vectors X and B. It is "fast-but-
8129 : lightweight" version of the solver which just solves linear system,
8130 : without any additional functions.
8131 :
8132 : Algorithm features:
8133 : * O(M*N^2) complexity
8134 : * matrix is represented by its upper or lower triangle
8135 : * no additional functionality
8136 :
8137 : INPUT PARAMETERS
8138 : CHA - array[N,N], Cholesky decomposition,
8139 : SPDMatrixCholesky result
8140 : N - size of CHA
8141 : IsUpper - what half of CHA is provided
8142 : B - array[N,M], right part
8143 : M - right part size
8144 :
8145 : OUTPUT PARAMETERS
8146 : Info - return code:
8147 : * -3 A is is exactly singular or badly conditioned
8148 : X is filled by zeros in such cases.
8149 : * -1 N<=0 was passed
8150 : * 1 task was solved
8151 : B - array[N]:
8152 : * for info>0 overwritten by solution
8153 : * for info=-3 filled by zeros
8154 :
8155 : -- ALGLIB --
8156 : Copyright 18.03.2015 by Bochkanov Sergey
8157 : *************************************************************************/
8158 0 : void spdmatrixcholeskysolvemfast(/* Real */ ae_matrix* cha,
8159 : ae_int_t n,
8160 : ae_bool isupper,
8161 : /* Real */ ae_matrix* b,
8162 : ae_int_t m,
8163 : ae_int_t* info,
8164 : ae_state *_state)
8165 : {
8166 : ae_int_t i;
8167 : ae_int_t j;
8168 : ae_int_t k;
8169 :
8170 0 : *info = 0;
8171 :
8172 0 : *info = 1;
8173 0 : if( n<=0 )
8174 : {
8175 0 : *info = -1;
8176 0 : return;
8177 : }
8178 0 : for(k=0; k<=n-1; k++)
8179 : {
8180 0 : if( ae_fp_eq(cha->ptr.pp_double[k][k],0.0) )
8181 : {
8182 0 : for(i=0; i<=n-1; i++)
8183 : {
8184 0 : for(j=0; j<=m-1; j++)
8185 : {
8186 0 : b->ptr.pp_double[i][j] = 0.0;
8187 : }
8188 : }
8189 0 : *info = -3;
8190 0 : return;
8191 : }
8192 : }
8193 0 : if( isupper )
8194 : {
8195 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 1, b, 0, 0, _state);
8196 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
8197 : }
8198 : else
8199 : {
8200 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
8201 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 1, b, 0, 0, _state);
8202 : }
8203 : }
8204 :
8205 :
8206 : /*************************************************************************
8207 : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
8208 : by its Cholesky decomposition, and N*1 real vectors x and b. This is "slow-
8209 : but-feature-rich" version of the solver which, in addition to the
8210 : solution, performs condition number estimation.
8211 :
8212 : Algorithm features:
8213 : * automatic detection of degenerate cases
8214 : * O(N^2) complexity
8215 : * condition number estimation
8216 : * matrix is represented by its upper or lower triangle
8217 :
8218 : No iterative refinement is provided because such partial representation of
8219 : matrix does not allow efficient calculation of extra-precise matrix-vector
8220 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8221 : need iterative refinement.
8222 :
8223 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8224 : ! by ALGLIB. It estimates condition number of linear system,
8225 : ! which results in 10-15x performance penalty when compared
8226 : ! with "fast" version which just calls triangular solver.
8227 : !
8228 : ! This performance penalty is insignificant when compared with
8229 : ! cost of large LU decomposition. However, if you call this
8230 : ! function many times for the same left side, this overhead
8231 : ! BECOMES significant. It also becomes significant for small-
8232 : ! scale problems (N<50).
8233 : !
8234 : ! In such cases we strongly recommend you to use faster solver,
8235 : ! SPDMatrixCholeskySolveFast() function.
8236 :
8237 : INPUT PARAMETERS
8238 : CHA - array[N,N], Cholesky decomposition,
8239 : SPDMatrixCholesky result
8240 : N - size of A
8241 : IsUpper - what half of CHA is provided
8242 : B - array[N], right part
8243 :
8244 : OUTPUT PARAMETERS
8245 : Info - return code:
8246 : * -3 A is is exactly singular or ill conditioned
8247 : X is filled by zeros in such cases.
8248 : * -1 N<=0 was passed
8249 : * 1 task is solved
8250 : Rep - additional report, following fields are set:
8251 : * rep.r1 condition number in 1-norm
8252 : * rep.rinf condition number in inf-norm
8253 : X - array[N]:
8254 : * for info>0 - solution
8255 : * for info=-3 - filled by zeros
8256 :
8257 : -- ALGLIB --
8258 : Copyright 27.01.2010 by Bochkanov Sergey
8259 : *************************************************************************/
8260 0 : void spdmatrixcholeskysolve(/* Real */ ae_matrix* cha,
8261 : ae_int_t n,
8262 : ae_bool isupper,
8263 : /* Real */ ae_vector* b,
8264 : ae_int_t* info,
8265 : densesolverreport* rep,
8266 : /* Real */ ae_vector* x,
8267 : ae_state *_state)
8268 : {
8269 : ae_frame _frame_block;
8270 : ae_matrix bm;
8271 : ae_matrix xm;
8272 :
8273 0 : ae_frame_make(_state, &_frame_block);
8274 0 : memset(&bm, 0, sizeof(bm));
8275 0 : memset(&xm, 0, sizeof(xm));
8276 0 : *info = 0;
8277 0 : _densesolverreport_clear(rep);
8278 0 : ae_vector_clear(x);
8279 0 : ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
8280 0 : ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
8281 :
8282 0 : if( n<=0 )
8283 : {
8284 0 : *info = -1;
8285 0 : ae_frame_leave(_state);
8286 0 : return;
8287 : }
8288 0 : ae_matrix_set_length(&bm, n, 1, _state);
8289 0 : ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
8290 0 : spdmatrixcholeskysolvem(cha, n, isupper, &bm, 1, info, rep, &xm, _state);
8291 0 : ae_vector_set_length(x, n, _state);
8292 0 : ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
8293 0 : ae_frame_leave(_state);
8294 : }
8295 :
8296 :
8297 : /*************************************************************************
8298 : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
8299 : by its Cholesky decomposition, and N*1 real vectors x and b. This is "fast-
8300 : but-lightweight" version of the solver.
8301 :
8302 : Algorithm features:
8303 : * O(N^2) complexity
8304 : * matrix is represented by its upper or lower triangle
8305 : * no additional features
8306 :
8307 : INPUT PARAMETERS
8308 : CHA - array[N,N], Cholesky decomposition,
8309 : SPDMatrixCholesky result
8310 : N - size of A
8311 : IsUpper - what half of CHA is provided
8312 : B - array[N], right part
8313 :
8314 : OUTPUT PARAMETERS
8315 : Info - return code:
8316 : * -3 A is is exactly singular or ill conditioned
8317 : X is filled by zeros in such cases.
8318 : * -1 N<=0 was passed
8319 : * 1 task is solved
8320 : B - array[N]:
8321 : * for info>0 - overwritten by solution
8322 : * for info=-3 - filled by zeros
8323 :
8324 : -- ALGLIB --
8325 : Copyright 27.01.2010 by Bochkanov Sergey
8326 : *************************************************************************/
8327 0 : void spdmatrixcholeskysolvefast(/* Real */ ae_matrix* cha,
8328 : ae_int_t n,
8329 : ae_bool isupper,
8330 : /* Real */ ae_vector* b,
8331 : ae_int_t* info,
8332 : ae_state *_state)
8333 : {
8334 : ae_int_t i;
8335 : ae_int_t k;
8336 :
8337 0 : *info = 0;
8338 :
8339 0 : *info = 1;
8340 0 : if( n<=0 )
8341 : {
8342 0 : *info = -1;
8343 0 : return;
8344 : }
8345 0 : for(k=0; k<=n-1; k++)
8346 : {
8347 0 : if( ae_fp_eq(cha->ptr.pp_double[k][k],0.0) )
8348 : {
8349 0 : for(i=0; i<=n-1; i++)
8350 : {
8351 0 : b->ptr.p_double[i] = 0.0;
8352 : }
8353 0 : *info = -3;
8354 0 : return;
8355 : }
8356 : }
8357 0 : directdensesolvers_spdbasiccholeskysolve(cha, n, isupper, b, _state);
8358 : }
8359 :
8360 :
8361 : /*************************************************************************
8362 : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and
8363 : N*M complex matrices X and B. "Slow-but-feature-rich" version of the
8364 : solver.
8365 :
8366 : Algorithm features:
8367 : * automatic detection of degenerate cases
8368 : * condition number estimation
8369 : * O(N^3+M*N^2) complexity
8370 : * matrix is represented by its upper or lower triangle
8371 :
8372 : No iterative refinement is provided because such partial representation of
8373 : matrix does not allow efficient calculation of extra-precise matrix-vector
8374 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8375 : need iterative refinement.
8376 :
8377 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8378 : ! by ALGLIB. It estimates condition number of linear system,
8379 : ! which results in significant performance penalty when
8380 : ! compared with "fast" version which just calls triangular
8381 : ! solver.
8382 : !
8383 : ! This performance penalty is especially apparent when you use
8384 : ! ALGLIB parallel capabilities (condition number estimation is
8385 : ! inherently sequential). It also becomes significant for
8386 : ! small-scale problems (N<100).
8387 : !
8388 : ! In such cases we strongly recommend you to use faster solver,
8389 : ! HPDMatrixSolveMFast() function.
8390 :
8391 : ! COMMERCIAL EDITION OF ALGLIB:
8392 : !
8393 : ! Commercial Edition of ALGLIB includes following important improvements
8394 : ! of this function:
8395 : ! * high-performance native backend with same C# interface (C# version)
8396 : ! * multithreading support (C++ and C# versions)
8397 : ! * hardware vendor (Intel) implementations of linear algebra primitives
8398 : ! (C++ and C# versions, x86/x64 platform)
8399 : !
8400 : ! We recommend you to read 'Working with commercial version' section of
8401 : ! ALGLIB Reference Manual in order to find out how to use performance-
8402 : ! related features provided by commercial edition of ALGLIB.
8403 :
8404 : INPUT PARAMETERS
8405 : A - array[0..N-1,0..N-1], system matrix
8406 : N - size of A
8407 : IsUpper - what half of A is provided
8408 : B - array[0..N-1,0..M-1], right part
8409 : M - right part size
8410 :
8411 : OUTPUT PARAMETERS
8412 : Info - same as in RMatrixSolve.
8413 : Returns -3 for non-HPD matrices.
8414 : Rep - same as in RMatrixSolve
8415 : X - same as in RMatrixSolve
8416 :
8417 : -- ALGLIB --
8418 : Copyright 27.01.2010 by Bochkanov Sergey
8419 : *************************************************************************/
8420 0 : void hpdmatrixsolvem(/* Complex */ ae_matrix* a,
8421 : ae_int_t n,
8422 : ae_bool isupper,
8423 : /* Complex */ ae_matrix* b,
8424 : ae_int_t m,
8425 : ae_int_t* info,
8426 : densesolverreport* rep,
8427 : /* Complex */ ae_matrix* x,
8428 : ae_state *_state)
8429 : {
8430 : ae_frame _frame_block;
8431 : ae_matrix da;
8432 : ae_int_t i;
8433 : ae_int_t j;
8434 : ae_int_t j1;
8435 : ae_int_t j2;
8436 :
8437 0 : ae_frame_make(_state, &_frame_block);
8438 0 : memset(&da, 0, sizeof(da));
8439 0 : *info = 0;
8440 0 : _densesolverreport_clear(rep);
8441 0 : ae_matrix_clear(x);
8442 0 : ae_matrix_init(&da, 0, 0, DT_COMPLEX, _state, ae_true);
8443 :
8444 :
8445 : /*
8446 : * prepare: check inputs, allocate space...
8447 : */
8448 0 : if( n<=0||m<=0 )
8449 : {
8450 0 : *info = -1;
8451 0 : ae_frame_leave(_state);
8452 0 : return;
8453 : }
8454 0 : ae_matrix_set_length(&da, n, n, _state);
8455 :
8456 : /*
8457 : * factorize matrix, solve
8458 : */
8459 0 : for(i=0; i<=n-1; i++)
8460 : {
8461 0 : if( isupper )
8462 : {
8463 0 : j1 = i;
8464 0 : j2 = n-1;
8465 : }
8466 : else
8467 : {
8468 0 : j1 = 0;
8469 0 : j2 = i;
8470 : }
8471 0 : ae_v_cmove(&da.ptr.pp_complex[i][j1], 1, &a->ptr.pp_complex[i][j1], 1, "N", ae_v_len(j1,j2));
8472 : }
8473 0 : if( !hpdmatrixcholesky(&da, n, isupper, _state) )
8474 : {
8475 0 : ae_matrix_set_length(x, n, m, _state);
8476 0 : for(i=0; i<=n-1; i++)
8477 : {
8478 0 : for(j=0; j<=m-1; j++)
8479 : {
8480 0 : x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
8481 : }
8482 : }
8483 0 : rep->r1 = (double)(0);
8484 0 : rep->rinf = (double)(0);
8485 0 : *info = -3;
8486 0 : ae_frame_leave(_state);
8487 0 : return;
8488 : }
8489 0 : *info = 1;
8490 0 : directdensesolvers_hpdmatrixcholeskysolveinternal(&da, n, isupper, a, ae_true, b, m, info, rep, x, _state);
8491 0 : ae_frame_leave(_state);
8492 : }
8493 :
8494 :
8495 : /*************************************************************************
8496 : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A and
8497 : N*M complex matrices X and B. "Fast-but-lightweight" version of the solver.
8498 :
8499 : Algorithm features:
8500 : * O(N^3+M*N^2) complexity
8501 : * matrix is represented by its upper or lower triangle
8502 : * no additional time consuming features like condition number estimation
8503 :
8504 : ! COMMERCIAL EDITION OF ALGLIB:
8505 : !
8506 : ! Commercial Edition of ALGLIB includes following important improvements
8507 : ! of this function:
8508 : ! * high-performance native backend with same C# interface (C# version)
8509 : ! * multithreading support (C++ and C# versions)
8510 : ! * hardware vendor (Intel) implementations of linear algebra primitives
8511 : ! (C++ and C# versions, x86/x64 platform)
8512 : !
8513 : ! We recommend you to read 'Working with commercial version' section of
8514 : ! ALGLIB Reference Manual in order to find out how to use performance-
8515 : ! related features provided by commercial edition of ALGLIB.
8516 :
8517 : INPUT PARAMETERS
8518 : A - array[0..N-1,0..N-1], system matrix
8519 : N - size of A
8520 : IsUpper - what half of A is provided
8521 : B - array[0..N-1,0..M-1], right part
8522 : M - right part size
8523 :
8524 : OUTPUT PARAMETERS
8525 : Info - return code:
8526 : * -3 A is is exactly singular or is not positive definite.
8527 : B is filled by zeros in such cases.
8528 : * -1 N<=0 was passed
8529 : * 1 task is solved
8530 : B - array[0..N-1]:
8531 : * overwritten by solution
8532 : * zeros, if problem was not solved
8533 :
8534 : -- ALGLIB --
8535 : Copyright 17.03.2015 by Bochkanov Sergey
8536 : *************************************************************************/
8537 0 : void hpdmatrixsolvemfast(/* Complex */ ae_matrix* a,
8538 : ae_int_t n,
8539 : ae_bool isupper,
8540 : /* Complex */ ae_matrix* b,
8541 : ae_int_t m,
8542 : ae_int_t* info,
8543 : ae_state *_state)
8544 : {
8545 : ae_frame _frame_block;
8546 : ae_matrix _a;
8547 : ae_int_t i;
8548 : ae_int_t j;
8549 :
8550 0 : ae_frame_make(_state, &_frame_block);
8551 0 : memset(&_a, 0, sizeof(_a));
8552 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
8553 0 : a = &_a;
8554 0 : *info = 0;
8555 :
8556 0 : *info = 1;
8557 0 : if( n<=0 )
8558 : {
8559 0 : *info = -1;
8560 0 : ae_frame_leave(_state);
8561 0 : return;
8562 : }
8563 0 : if( !hpdmatrixcholesky(a, n, isupper, _state) )
8564 : {
8565 0 : for(i=0; i<=n-1; i++)
8566 : {
8567 0 : for(j=0; j<=m-1; j++)
8568 : {
8569 0 : b->ptr.pp_complex[i][j] = ae_complex_from_d(0.0);
8570 : }
8571 : }
8572 0 : *info = -3;
8573 0 : ae_frame_leave(_state);
8574 0 : return;
8575 : }
8576 0 : if( isupper )
8577 : {
8578 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 2, b, 0, 0, _state);
8579 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
8580 : }
8581 : else
8582 : {
8583 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
8584 0 : cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 2, b, 0, 0, _state);
8585 : }
8586 0 : ae_frame_leave(_state);
8587 : }
8588 :
8589 :
8590 : /*************************************************************************
8591 : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
8592 : N*1 complex vectors x and b. "Slow-but-feature-rich" version of the
8593 : solver.
8594 :
8595 : Algorithm features:
8596 : * automatic detection of degenerate cases
8597 : * condition number estimation
8598 : * O(N^3) complexity
8599 : * matrix is represented by its upper or lower triangle
8600 :
8601 : No iterative refinement is provided because such partial representation of
8602 : matrix does not allow efficient calculation of extra-precise matrix-vector
8603 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8604 : need iterative refinement.
8605 :
8606 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8607 : ! by ALGLIB. It estimates condition number of linear system,
8608 : ! which results in significant performance penalty when
8609 : ! compared with "fast" version which just performs Cholesky
8610 : ! decomposition and calls triangular solver.
8611 : !
8612 : ! This performance penalty is especially visible in the
8613 : ! multithreaded mode, because both condition number estimation
8614 : ! and iterative refinement are inherently sequential
8615 : ! calculations.
8616 : !
8617 : ! Thus, if you need high performance and if you are pretty sure
8618 : ! that your system is well conditioned, we strongly recommend
8619 : ! you to use faster solver, HPDMatrixSolveFast() function.
8620 :
8621 : ! COMMERCIAL EDITION OF ALGLIB:
8622 : !
8623 : ! Commercial Edition of ALGLIB includes following important improvements
8624 : ! of this function:
8625 : ! * high-performance native backend with same C# interface (C# version)
8626 : ! * multithreading support (C++ and C# versions)
8627 : ! * hardware vendor (Intel) implementations of linear algebra primitives
8628 : ! (C++ and C# versions, x86/x64 platform)
8629 : !
8630 : ! We recommend you to read 'Working with commercial version' section of
8631 : ! ALGLIB Reference Manual in order to find out how to use performance-
8632 : ! related features provided by commercial edition of ALGLIB.
8633 :
8634 : INPUT PARAMETERS
8635 : A - array[0..N-1,0..N-1], system matrix
8636 : N - size of A
8637 : IsUpper - what half of A is provided
8638 : B - array[0..N-1], right part
8639 :
8640 : OUTPUT PARAMETERS
8641 : Info - same as in RMatrixSolve
8642 : Returns -3 for non-HPD matrices.
8643 : Rep - same as in RMatrixSolve
8644 : X - same as in RMatrixSolve
8645 :
8646 : -- ALGLIB --
8647 : Copyright 27.01.2010 by Bochkanov Sergey
8648 : *************************************************************************/
8649 0 : void hpdmatrixsolve(/* Complex */ ae_matrix* a,
8650 : ae_int_t n,
8651 : ae_bool isupper,
8652 : /* Complex */ ae_vector* b,
8653 : ae_int_t* info,
8654 : densesolverreport* rep,
8655 : /* Complex */ ae_vector* x,
8656 : ae_state *_state)
8657 : {
8658 : ae_frame _frame_block;
8659 : ae_matrix bm;
8660 : ae_matrix xm;
8661 :
8662 0 : ae_frame_make(_state, &_frame_block);
8663 0 : memset(&bm, 0, sizeof(bm));
8664 0 : memset(&xm, 0, sizeof(xm));
8665 0 : *info = 0;
8666 0 : _densesolverreport_clear(rep);
8667 0 : ae_vector_clear(x);
8668 0 : ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
8669 0 : ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
8670 :
8671 0 : if( n<=0 )
8672 : {
8673 0 : *info = -1;
8674 0 : ae_frame_leave(_state);
8675 0 : return;
8676 : }
8677 0 : ae_matrix_set_length(&bm, n, 1, _state);
8678 0 : ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
8679 0 : hpdmatrixsolvem(a, n, isupper, &bm, 1, info, rep, &xm, _state);
8680 0 : ae_vector_set_length(x, n, _state);
8681 0 : ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
8682 0 : ae_frame_leave(_state);
8683 : }
8684 :
8685 :
8686 : /*************************************************************************
8687 : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
8688 : N*1 complex vectors x and b. "Fast-but-lightweight" version of the
8689 : solver without additional functions.
8690 :
8691 : Algorithm features:
8692 : * O(N^3) complexity
8693 : * matrix is represented by its upper or lower triangle
8694 : * no additional time consuming functions
8695 :
8696 : ! COMMERCIAL EDITION OF ALGLIB:
8697 : !
8698 : ! Commercial Edition of ALGLIB includes following important improvements
8699 : ! of this function:
8700 : ! * high-performance native backend with same C# interface (C# version)
8701 : ! * multithreading support (C++ and C# versions)
8702 : ! * hardware vendor (Intel) implementations of linear algebra primitives
8703 : ! (C++ and C# versions, x86/x64 platform)
8704 : !
8705 : ! We recommend you to read 'Working with commercial version' section of
8706 : ! ALGLIB Reference Manual in order to find out how to use performance-
8707 : ! related features provided by commercial edition of ALGLIB.
8708 :
8709 : INPUT PARAMETERS
8710 : A - array[0..N-1,0..N-1], system matrix
8711 : N - size of A
8712 : IsUpper - what half of A is provided
8713 : B - array[0..N-1], right part
8714 :
8715 : OUTPUT PARAMETERS
8716 : Info - return code:
8717 : * -3 A is is exactly singular or not positive definite
8718 : X is filled by zeros in such cases.
8719 : * -1 N<=0 was passed
8720 : * 1 task was solved
8721 : B - array[0..N-1]:
8722 : * overwritten by solution
8723 : * zeros, if A is exactly singular (diagonal of its LU
8724 : decomposition has exact zeros).
8725 :
8726 : -- ALGLIB --
8727 : Copyright 17.03.2015 by Bochkanov Sergey
8728 : *************************************************************************/
8729 0 : void hpdmatrixsolvefast(/* Complex */ ae_matrix* a,
8730 : ae_int_t n,
8731 : ae_bool isupper,
8732 : /* Complex */ ae_vector* b,
8733 : ae_int_t* info,
8734 : ae_state *_state)
8735 : {
8736 : ae_frame _frame_block;
8737 : ae_matrix _a;
8738 : ae_int_t i;
8739 :
8740 0 : ae_frame_make(_state, &_frame_block);
8741 0 : memset(&_a, 0, sizeof(_a));
8742 0 : ae_matrix_init_copy(&_a, a, _state, ae_true);
8743 0 : a = &_a;
8744 0 : *info = 0;
8745 :
8746 0 : *info = 1;
8747 0 : if( n<=0 )
8748 : {
8749 0 : *info = -1;
8750 0 : ae_frame_leave(_state);
8751 0 : return;
8752 : }
8753 0 : if( !hpdmatrixcholesky(a, n, isupper, _state) )
8754 : {
8755 0 : for(i=0; i<=n-1; i++)
8756 : {
8757 0 : b->ptr.p_complex[i] = ae_complex_from_d(0.0);
8758 : }
8759 0 : *info = -3;
8760 0 : ae_frame_leave(_state);
8761 0 : return;
8762 : }
8763 0 : directdensesolvers_hpdbasiccholeskysolve(a, n, isupper, b, _state);
8764 0 : ae_frame_leave(_state);
8765 : }
8766 :
8767 :
8768 : /*************************************************************************
8769 : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
8770 : by its Cholesky decomposition and N*M complex matrices X and B. This is
8771 : "slow-but-feature-rich" version of the solver which, in addition to the
8772 : solution, estimates condition number of the system.
8773 :
8774 : Algorithm features:
8775 : * automatic detection of degenerate cases
8776 : * O(M*N^2) complexity
8777 : * condition number estimation
8778 : * matrix is represented by its upper or lower triangle
8779 :
8780 : No iterative refinement is provided because such partial representation of
8781 : matrix does not allow efficient calculation of extra-precise matrix-vector
8782 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8783 : need iterative refinement.
8784 :
8785 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8786 : ! by ALGLIB. It estimates condition number of linear system,
8787 : ! which results in significant performance penalty when
8788 : ! compared with "fast" version which just calls triangular
8789 : ! solver. Amount of overhead introduced depends on M (the
8790 : ! larger - the more efficient).
8791 : !
8792 : ! This performance penalty is insignificant when compared with
8793 : ! cost of large Cholesky decomposition. However, if you call
8794 : ! this function many times for the same left side, this
8795 : ! overhead BECOMES significant. It also becomes significant
8796 : ! for small-scale problems (N<50).
8797 : !
8798 : ! In such cases we strongly recommend you to use faster solver,
8799 : ! HPDMatrixCholeskySolveMFast() function.
8800 :
8801 :
8802 : INPUT PARAMETERS
8803 : CHA - array[N,N], Cholesky decomposition,
8804 : HPDMatrixCholesky result
8805 : N - size of CHA
8806 : IsUpper - what half of CHA is provided
8807 : B - array[N,M], right part
8808 : M - right part size
8809 :
8810 : OUTPUT PARAMETERS:
8811 : Info - return code:
8812 : * -3 A is singular, or VERY close to singular.
8813 : X is filled by zeros in such cases.
8814 : * -1 N<=0 was passed
8815 : * 1 task was solved
8816 : Rep - additional report, following fields are set:
8817 : * rep.r1 condition number in 1-norm
8818 : * rep.rinf condition number in inf-norm
8819 : X - array[N]:
8820 : * for info>0 contains solution
8821 : * for info=-3 filled by zeros
8822 :
8823 : -- ALGLIB --
8824 : Copyright 27.01.2010 by Bochkanov Sergey
8825 : *************************************************************************/
8826 0 : void hpdmatrixcholeskysolvem(/* Complex */ ae_matrix* cha,
8827 : ae_int_t n,
8828 : ae_bool isupper,
8829 : /* Complex */ ae_matrix* b,
8830 : ae_int_t m,
8831 : ae_int_t* info,
8832 : densesolverreport* rep,
8833 : /* Complex */ ae_matrix* x,
8834 : ae_state *_state)
8835 : {
8836 : ae_frame _frame_block;
8837 : ae_matrix emptya;
8838 :
8839 0 : ae_frame_make(_state, &_frame_block);
8840 0 : memset(&emptya, 0, sizeof(emptya));
8841 0 : *info = 0;
8842 0 : _densesolverreport_clear(rep);
8843 0 : ae_matrix_clear(x);
8844 0 : ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
8845 :
8846 :
8847 : /*
8848 : * prepare: check inputs, allocate space...
8849 : */
8850 0 : if( n<=0||m<=0 )
8851 : {
8852 0 : *info = -1;
8853 0 : ae_frame_leave(_state);
8854 0 : return;
8855 : }
8856 :
8857 : /*
8858 : * 1. scale matrix, max(|U[i,j]|)
8859 : * 2. factorize scaled matrix
8860 : * 3. solve
8861 : */
8862 0 : directdensesolvers_hpdmatrixcholeskysolveinternal(cha, n, isupper, &emptya, ae_false, b, m, info, rep, x, _state);
8863 0 : ae_frame_leave(_state);
8864 : }
8865 :
8866 :
8867 : /*************************************************************************
8868 : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
8869 : by its Cholesky decomposition and N*M complex matrices X and B. This is
8870 : "fast-but-lightweight" version of the solver.
8871 :
8872 : Algorithm features:
8873 : * O(M*N^2) complexity
8874 : * matrix is represented by its upper or lower triangle
8875 : * no additional time-consuming features
8876 :
8877 : INPUT PARAMETERS
8878 : CHA - array[N,N], Cholesky decomposition,
8879 : HPDMatrixCholesky result
8880 : N - size of CHA
8881 : IsUpper - what half of CHA is provided
8882 : B - array[N,M], right part
8883 : M - right part size
8884 :
8885 : OUTPUT PARAMETERS:
8886 : Info - return code:
8887 : * -3 A is singular, or VERY close to singular.
8888 : X is filled by zeros in such cases.
8889 : * -1 N<=0 was passed
8890 : * 1 task was solved
8891 : B - array[N]:
8892 : * for info>0 overwritten by solution
8893 : * for info=-3 filled by zeros
8894 :
8895 : -- ALGLIB --
8896 : Copyright 18.03.2015 by Bochkanov Sergey
8897 : *************************************************************************/
8898 0 : void hpdmatrixcholeskysolvemfast(/* Complex */ ae_matrix* cha,
8899 : ae_int_t n,
8900 : ae_bool isupper,
8901 : /* Complex */ ae_matrix* b,
8902 : ae_int_t m,
8903 : ae_int_t* info,
8904 : ae_state *_state)
8905 : {
8906 : ae_int_t i;
8907 : ae_int_t j;
8908 : ae_int_t k;
8909 :
8910 0 : *info = 0;
8911 :
8912 0 : *info = 1;
8913 0 : if( n<=0 )
8914 : {
8915 0 : *info = -1;
8916 0 : return;
8917 : }
8918 0 : for(k=0; k<=n-1; k++)
8919 : {
8920 0 : if( ae_fp_eq(cha->ptr.pp_complex[k][k].x,0.0)&&ae_fp_eq(cha->ptr.pp_complex[k][k].y,0.0) )
8921 : {
8922 0 : for(i=0; i<=n-1; i++)
8923 : {
8924 0 : for(j=0; j<=m-1; j++)
8925 : {
8926 0 : b->ptr.pp_complex[i][j] = ae_complex_from_d(0.0);
8927 : }
8928 : }
8929 0 : *info = -3;
8930 0 : return;
8931 : }
8932 : }
8933 0 : if( isupper )
8934 : {
8935 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 2, b, 0, 0, _state);
8936 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
8937 : }
8938 : else
8939 : {
8940 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
8941 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 2, b, 0, 0, _state);
8942 : }
8943 : }
8944 :
8945 :
8946 : /*************************************************************************
8947 : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
8948 : by its Cholesky decomposition, and N*1 complex vectors x and b. This is
8949 : "slow-but-feature-rich" version of the solver which estimates condition
8950 : number of the system.
8951 :
8952 : Algorithm features:
8953 : * automatic detection of degenerate cases
8954 : * O(N^2) complexity
8955 : * condition number estimation
8956 : * matrix is represented by its upper or lower triangle
8957 :
8958 : No iterative refinement is provided because such partial representation of
8959 : matrix does not allow efficient calculation of extra-precise matrix-vector
8960 : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve if you
8961 : need iterative refinement.
8962 :
8963 : IMPORTANT: ! this function is NOT the most efficient linear solver provided
8964 : ! by ALGLIB. It estimates condition number of linear system,
8965 : ! which results in 10-15x performance penalty when compared
8966 : ! with "fast" version which just calls triangular solver.
8967 : !
8968 : ! This performance penalty is insignificant when compared with
8969 : ! cost of large LU decomposition. However, if you call this
8970 : ! function many times for the same left side, this overhead
8971 : ! BECOMES significant. It also becomes significant for small-
8972 : ! scale problems (N<50).
8973 : !
8974 : ! In such cases we strongly recommend you to use faster solver,
8975 : ! HPDMatrixCholeskySolveFast() function.
8976 :
8977 : INPUT PARAMETERS
8978 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
8979 : SPDMatrixCholesky result
8980 : N - size of A
8981 : IsUpper - what half of CHA is provided
8982 : B - array[0..N-1], right part
8983 :
8984 : OUTPUT PARAMETERS
8985 : Info - return code:
8986 : * -3 A is is exactly singular or ill conditioned
8987 : X is filled by zeros in such cases.
8988 : * -1 N<=0 was passed
8989 : * 1 task is solved
8990 : Rep - additional report, following fields are set:
8991 : * rep.r1 condition number in 1-norm
8992 : * rep.rinf condition number in inf-norm
8993 : X - array[N]:
8994 : * for info>0 - solution
8995 : * for info=-3 - filled by zeros
8996 :
8997 : -- ALGLIB --
8998 : Copyright 27.01.2010 by Bochkanov Sergey
8999 : *************************************************************************/
9000 0 : void hpdmatrixcholeskysolve(/* Complex */ ae_matrix* cha,
9001 : ae_int_t n,
9002 : ae_bool isupper,
9003 : /* Complex */ ae_vector* b,
9004 : ae_int_t* info,
9005 : densesolverreport* rep,
9006 : /* Complex */ ae_vector* x,
9007 : ae_state *_state)
9008 : {
9009 : ae_frame _frame_block;
9010 : ae_matrix bm;
9011 : ae_matrix xm;
9012 :
9013 0 : ae_frame_make(_state, &_frame_block);
9014 0 : memset(&bm, 0, sizeof(bm));
9015 0 : memset(&xm, 0, sizeof(xm));
9016 0 : *info = 0;
9017 0 : _densesolverreport_clear(rep);
9018 0 : ae_vector_clear(x);
9019 0 : ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
9020 0 : ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
9021 :
9022 0 : if( n<=0 )
9023 : {
9024 0 : *info = -1;
9025 0 : ae_frame_leave(_state);
9026 0 : return;
9027 : }
9028 0 : ae_matrix_set_length(&bm, n, 1, _state);
9029 0 : ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
9030 0 : hpdmatrixcholeskysolvem(cha, n, isupper, &bm, 1, info, rep, &xm, _state);
9031 0 : ae_vector_set_length(x, n, _state);
9032 0 : ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
9033 0 : ae_frame_leave(_state);
9034 : }
9035 :
9036 :
9037 : /*************************************************************************
9038 : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
9039 : by its Cholesky decomposition, and N*1 complex vectors x and b. This is
9040 : "fast-but-lightweight" version of the solver.
9041 :
9042 : Algorithm features:
9043 : * O(N^2) complexity
9044 : * matrix is represented by its upper or lower triangle
9045 : * no additional time-consuming features
9046 :
9047 : INPUT PARAMETERS
9048 : CHA - array[0..N-1,0..N-1], Cholesky decomposition,
9049 : SPDMatrixCholesky result
9050 : N - size of A
9051 : IsUpper - what half of CHA is provided
9052 : B - array[0..N-1], right part
9053 :
9054 : OUTPUT PARAMETERS
9055 : Info - return code:
9056 : * -3 A is is exactly singular or ill conditioned
9057 : B is filled by zeros in such cases.
9058 : * -1 N<=0 was passed
9059 : * 1 task is solved
9060 : B - array[N]:
9061 : * for info>0 - overwritten by solution
9062 : * for info=-3 - filled by zeros
9063 :
9064 : -- ALGLIB --
9065 : Copyright 18.03.2015 by Bochkanov Sergey
9066 : *************************************************************************/
9067 0 : void hpdmatrixcholeskysolvefast(/* Complex */ ae_matrix* cha,
9068 : ae_int_t n,
9069 : ae_bool isupper,
9070 : /* Complex */ ae_vector* b,
9071 : ae_int_t* info,
9072 : ae_state *_state)
9073 : {
9074 : ae_int_t i;
9075 : ae_int_t k;
9076 :
9077 0 : *info = 0;
9078 :
9079 0 : *info = 1;
9080 0 : if( n<=0 )
9081 : {
9082 0 : *info = -1;
9083 0 : return;
9084 : }
9085 0 : for(k=0; k<=n-1; k++)
9086 : {
9087 0 : if( ae_fp_eq(cha->ptr.pp_complex[k][k].x,0.0)&&ae_fp_eq(cha->ptr.pp_complex[k][k].y,0.0) )
9088 : {
9089 0 : for(i=0; i<=n-1; i++)
9090 : {
9091 0 : b->ptr.p_complex[i] = ae_complex_from_d(0.0);
9092 : }
9093 0 : *info = -3;
9094 0 : return;
9095 : }
9096 : }
9097 0 : directdensesolvers_hpdbasiccholeskysolve(cha, n, isupper, b, _state);
9098 : }
9099 :
9100 :
9101 : /*************************************************************************
9102 : Dense solver.
9103 :
9104 : This subroutine finds solution of the linear system A*X=B with non-square,
9105 : possibly degenerate A. System is solved in the least squares sense, and
9106 : general least squares solution X = X0 + CX*y which minimizes |A*X-B| is
9107 : returned. If A is non-degenerate, solution in the usual sense is returned.
9108 :
9109 : Algorithm features:
9110 : * automatic detection (and correct handling!) of degenerate cases
9111 : * iterative refinement
9112 : * O(N^3) complexity
9113 :
9114 : ! COMMERCIAL EDITION OF ALGLIB:
9115 : !
9116 : ! Commercial Edition of ALGLIB includes following important improvements
9117 : ! of this function:
9118 : ! * high-performance native backend with same C# interface (C# version)
9119 : ! * multithreading support (C++ and C# versions)
9120 : ! * hardware vendor (Intel) implementations of linear algebra primitives
9121 : ! (C++ and C# versions, x86/x64 platform)
9122 : !
9123 : ! We recommend you to read 'Working with commercial version' section of
9124 : ! ALGLIB Reference Manual in order to find out how to use performance-
9125 : ! related features provided by commercial edition of ALGLIB.
9126 :
9127 : INPUT PARAMETERS
9128 : A - array[0..NRows-1,0..NCols-1], system matrix
9129 : NRows - vertical size of A
9130 : NCols - horizontal size of A
9131 : B - array[0..NCols-1], right part
9132 : Threshold- a number in [0,1]. Singular values beyond Threshold are
9133 : considered zero. Set it to 0.0, if you don't understand
9134 : what it means, so the solver will choose good value on its
9135 : own.
9136 :
9137 : OUTPUT PARAMETERS
9138 : Info - return code:
9139 : * -4 SVD subroutine failed
9140 : * -1 if NRows<=0 or NCols<=0 or Threshold<0 was passed
9141 : * 1 if task is solved
9142 : Rep - solver report, see below for more info
9143 : X - array[0..N-1,0..M-1], it contains:
9144 : * solution of A*X=B (even for singular A)
9145 : * zeros, if SVD subroutine failed
9146 :
9147 : SOLVER REPORT
9148 :
9149 : Subroutine sets following fields of the Rep structure:
9150 : * R2 reciprocal of condition number: 1/cond(A), 2-norm.
9151 : * N = NCols
9152 : * K dim(Null(A))
9153 : * CX array[0..N-1,0..K-1], kernel of A.
9154 : Columns of CX store such vectors that A*CX[i]=0.
9155 :
9156 : -- ALGLIB --
9157 : Copyright 24.08.2009 by Bochkanov Sergey
9158 : *************************************************************************/
9159 0 : void rmatrixsolvels(/* Real */ ae_matrix* a,
9160 : ae_int_t nrows,
9161 : ae_int_t ncols,
9162 : /* Real */ ae_vector* b,
9163 : double threshold,
9164 : ae_int_t* info,
9165 : densesolverlsreport* rep,
9166 : /* Real */ ae_vector* x,
9167 : ae_state *_state)
9168 : {
9169 : ae_frame _frame_block;
9170 : ae_vector sv;
9171 : ae_matrix u;
9172 : ae_matrix vt;
9173 : ae_vector rp;
9174 : ae_vector utb;
9175 : ae_vector sutb;
9176 : ae_vector tmp;
9177 : ae_vector ta;
9178 : ae_vector tx;
9179 : ae_vector buf;
9180 : ae_vector w;
9181 : ae_int_t i;
9182 : ae_int_t j;
9183 : ae_int_t nsv;
9184 : ae_int_t kernelidx;
9185 : double v;
9186 : double verr;
9187 : ae_bool svdfailed;
9188 : ae_bool zeroa;
9189 : ae_int_t rfs;
9190 : ae_int_t nrfs;
9191 : ae_bool terminatenexttime;
9192 : ae_bool smallerr;
9193 :
9194 0 : ae_frame_make(_state, &_frame_block);
9195 0 : memset(&sv, 0, sizeof(sv));
9196 0 : memset(&u, 0, sizeof(u));
9197 0 : memset(&vt, 0, sizeof(vt));
9198 0 : memset(&rp, 0, sizeof(rp));
9199 0 : memset(&utb, 0, sizeof(utb));
9200 0 : memset(&sutb, 0, sizeof(sutb));
9201 0 : memset(&tmp, 0, sizeof(tmp));
9202 0 : memset(&ta, 0, sizeof(ta));
9203 0 : memset(&tx, 0, sizeof(tx));
9204 0 : memset(&buf, 0, sizeof(buf));
9205 0 : memset(&w, 0, sizeof(w));
9206 0 : *info = 0;
9207 0 : _densesolverlsreport_clear(rep);
9208 0 : ae_vector_clear(x);
9209 0 : ae_vector_init(&sv, 0, DT_REAL, _state, ae_true);
9210 0 : ae_matrix_init(&u, 0, 0, DT_REAL, _state, ae_true);
9211 0 : ae_matrix_init(&vt, 0, 0, DT_REAL, _state, ae_true);
9212 0 : ae_vector_init(&rp, 0, DT_REAL, _state, ae_true);
9213 0 : ae_vector_init(&utb, 0, DT_REAL, _state, ae_true);
9214 0 : ae_vector_init(&sutb, 0, DT_REAL, _state, ae_true);
9215 0 : ae_vector_init(&tmp, 0, DT_REAL, _state, ae_true);
9216 0 : ae_vector_init(&ta, 0, DT_REAL, _state, ae_true);
9217 0 : ae_vector_init(&tx, 0, DT_REAL, _state, ae_true);
9218 0 : ae_vector_init(&buf, 0, DT_REAL, _state, ae_true);
9219 0 : ae_vector_init(&w, 0, DT_REAL, _state, ae_true);
9220 :
9221 0 : if( (nrows<=0||ncols<=0)||ae_fp_less(threshold,(double)(0)) )
9222 : {
9223 0 : *info = -1;
9224 0 : ae_frame_leave(_state);
9225 0 : return;
9226 : }
9227 0 : if( ae_fp_eq(threshold,(double)(0)) )
9228 : {
9229 0 : threshold = 1000*ae_machineepsilon;
9230 : }
9231 :
9232 : /*
9233 : * Factorize A first
9234 : */
9235 0 : svdfailed = !rmatrixsvd(a, nrows, ncols, 1, 2, 2, &sv, &u, &vt, _state);
9236 0 : zeroa = ae_fp_eq(sv.ptr.p_double[0],(double)(0));
9237 0 : if( svdfailed||zeroa )
9238 : {
9239 0 : if( svdfailed )
9240 : {
9241 0 : *info = -4;
9242 : }
9243 : else
9244 : {
9245 0 : *info = 1;
9246 : }
9247 0 : ae_vector_set_length(x, ncols, _state);
9248 0 : for(i=0; i<=ncols-1; i++)
9249 : {
9250 0 : x->ptr.p_double[i] = (double)(0);
9251 : }
9252 0 : rep->n = ncols;
9253 0 : rep->k = ncols;
9254 0 : ae_matrix_set_length(&rep->cx, ncols, ncols, _state);
9255 0 : for(i=0; i<=ncols-1; i++)
9256 : {
9257 0 : for(j=0; j<=ncols-1; j++)
9258 : {
9259 0 : if( i==j )
9260 : {
9261 0 : rep->cx.ptr.pp_double[i][j] = (double)(1);
9262 : }
9263 : else
9264 : {
9265 0 : rep->cx.ptr.pp_double[i][j] = (double)(0);
9266 : }
9267 : }
9268 : }
9269 0 : rep->r2 = (double)(0);
9270 0 : ae_frame_leave(_state);
9271 0 : return;
9272 : }
9273 0 : nsv = ae_minint(ncols, nrows, _state);
9274 0 : if( nsv==ncols )
9275 : {
9276 0 : rep->r2 = sv.ptr.p_double[nsv-1]/sv.ptr.p_double[0];
9277 : }
9278 : else
9279 : {
9280 0 : rep->r2 = (double)(0);
9281 : }
9282 0 : rep->n = ncols;
9283 0 : *info = 1;
9284 :
9285 : /*
9286 : * Iterative refinement of xc combined with solution:
9287 : * 1. xc = 0
9288 : * 2. calculate r = bc-A*xc using extra-precise dot product
9289 : * 3. solve A*y = r
9290 : * 4. update x:=x+r
9291 : * 5. goto 2
9292 : *
9293 : * This cycle is executed until one of two things happens:
9294 : * 1. maximum number of iterations reached
9295 : * 2. last iteration decreased error to the lower limit
9296 : */
9297 0 : ae_vector_set_length(&utb, nsv, _state);
9298 0 : ae_vector_set_length(&sutb, nsv, _state);
9299 0 : ae_vector_set_length(x, ncols, _state);
9300 0 : ae_vector_set_length(&tmp, ncols, _state);
9301 0 : ae_vector_set_length(&ta, ncols+1, _state);
9302 0 : ae_vector_set_length(&tx, ncols+1, _state);
9303 0 : ae_vector_set_length(&buf, ncols+1, _state);
9304 0 : for(i=0; i<=ncols-1; i++)
9305 : {
9306 0 : x->ptr.p_double[i] = (double)(0);
9307 : }
9308 0 : kernelidx = nsv;
9309 0 : for(i=0; i<=nsv-1; i++)
9310 : {
9311 0 : if( ae_fp_less_eq(sv.ptr.p_double[i],threshold*sv.ptr.p_double[0]) )
9312 : {
9313 0 : kernelidx = i;
9314 0 : break;
9315 : }
9316 : }
9317 0 : rep->k = ncols-kernelidx;
9318 0 : nrfs = directdensesolvers_densesolverrfsmaxv2(ncols, rep->r2, _state);
9319 0 : terminatenexttime = ae_false;
9320 0 : ae_vector_set_length(&rp, nrows, _state);
9321 0 : for(rfs=0; rfs<=nrfs; rfs++)
9322 : {
9323 0 : if( terminatenexttime )
9324 : {
9325 0 : break;
9326 : }
9327 :
9328 : /*
9329 : * calculate right part
9330 : */
9331 0 : if( rfs==0 )
9332 : {
9333 0 : ae_v_move(&rp.ptr.p_double[0], 1, &b->ptr.p_double[0], 1, ae_v_len(0,nrows-1));
9334 : }
9335 : else
9336 : {
9337 0 : smallerr = ae_true;
9338 0 : for(i=0; i<=nrows-1; i++)
9339 : {
9340 0 : ae_v_move(&ta.ptr.p_double[0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,ncols-1));
9341 0 : ta.ptr.p_double[ncols] = (double)(-1);
9342 0 : ae_v_move(&tx.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,ncols-1));
9343 0 : tx.ptr.p_double[ncols] = b->ptr.p_double[i];
9344 0 : xdot(&ta, &tx, ncols+1, &buf, &v, &verr, _state);
9345 0 : rp.ptr.p_double[i] = -v;
9346 0 : smallerr = smallerr&&ae_fp_less(ae_fabs(v, _state),4*verr);
9347 : }
9348 0 : if( smallerr )
9349 : {
9350 0 : terminatenexttime = ae_true;
9351 : }
9352 : }
9353 :
9354 : /*
9355 : * solve A*dx = rp
9356 : */
9357 0 : for(i=0; i<=ncols-1; i++)
9358 : {
9359 0 : tmp.ptr.p_double[i] = (double)(0);
9360 : }
9361 0 : for(i=0; i<=nsv-1; i++)
9362 : {
9363 0 : utb.ptr.p_double[i] = (double)(0);
9364 : }
9365 0 : for(i=0; i<=nrows-1; i++)
9366 : {
9367 0 : v = rp.ptr.p_double[i];
9368 0 : ae_v_addd(&utb.ptr.p_double[0], 1, &u.ptr.pp_double[i][0], 1, ae_v_len(0,nsv-1), v);
9369 : }
9370 0 : for(i=0; i<=nsv-1; i++)
9371 : {
9372 0 : if( i<kernelidx )
9373 : {
9374 0 : sutb.ptr.p_double[i] = utb.ptr.p_double[i]/sv.ptr.p_double[i];
9375 : }
9376 : else
9377 : {
9378 0 : sutb.ptr.p_double[i] = (double)(0);
9379 : }
9380 : }
9381 0 : for(i=0; i<=nsv-1; i++)
9382 : {
9383 0 : v = sutb.ptr.p_double[i];
9384 0 : ae_v_addd(&tmp.ptr.p_double[0], 1, &vt.ptr.pp_double[i][0], 1, ae_v_len(0,ncols-1), v);
9385 : }
9386 :
9387 : /*
9388 : * update x: x:=x+dx
9389 : */
9390 0 : ae_v_add(&x->ptr.p_double[0], 1, &tmp.ptr.p_double[0], 1, ae_v_len(0,ncols-1));
9391 : }
9392 :
9393 : /*
9394 : * fill CX
9395 : */
9396 0 : if( rep->k>0 )
9397 : {
9398 0 : ae_matrix_set_length(&rep->cx, ncols, rep->k, _state);
9399 0 : for(i=0; i<=rep->k-1; i++)
9400 : {
9401 0 : ae_v_move(&rep->cx.ptr.pp_double[0][i], rep->cx.stride, &vt.ptr.pp_double[kernelidx+i][0], 1, ae_v_len(0,ncols-1));
9402 : }
9403 : }
9404 0 : ae_frame_leave(_state);
9405 : }
9406 :
9407 :
9408 : /*************************************************************************
9409 : Internal LU solver
9410 :
9411 : -- ALGLIB --
9412 : Copyright 27.01.2010 by Bochkanov Sergey
9413 : *************************************************************************/
9414 0 : static void directdensesolvers_rmatrixlusolveinternal(/* Real */ ae_matrix* lua,
9415 : /* Integer */ ae_vector* p,
9416 : ae_int_t n,
9417 : /* Real */ ae_matrix* a,
9418 : ae_bool havea,
9419 : /* Real */ ae_matrix* b,
9420 : ae_int_t m,
9421 : ae_int_t* info,
9422 : densesolverreport* rep,
9423 : /* Real */ ae_matrix* x,
9424 : ae_state *_state)
9425 : {
9426 : ae_frame _frame_block;
9427 : ae_int_t i;
9428 : ae_int_t j;
9429 : ae_int_t k;
9430 : ae_int_t rfs;
9431 : ae_int_t nrfs;
9432 : ae_vector xc;
9433 : ae_vector y;
9434 : ae_vector bc;
9435 : ae_vector xa;
9436 : ae_vector xb;
9437 : ae_vector tx;
9438 : double v;
9439 : double verr;
9440 : double mxb;
9441 : ae_bool smallerr;
9442 : ae_bool terminatenexttime;
9443 :
9444 0 : ae_frame_make(_state, &_frame_block);
9445 0 : memset(&xc, 0, sizeof(xc));
9446 0 : memset(&y, 0, sizeof(y));
9447 0 : memset(&bc, 0, sizeof(bc));
9448 0 : memset(&xa, 0, sizeof(xa));
9449 0 : memset(&xb, 0, sizeof(xb));
9450 0 : memset(&tx, 0, sizeof(tx));
9451 0 : *info = 0;
9452 0 : _densesolverreport_clear(rep);
9453 0 : ae_matrix_clear(x);
9454 0 : ae_vector_init(&xc, 0, DT_REAL, _state, ae_true);
9455 0 : ae_vector_init(&y, 0, DT_REAL, _state, ae_true);
9456 0 : ae_vector_init(&bc, 0, DT_REAL, _state, ae_true);
9457 0 : ae_vector_init(&xa, 0, DT_REAL, _state, ae_true);
9458 0 : ae_vector_init(&xb, 0, DT_REAL, _state, ae_true);
9459 0 : ae_vector_init(&tx, 0, DT_REAL, _state, ae_true);
9460 :
9461 :
9462 : /*
9463 : * prepare: check inputs, allocate space...
9464 : */
9465 0 : if( n<=0||m<=0 )
9466 : {
9467 0 : *info = -1;
9468 0 : ae_frame_leave(_state);
9469 0 : return;
9470 : }
9471 0 : for(i=0; i<=n-1; i++)
9472 : {
9473 0 : if( p->ptr.p_int[i]>n-1||p->ptr.p_int[i]<i )
9474 : {
9475 0 : *info = -1;
9476 0 : ae_frame_leave(_state);
9477 0 : return;
9478 : }
9479 : }
9480 0 : ae_matrix_set_length(x, n, m, _state);
9481 0 : ae_vector_set_length(&y, n, _state);
9482 0 : ae_vector_set_length(&xc, n, _state);
9483 0 : ae_vector_set_length(&bc, n, _state);
9484 0 : ae_vector_set_length(&tx, n+1, _state);
9485 0 : ae_vector_set_length(&xa, n+1, _state);
9486 0 : ae_vector_set_length(&xb, n+1, _state);
9487 :
9488 : /*
9489 : * estimate condition number, test for near singularity
9490 : */
9491 0 : rep->r1 = rmatrixlurcond1(lua, n, _state);
9492 0 : rep->rinf = rmatrixlurcondinf(lua, n, _state);
9493 0 : if( ae_fp_less(rep->r1,rcondthreshold(_state))||ae_fp_less(rep->rinf,rcondthreshold(_state)) )
9494 : {
9495 0 : for(i=0; i<=n-1; i++)
9496 : {
9497 0 : for(j=0; j<=m-1; j++)
9498 : {
9499 0 : x->ptr.pp_double[i][j] = (double)(0);
9500 : }
9501 : }
9502 0 : rep->r1 = (double)(0);
9503 0 : rep->rinf = (double)(0);
9504 0 : *info = -3;
9505 0 : ae_frame_leave(_state);
9506 0 : return;
9507 : }
9508 0 : *info = 1;
9509 :
9510 : /*
9511 : * First stage of solution: rough solution with TRSM()
9512 : */
9513 0 : mxb = 0.0;
9514 0 : for(i=0; i<=n-1; i++)
9515 : {
9516 0 : for(j=0; j<=m-1; j++)
9517 : {
9518 0 : v = b->ptr.pp_double[i][j];
9519 0 : mxb = ae_maxreal(mxb, ae_fabs(v, _state), _state);
9520 0 : x->ptr.pp_double[i][j] = v;
9521 : }
9522 : }
9523 0 : for(i=0; i<=n-1; i++)
9524 : {
9525 0 : if( p->ptr.p_int[i]!=i )
9526 : {
9527 0 : for(j=0; j<=m-1; j++)
9528 : {
9529 0 : v = x->ptr.pp_double[i][j];
9530 0 : x->ptr.pp_double[i][j] = x->ptr.pp_double[p->ptr.p_int[i]][j];
9531 0 : x->ptr.pp_double[p->ptr.p_int[i]][j] = v;
9532 : }
9533 : }
9534 : }
9535 0 : rmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, x, 0, 0, _state);
9536 0 : rmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
9537 :
9538 : /*
9539 : * Second stage: iterative refinement
9540 : */
9541 0 : if( havea )
9542 : {
9543 0 : for(k=0; k<=m-1; k++)
9544 : {
9545 0 : nrfs = directdensesolvers_densesolverrfsmax(n, rep->r1, rep->rinf, _state);
9546 0 : terminatenexttime = ae_false;
9547 0 : for(rfs=0; rfs<=nrfs-1; rfs++)
9548 : {
9549 0 : if( terminatenexttime )
9550 : {
9551 0 : break;
9552 : }
9553 :
9554 : /*
9555 : * generate right part
9556 : */
9557 0 : smallerr = ae_true;
9558 0 : ae_v_move(&xb.ptr.p_double[0], 1, &x->ptr.pp_double[0][k], x->stride, ae_v_len(0,n-1));
9559 0 : for(i=0; i<=n-1; i++)
9560 : {
9561 0 : ae_v_move(&xa.ptr.p_double[0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,n-1));
9562 0 : xa.ptr.p_double[n] = (double)(-1);
9563 0 : xb.ptr.p_double[n] = b->ptr.pp_double[i][k];
9564 0 : xdot(&xa, &xb, n+1, &tx, &v, &verr, _state);
9565 0 : y.ptr.p_double[i] = -v;
9566 0 : smallerr = smallerr&&ae_fp_less(ae_fabs(v, _state),4*verr);
9567 : }
9568 0 : if( smallerr )
9569 : {
9570 0 : terminatenexttime = ae_true;
9571 : }
9572 :
9573 : /*
9574 : * solve and update
9575 : */
9576 0 : directdensesolvers_rbasiclusolve(lua, p, n, &y, _state);
9577 0 : ae_v_add(&x->ptr.pp_double[0][k], x->stride, &y.ptr.p_double[0], 1, ae_v_len(0,n-1));
9578 : }
9579 : }
9580 : }
9581 0 : ae_frame_leave(_state);
9582 : }
9583 :
9584 :
9585 : /*************************************************************************
9586 : Internal Cholesky solver
9587 :
9588 : -- ALGLIB --
9589 : Copyright 27.01.2010 by Bochkanov Sergey
9590 : *************************************************************************/
9591 0 : static void directdensesolvers_spdmatrixcholeskysolveinternal(/* Real */ ae_matrix* cha,
9592 : ae_int_t n,
9593 : ae_bool isupper,
9594 : /* Real */ ae_matrix* a,
9595 : ae_bool havea,
9596 : /* Real */ ae_matrix* b,
9597 : ae_int_t m,
9598 : ae_int_t* info,
9599 : densesolverreport* rep,
9600 : /* Real */ ae_matrix* x,
9601 : ae_state *_state)
9602 : {
9603 : ae_int_t i;
9604 : ae_int_t j;
9605 :
9606 0 : *info = 0;
9607 0 : _densesolverreport_clear(rep);
9608 0 : ae_matrix_clear(x);
9609 :
9610 :
9611 : /*
9612 : * prepare: check inputs, allocate space...
9613 : */
9614 0 : if( n<=0||m<=0 )
9615 : {
9616 0 : *info = -1;
9617 0 : return;
9618 : }
9619 0 : ae_matrix_set_length(x, n, m, _state);
9620 :
9621 : /*
9622 : * estimate condition number, test for near singularity
9623 : */
9624 0 : rep->r1 = spdmatrixcholeskyrcond(cha, n, isupper, _state);
9625 0 : rep->rinf = rep->r1;
9626 0 : if( ae_fp_less(rep->r1,rcondthreshold(_state)) )
9627 : {
9628 0 : for(i=0; i<=n-1; i++)
9629 : {
9630 0 : for(j=0; j<=m-1; j++)
9631 : {
9632 0 : x->ptr.pp_double[i][j] = (double)(0);
9633 : }
9634 : }
9635 0 : rep->r1 = (double)(0);
9636 0 : rep->rinf = (double)(0);
9637 0 : *info = -3;
9638 0 : return;
9639 : }
9640 0 : *info = 1;
9641 :
9642 : /*
9643 : * Solve with TRSM()
9644 : */
9645 0 : for(i=0; i<=n-1; i++)
9646 : {
9647 0 : for(j=0; j<=m-1; j++)
9648 : {
9649 0 : x->ptr.pp_double[i][j] = b->ptr.pp_double[i][j];
9650 : }
9651 : }
9652 0 : if( isupper )
9653 : {
9654 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 1, x, 0, 0, _state);
9655 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
9656 : }
9657 : else
9658 : {
9659 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, x, 0, 0, _state);
9660 0 : rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 1, x, 0, 0, _state);
9661 : }
9662 : }
9663 :
9664 :
9665 : /*************************************************************************
9666 : Internal LU solver
9667 :
9668 : -- ALGLIB --
9669 : Copyright 27.01.2010 by Bochkanov Sergey
9670 : *************************************************************************/
9671 0 : static void directdensesolvers_cmatrixlusolveinternal(/* Complex */ ae_matrix* lua,
9672 : /* Integer */ ae_vector* p,
9673 : ae_int_t n,
9674 : /* Complex */ ae_matrix* a,
9675 : ae_bool havea,
9676 : /* Complex */ ae_matrix* b,
9677 : ae_int_t m,
9678 : ae_int_t* info,
9679 : densesolverreport* rep,
9680 : /* Complex */ ae_matrix* x,
9681 : ae_state *_state)
9682 : {
9683 : ae_frame _frame_block;
9684 : ae_int_t i;
9685 : ae_int_t j;
9686 : ae_int_t k;
9687 : ae_int_t rfs;
9688 : ae_int_t nrfs;
9689 : ae_vector xc;
9690 : ae_vector y;
9691 : ae_vector bc;
9692 : ae_vector xa;
9693 : ae_vector xb;
9694 : ae_vector tx;
9695 : ae_vector tmpbuf;
9696 : ae_complex v;
9697 : double verr;
9698 : ae_bool smallerr;
9699 : ae_bool terminatenexttime;
9700 :
9701 0 : ae_frame_make(_state, &_frame_block);
9702 0 : memset(&xc, 0, sizeof(xc));
9703 0 : memset(&y, 0, sizeof(y));
9704 0 : memset(&bc, 0, sizeof(bc));
9705 0 : memset(&xa, 0, sizeof(xa));
9706 0 : memset(&xb, 0, sizeof(xb));
9707 0 : memset(&tx, 0, sizeof(tx));
9708 0 : memset(&tmpbuf, 0, sizeof(tmpbuf));
9709 0 : *info = 0;
9710 0 : _densesolverreport_clear(rep);
9711 0 : ae_matrix_clear(x);
9712 0 : ae_vector_init(&xc, 0, DT_COMPLEX, _state, ae_true);
9713 0 : ae_vector_init(&y, 0, DT_COMPLEX, _state, ae_true);
9714 0 : ae_vector_init(&bc, 0, DT_COMPLEX, _state, ae_true);
9715 0 : ae_vector_init(&xa, 0, DT_COMPLEX, _state, ae_true);
9716 0 : ae_vector_init(&xb, 0, DT_COMPLEX, _state, ae_true);
9717 0 : ae_vector_init(&tx, 0, DT_COMPLEX, _state, ae_true);
9718 0 : ae_vector_init(&tmpbuf, 0, DT_REAL, _state, ae_true);
9719 :
9720 :
9721 : /*
9722 : * prepare: check inputs, allocate space...
9723 : */
9724 0 : if( n<=0||m<=0 )
9725 : {
9726 0 : *info = -1;
9727 0 : ae_frame_leave(_state);
9728 0 : return;
9729 : }
9730 0 : for(i=0; i<=n-1; i++)
9731 : {
9732 0 : if( p->ptr.p_int[i]>n-1||p->ptr.p_int[i]<i )
9733 : {
9734 0 : *info = -1;
9735 0 : ae_frame_leave(_state);
9736 0 : return;
9737 : }
9738 : }
9739 0 : ae_matrix_set_length(x, n, m, _state);
9740 0 : ae_vector_set_length(&y, n, _state);
9741 0 : ae_vector_set_length(&xc, n, _state);
9742 0 : ae_vector_set_length(&bc, n, _state);
9743 0 : ae_vector_set_length(&tx, n, _state);
9744 0 : ae_vector_set_length(&xa, n+1, _state);
9745 0 : ae_vector_set_length(&xb, n+1, _state);
9746 0 : ae_vector_set_length(&tmpbuf, 2*n+2, _state);
9747 :
9748 : /*
9749 : * estimate condition number, test for near singularity
9750 : */
9751 0 : rep->r1 = cmatrixlurcond1(lua, n, _state);
9752 0 : rep->rinf = cmatrixlurcondinf(lua, n, _state);
9753 0 : if( ae_fp_less(rep->r1,rcondthreshold(_state))||ae_fp_less(rep->rinf,rcondthreshold(_state)) )
9754 : {
9755 0 : for(i=0; i<=n-1; i++)
9756 : {
9757 0 : for(j=0; j<=m-1; j++)
9758 : {
9759 0 : x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
9760 : }
9761 : }
9762 0 : rep->r1 = (double)(0);
9763 0 : rep->rinf = (double)(0);
9764 0 : *info = -3;
9765 0 : ae_frame_leave(_state);
9766 0 : return;
9767 : }
9768 0 : *info = 1;
9769 :
9770 : /*
9771 : * First phase: solve with TRSM()
9772 : */
9773 0 : for(i=0; i<=n-1; i++)
9774 : {
9775 0 : for(j=0; j<=m-1; j++)
9776 : {
9777 0 : x->ptr.pp_complex[i][j] = b->ptr.pp_complex[i][j];
9778 : }
9779 : }
9780 0 : for(i=0; i<=n-1; i++)
9781 : {
9782 0 : if( p->ptr.p_int[i]!=i )
9783 : {
9784 0 : for(j=0; j<=m-1; j++)
9785 : {
9786 0 : v = x->ptr.pp_complex[i][j];
9787 0 : x->ptr.pp_complex[i][j] = x->ptr.pp_complex[p->ptr.p_int[i]][j];
9788 0 : x->ptr.pp_complex[p->ptr.p_int[i]][j] = v;
9789 : }
9790 : }
9791 : }
9792 0 : cmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, x, 0, 0, _state);
9793 0 : cmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
9794 :
9795 : /*
9796 : * solve
9797 : */
9798 0 : for(k=0; k<=m-1; k++)
9799 : {
9800 0 : ae_v_cmove(&bc.ptr.p_complex[0], 1, &b->ptr.pp_complex[0][k], b->stride, "N", ae_v_len(0,n-1));
9801 0 : ae_v_cmove(&xc.ptr.p_complex[0], 1, &x->ptr.pp_complex[0][k], x->stride, "N", ae_v_len(0,n-1));
9802 :
9803 : /*
9804 : * Iterative refinement of xc:
9805 : * * calculate r = bc-A*xc using extra-precise dot product
9806 : * * solve A*y = r
9807 : * * update x:=x+r
9808 : *
9809 : * This cycle is executed until one of two things happens:
9810 : * 1. maximum number of iterations reached
9811 : * 2. last iteration decreased error to the lower limit
9812 : */
9813 0 : if( havea )
9814 : {
9815 0 : nrfs = directdensesolvers_densesolverrfsmax(n, rep->r1, rep->rinf, _state);
9816 0 : terminatenexttime = ae_false;
9817 0 : for(rfs=0; rfs<=nrfs-1; rfs++)
9818 : {
9819 0 : if( terminatenexttime )
9820 : {
9821 0 : break;
9822 : }
9823 :
9824 : /*
9825 : * generate right part
9826 : */
9827 0 : smallerr = ae_true;
9828 0 : ae_v_cmove(&xb.ptr.p_complex[0], 1, &xc.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
9829 0 : for(i=0; i<=n-1; i++)
9830 : {
9831 0 : ae_v_cmove(&xa.ptr.p_complex[0], 1, &a->ptr.pp_complex[i][0], 1, "N", ae_v_len(0,n-1));
9832 0 : xa.ptr.p_complex[n] = ae_complex_from_i(-1);
9833 0 : xb.ptr.p_complex[n] = bc.ptr.p_complex[i];
9834 0 : xcdot(&xa, &xb, n+1, &tmpbuf, &v, &verr, _state);
9835 0 : y.ptr.p_complex[i] = ae_c_neg(v);
9836 0 : smallerr = smallerr&&ae_fp_less(ae_c_abs(v, _state),4*verr);
9837 : }
9838 0 : if( smallerr )
9839 : {
9840 0 : terminatenexttime = ae_true;
9841 : }
9842 :
9843 : /*
9844 : * solve and update
9845 : */
9846 0 : directdensesolvers_cbasiclusolve(lua, p, n, &y, _state);
9847 0 : ae_v_cadd(&xc.ptr.p_complex[0], 1, &y.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
9848 : }
9849 : }
9850 :
9851 : /*
9852 : * Store xc.
9853 : * Post-scale result.
9854 : */
9855 0 : ae_v_cmove(&x->ptr.pp_complex[0][k], x->stride, &xc.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
9856 : }
9857 0 : ae_frame_leave(_state);
9858 : }
9859 :
9860 :
9861 : /*************************************************************************
9862 : Internal Cholesky solver
9863 :
9864 : -- ALGLIB --
9865 : Copyright 27.01.2010 by Bochkanov Sergey
9866 : *************************************************************************/
9867 0 : static void directdensesolvers_hpdmatrixcholeskysolveinternal(/* Complex */ ae_matrix* cha,
9868 : ae_int_t n,
9869 : ae_bool isupper,
9870 : /* Complex */ ae_matrix* a,
9871 : ae_bool havea,
9872 : /* Complex */ ae_matrix* b,
9873 : ae_int_t m,
9874 : ae_int_t* info,
9875 : densesolverreport* rep,
9876 : /* Complex */ ae_matrix* x,
9877 : ae_state *_state)
9878 : {
9879 : ae_frame _frame_block;
9880 : ae_int_t i;
9881 : ae_int_t j;
9882 : ae_vector xc;
9883 : ae_vector y;
9884 : ae_vector bc;
9885 : ae_vector xa;
9886 : ae_vector xb;
9887 : ae_vector tx;
9888 :
9889 0 : ae_frame_make(_state, &_frame_block);
9890 0 : memset(&xc, 0, sizeof(xc));
9891 0 : memset(&y, 0, sizeof(y));
9892 0 : memset(&bc, 0, sizeof(bc));
9893 0 : memset(&xa, 0, sizeof(xa));
9894 0 : memset(&xb, 0, sizeof(xb));
9895 0 : memset(&tx, 0, sizeof(tx));
9896 0 : *info = 0;
9897 0 : _densesolverreport_clear(rep);
9898 0 : ae_matrix_clear(x);
9899 0 : ae_vector_init(&xc, 0, DT_COMPLEX, _state, ae_true);
9900 0 : ae_vector_init(&y, 0, DT_COMPLEX, _state, ae_true);
9901 0 : ae_vector_init(&bc, 0, DT_COMPLEX, _state, ae_true);
9902 0 : ae_vector_init(&xa, 0, DT_COMPLEX, _state, ae_true);
9903 0 : ae_vector_init(&xb, 0, DT_COMPLEX, _state, ae_true);
9904 0 : ae_vector_init(&tx, 0, DT_COMPLEX, _state, ae_true);
9905 :
9906 :
9907 : /*
9908 : * prepare: check inputs, allocate space...
9909 : */
9910 0 : if( n<=0||m<=0 )
9911 : {
9912 0 : *info = -1;
9913 0 : ae_frame_leave(_state);
9914 0 : return;
9915 : }
9916 0 : ae_matrix_set_length(x, n, m, _state);
9917 0 : ae_vector_set_length(&y, n, _state);
9918 0 : ae_vector_set_length(&xc, n, _state);
9919 0 : ae_vector_set_length(&bc, n, _state);
9920 0 : ae_vector_set_length(&tx, n+1, _state);
9921 0 : ae_vector_set_length(&xa, n+1, _state);
9922 0 : ae_vector_set_length(&xb, n+1, _state);
9923 :
9924 : /*
9925 : * estimate condition number, test for near singularity
9926 : */
9927 0 : rep->r1 = hpdmatrixcholeskyrcond(cha, n, isupper, _state);
9928 0 : rep->rinf = rep->r1;
9929 0 : if( ae_fp_less(rep->r1,rcondthreshold(_state)) )
9930 : {
9931 0 : for(i=0; i<=n-1; i++)
9932 : {
9933 0 : for(j=0; j<=m-1; j++)
9934 : {
9935 0 : x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
9936 : }
9937 : }
9938 0 : rep->r1 = (double)(0);
9939 0 : rep->rinf = (double)(0);
9940 0 : *info = -3;
9941 0 : ae_frame_leave(_state);
9942 0 : return;
9943 : }
9944 0 : *info = 1;
9945 :
9946 : /*
9947 : * solve
9948 : */
9949 0 : for(i=0; i<=n-1; i++)
9950 : {
9951 0 : for(j=0; j<=m-1; j++)
9952 : {
9953 0 : x->ptr.pp_complex[i][j] = b->ptr.pp_complex[i][j];
9954 : }
9955 : }
9956 0 : if( isupper )
9957 : {
9958 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 2, x, 0, 0, _state);
9959 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
9960 : }
9961 : else
9962 : {
9963 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, x, 0, 0, _state);
9964 0 : cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 2, x, 0, 0, _state);
9965 : }
9966 0 : ae_frame_leave(_state);
9967 : }
9968 :
9969 :
9970 : /*************************************************************************
9971 : Internal subroutine.
9972 : Returns maximum count of RFS iterations as function of:
9973 : 1. machine epsilon
9974 : 2. task size.
9975 : 3. condition number
9976 :
9977 : -- ALGLIB --
9978 : Copyright 27.01.2010 by Bochkanov Sergey
9979 : *************************************************************************/
9980 0 : static ae_int_t directdensesolvers_densesolverrfsmax(ae_int_t n,
9981 : double r1,
9982 : double rinf,
9983 : ae_state *_state)
9984 : {
9985 : ae_int_t result;
9986 :
9987 :
9988 0 : result = 5;
9989 0 : return result;
9990 : }
9991 :
9992 :
9993 : /*************************************************************************
9994 : Internal subroutine.
9995 : Returns maximum count of RFS iterations as function of:
9996 : 1. machine epsilon
9997 : 2. task size.
9998 : 3. norm-2 condition number
9999 :
10000 : -- ALGLIB --
10001 : Copyright 27.01.2010 by Bochkanov Sergey
10002 : *************************************************************************/
10003 0 : static ae_int_t directdensesolvers_densesolverrfsmaxv2(ae_int_t n,
10004 : double r2,
10005 : ae_state *_state)
10006 : {
10007 : ae_int_t result;
10008 :
10009 :
10010 0 : result = directdensesolvers_densesolverrfsmax(n, (double)(0), (double)(0), _state);
10011 0 : return result;
10012 : }
10013 :
10014 :
10015 : /*************************************************************************
10016 : Basic LU solver for PLU*x = y.
10017 :
10018 : This subroutine assumes that:
10019 : * A=PLU is well-conditioned, so no zero divisions or overflow may occur
10020 :
10021 : -- ALGLIB --
10022 : Copyright 27.01.2010 by Bochkanov Sergey
10023 : *************************************************************************/
10024 0 : static void directdensesolvers_rbasiclusolve(/* Real */ ae_matrix* lua,
10025 : /* Integer */ ae_vector* p,
10026 : ae_int_t n,
10027 : /* Real */ ae_vector* xb,
10028 : ae_state *_state)
10029 : {
10030 : ae_int_t i;
10031 : double v;
10032 :
10033 :
10034 0 : for(i=0; i<=n-1; i++)
10035 : {
10036 0 : if( p->ptr.p_int[i]!=i )
10037 : {
10038 0 : v = xb->ptr.p_double[i];
10039 0 : xb->ptr.p_double[i] = xb->ptr.p_double[p->ptr.p_int[i]];
10040 0 : xb->ptr.p_double[p->ptr.p_int[i]] = v;
10041 : }
10042 : }
10043 0 : for(i=1; i<=n-1; i++)
10044 : {
10045 0 : v = ae_v_dotproduct(&lua->ptr.pp_double[i][0], 1, &xb->ptr.p_double[0], 1, ae_v_len(0,i-1));
10046 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
10047 : }
10048 0 : xb->ptr.p_double[n-1] = xb->ptr.p_double[n-1]/lua->ptr.pp_double[n-1][n-1];
10049 0 : for(i=n-2; i>=0; i--)
10050 : {
10051 0 : v = ae_v_dotproduct(&lua->ptr.pp_double[i][i+1], 1, &xb->ptr.p_double[i+1], 1, ae_v_len(i+1,n-1));
10052 0 : xb->ptr.p_double[i] = (xb->ptr.p_double[i]-v)/lua->ptr.pp_double[i][i];
10053 : }
10054 0 : }
10055 :
10056 :
10057 : /*************************************************************************
10058 : Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
10059 :
10060 : This subroutine assumes that:
10061 : * A*ScaleA is well scaled
10062 : * A is well-conditioned, so no zero divisions or overflow may occur
10063 :
10064 : -- ALGLIB --
10065 : Copyright 27.01.2010 by Bochkanov Sergey
10066 : *************************************************************************/
10067 0 : static void directdensesolvers_spdbasiccholeskysolve(/* Real */ ae_matrix* cha,
10068 : ae_int_t n,
10069 : ae_bool isupper,
10070 : /* Real */ ae_vector* xb,
10071 : ae_state *_state)
10072 : {
10073 : ae_int_t i;
10074 : double v;
10075 :
10076 :
10077 :
10078 : /*
10079 : * A = L*L' or A=U'*U
10080 : */
10081 0 : if( isupper )
10082 : {
10083 :
10084 : /*
10085 : * Solve U'*y=b first.
10086 : */
10087 0 : for(i=0; i<=n-1; i++)
10088 : {
10089 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
10090 0 : if( i<n-1 )
10091 : {
10092 0 : v = xb->ptr.p_double[i];
10093 0 : ae_v_subd(&xb->ptr.p_double[i+1], 1, &cha->ptr.pp_double[i][i+1], 1, ae_v_len(i+1,n-1), v);
10094 : }
10095 : }
10096 :
10097 : /*
10098 : * Solve U*x=y then.
10099 : */
10100 0 : for(i=n-1; i>=0; i--)
10101 : {
10102 0 : if( i<n-1 )
10103 : {
10104 0 : v = ae_v_dotproduct(&cha->ptr.pp_double[i][i+1], 1, &xb->ptr.p_double[i+1], 1, ae_v_len(i+1,n-1));
10105 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
10106 : }
10107 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
10108 : }
10109 : }
10110 : else
10111 : {
10112 :
10113 : /*
10114 : * Solve L*y=b first
10115 : */
10116 0 : for(i=0; i<=n-1; i++)
10117 : {
10118 0 : if( i>0 )
10119 : {
10120 0 : v = ae_v_dotproduct(&cha->ptr.pp_double[i][0], 1, &xb->ptr.p_double[0], 1, ae_v_len(0,i-1));
10121 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
10122 : }
10123 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
10124 : }
10125 :
10126 : /*
10127 : * Solve L'*x=y then.
10128 : */
10129 0 : for(i=n-1; i>=0; i--)
10130 : {
10131 0 : xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
10132 0 : if( i>0 )
10133 : {
10134 0 : v = xb->ptr.p_double[i];
10135 0 : ae_v_subd(&xb->ptr.p_double[0], 1, &cha->ptr.pp_double[i][0], 1, ae_v_len(0,i-1), v);
10136 : }
10137 : }
10138 : }
10139 0 : }
10140 :
10141 :
10142 : /*************************************************************************
10143 : Basic LU solver for ScaleA*PLU*x = y.
10144 :
10145 : This subroutine assumes that:
10146 : * L is well-scaled, and it is U which needs scaling by ScaleA.
10147 : * A=PLU is well-conditioned, so no zero divisions or overflow may occur
10148 :
10149 : -- ALGLIB --
10150 : Copyright 27.01.2010 by Bochkanov Sergey
10151 : *************************************************************************/
10152 0 : static void directdensesolvers_cbasiclusolve(/* Complex */ ae_matrix* lua,
10153 : /* Integer */ ae_vector* p,
10154 : ae_int_t n,
10155 : /* Complex */ ae_vector* xb,
10156 : ae_state *_state)
10157 : {
10158 : ae_int_t i;
10159 : ae_complex v;
10160 :
10161 :
10162 0 : for(i=0; i<=n-1; i++)
10163 : {
10164 0 : if( p->ptr.p_int[i]!=i )
10165 : {
10166 0 : v = xb->ptr.p_complex[i];
10167 0 : xb->ptr.p_complex[i] = xb->ptr.p_complex[p->ptr.p_int[i]];
10168 0 : xb->ptr.p_complex[p->ptr.p_int[i]] = v;
10169 : }
10170 : }
10171 0 : for(i=1; i<=n-1; i++)
10172 : {
10173 0 : v = ae_v_cdotproduct(&lua->ptr.pp_complex[i][0], 1, "N", &xb->ptr.p_complex[0], 1, "N", ae_v_len(0,i-1));
10174 0 : xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
10175 : }
10176 0 : xb->ptr.p_complex[n-1] = ae_c_div(xb->ptr.p_complex[n-1],lua->ptr.pp_complex[n-1][n-1]);
10177 0 : for(i=n-2; i>=0; i--)
10178 : {
10179 0 : v = ae_v_cdotproduct(&lua->ptr.pp_complex[i][i+1], 1, "N", &xb->ptr.p_complex[i+1], 1, "N", ae_v_len(i+1,n-1));
10180 0 : xb->ptr.p_complex[i] = ae_c_div(ae_c_sub(xb->ptr.p_complex[i],v),lua->ptr.pp_complex[i][i]);
10181 : }
10182 0 : }
10183 :
10184 :
10185 : /*************************************************************************
10186 : Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
10187 :
10188 : This subroutine assumes that:
10189 : * A*ScaleA is well scaled
10190 : * A is well-conditioned, so no zero divisions or overflow may occur
10191 :
10192 : -- ALGLIB --
10193 : Copyright 27.01.2010 by Bochkanov Sergey
10194 : *************************************************************************/
10195 0 : static void directdensesolvers_hpdbasiccholeskysolve(/* Complex */ ae_matrix* cha,
10196 : ae_int_t n,
10197 : ae_bool isupper,
10198 : /* Complex */ ae_vector* xb,
10199 : ae_state *_state)
10200 : {
10201 : ae_int_t i;
10202 : ae_complex v;
10203 :
10204 :
10205 :
10206 : /*
10207 : * A = L*L' or A=U'*U
10208 : */
10209 0 : if( isupper )
10210 : {
10211 :
10212 : /*
10213 : * Solve U'*y=b first.
10214 : */
10215 0 : for(i=0; i<=n-1; i++)
10216 : {
10217 0 : xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],ae_c_conj(cha->ptr.pp_complex[i][i], _state));
10218 0 : if( i<n-1 )
10219 : {
10220 0 : v = xb->ptr.p_complex[i];
10221 0 : ae_v_csubc(&xb->ptr.p_complex[i+1], 1, &cha->ptr.pp_complex[i][i+1], 1, "Conj", ae_v_len(i+1,n-1), v);
10222 : }
10223 : }
10224 :
10225 : /*
10226 : * Solve U*x=y then.
10227 : */
10228 0 : for(i=n-1; i>=0; i--)
10229 : {
10230 0 : if( i<n-1 )
10231 : {
10232 0 : v = ae_v_cdotproduct(&cha->ptr.pp_complex[i][i+1], 1, "N", &xb->ptr.p_complex[i+1], 1, "N", ae_v_len(i+1,n-1));
10233 0 : xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
10234 : }
10235 0 : xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],cha->ptr.pp_complex[i][i]);
10236 : }
10237 : }
10238 : else
10239 : {
10240 :
10241 : /*
10242 : * Solve L*y=b first
10243 : */
10244 0 : for(i=0; i<=n-1; i++)
10245 : {
10246 0 : if( i>0 )
10247 : {
10248 0 : v = ae_v_cdotproduct(&cha->ptr.pp_complex[i][0], 1, "N", &xb->ptr.p_complex[0], 1, "N", ae_v_len(0,i-1));
10249 0 : xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
10250 : }
10251 0 : xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],cha->ptr.pp_complex[i][i]);
10252 : }
10253 :
10254 : /*
10255 : * Solve L'*x=y then.
10256 : */
10257 0 : for(i=n-1; i>=0; i--)
10258 : {
10259 0 : xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],ae_c_conj(cha->ptr.pp_complex[i][i], _state));
10260 0 : if( i>0 )
10261 : {
10262 0 : v = xb->ptr.p_complex[i];
10263 0 : ae_v_csubc(&xb->ptr.p_complex[0], 1, &cha->ptr.pp_complex[i][0], 1, "Conj", ae_v_len(0,i-1), v);
10264 : }
10265 : }
10266 : }
10267 0 : }
10268 :
10269 :
10270 0 : void _densesolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
10271 : {
10272 0 : densesolverreport *p = (densesolverreport*)_p;
10273 0 : ae_touch_ptr((void*)p);
10274 0 : }
10275 :
10276 :
10277 0 : void _densesolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
10278 : {
10279 0 : densesolverreport *dst = (densesolverreport*)_dst;
10280 0 : densesolverreport *src = (densesolverreport*)_src;
10281 0 : dst->r1 = src->r1;
10282 0 : dst->rinf = src->rinf;
10283 0 : }
10284 :
10285 :
10286 0 : void _densesolverreport_clear(void* _p)
10287 : {
10288 0 : densesolverreport *p = (densesolverreport*)_p;
10289 0 : ae_touch_ptr((void*)p);
10290 0 : }
10291 :
10292 :
10293 0 : void _densesolverreport_destroy(void* _p)
10294 : {
10295 0 : densesolverreport *p = (densesolverreport*)_p;
10296 0 : ae_touch_ptr((void*)p);
10297 0 : }
10298 :
10299 :
10300 0 : void _densesolverlsreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
10301 : {
10302 0 : densesolverlsreport *p = (densesolverlsreport*)_p;
10303 0 : ae_touch_ptr((void*)p);
10304 0 : ae_matrix_init(&p->cx, 0, 0, DT_REAL, _state, make_automatic);
10305 0 : }
10306 :
10307 :
10308 0 : void _densesolverlsreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
10309 : {
10310 0 : densesolverlsreport *dst = (densesolverlsreport*)_dst;
10311 0 : densesolverlsreport *src = (densesolverlsreport*)_src;
10312 0 : dst->r2 = src->r2;
10313 0 : ae_matrix_init_copy(&dst->cx, &src->cx, _state, make_automatic);
10314 0 : dst->n = src->n;
10315 0 : dst->k = src->k;
10316 0 : }
10317 :
10318 :
10319 0 : void _densesolverlsreport_clear(void* _p)
10320 : {
10321 0 : densesolverlsreport *p = (densesolverlsreport*)_p;
10322 0 : ae_touch_ptr((void*)p);
10323 0 : ae_matrix_clear(&p->cx);
10324 0 : }
10325 :
10326 :
10327 0 : void _densesolverlsreport_destroy(void* _p)
10328 : {
10329 0 : densesolverlsreport *p = (densesolverlsreport*)_p;
10330 0 : ae_touch_ptr((void*)p);
10331 0 : ae_matrix_destroy(&p->cx);
10332 0 : }
10333 :
10334 :
10335 : #endif
10336 : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
10337 :
10338 :
10339 : /*************************************************************************
10340 : This function initializes linear LSQR Solver. This solver is used to solve
10341 : non-symmetric (and, possibly, non-square) problems. Least squares solution
10342 : is returned for non-compatible systems.
10343 :
10344 : USAGE:
10345 : 1. User initializes algorithm state with LinLSQRCreate() call
10346 : 2. User tunes solver parameters with LinLSQRSetCond() and other functions
10347 : 3. User calls LinLSQRSolveSparse() function which takes algorithm state
10348 : and SparseMatrix object.
10349 : 4. User calls LinLSQRResults() to get solution
10350 : 5. Optionally, user may call LinLSQRSolveSparse() again to solve another
10351 : problem with different matrix and/or right part without reinitializing
10352 : LinLSQRState structure.
10353 :
10354 : INPUT PARAMETERS:
10355 : M - number of rows in A
10356 : N - number of variables, N>0
10357 :
10358 : OUTPUT PARAMETERS:
10359 : State - structure which stores algorithm state
10360 :
10361 : NOTE: see also linlsqrcreatebuf() for version which reuses previously
10362 : allocated place as much as possible.
10363 :
10364 : -- ALGLIB --
10365 : Copyright 30.11.2011 by Bochkanov Sergey
10366 : *************************************************************************/
10367 0 : void linlsqrcreate(ae_int_t m,
10368 : ae_int_t n,
10369 : linlsqrstate* state,
10370 : ae_state *_state)
10371 : {
10372 :
10373 0 : _linlsqrstate_clear(state);
10374 :
10375 0 : ae_assert(m>0, "LinLSQRCreate: M<=0", _state);
10376 0 : ae_assert(n>0, "LinLSQRCreate: N<=0", _state);
10377 0 : linlsqrcreatebuf(m, n, state, _state);
10378 0 : }
10379 :
10380 :
10381 : /*************************************************************************
10382 : This function initializes linear LSQR Solver. It provides exactly same
10383 : functionality as linlsqrcreate(), but reuses previously allocated space
10384 : as much as possible.
10385 :
10386 : INPUT PARAMETERS:
10387 : M - number of rows in A
10388 : N - number of variables, N>0
10389 :
10390 : OUTPUT PARAMETERS:
10391 : State - structure which stores algorithm state
10392 :
10393 : -- ALGLIB --
10394 : Copyright 14.11.2018 by Bochkanov Sergey
10395 : *************************************************************************/
10396 0 : void linlsqrcreatebuf(ae_int_t m,
10397 : ae_int_t n,
10398 : linlsqrstate* state,
10399 : ae_state *_state)
10400 : {
10401 : ae_int_t i;
10402 :
10403 :
10404 0 : ae_assert(m>0, "LinLSQRCreateBuf: M<=0", _state);
10405 0 : ae_assert(n>0, "LinLSQRCreateBuf: N<=0", _state);
10406 0 : state->m = m;
10407 0 : state->n = n;
10408 0 : state->prectype = 0;
10409 0 : state->epsa = linlsqr_atol;
10410 0 : state->epsb = linlsqr_btol;
10411 0 : state->epsc = 1/ae_sqrt(ae_machineepsilon, _state);
10412 0 : state->maxits = 0;
10413 0 : state->lambdai = (double)(0);
10414 0 : state->xrep = ae_false;
10415 0 : state->running = ae_false;
10416 0 : state->repiterationscount = 0;
10417 :
10418 : /*
10419 : * * allocate arrays
10420 : * * set RX to NAN (just for the case user calls Results() without
10421 : * calling SolveSparse()
10422 : * * set B to zero
10423 : */
10424 0 : normestimatorcreate(m, n, 2, 2, &state->nes, _state);
10425 0 : ae_vector_set_length(&state->rx, state->n, _state);
10426 0 : ae_vector_set_length(&state->ui, state->m+state->n, _state);
10427 0 : ae_vector_set_length(&state->uip1, state->m+state->n, _state);
10428 0 : ae_vector_set_length(&state->vip1, state->n, _state);
10429 0 : ae_vector_set_length(&state->vi, state->n, _state);
10430 0 : ae_vector_set_length(&state->omegai, state->n, _state);
10431 0 : ae_vector_set_length(&state->omegaip1, state->n, _state);
10432 0 : ae_vector_set_length(&state->d, state->n, _state);
10433 0 : ae_vector_set_length(&state->x, state->m+state->n, _state);
10434 0 : ae_vector_set_length(&state->mv, state->m+state->n, _state);
10435 0 : ae_vector_set_length(&state->mtv, state->n, _state);
10436 0 : ae_vector_set_length(&state->b, state->m, _state);
10437 0 : for(i=0; i<=n-1; i++)
10438 : {
10439 0 : state->rx.ptr.p_double[i] = _state->v_nan;
10440 : }
10441 0 : for(i=0; i<=m-1; i++)
10442 : {
10443 0 : state->b.ptr.p_double[i] = (double)(0);
10444 : }
10445 0 : ae_vector_set_length(&state->rstate.ia, 1+1, _state);
10446 0 : ae_vector_set_length(&state->rstate.ra, 0+1, _state);
10447 0 : state->rstate.stage = -1;
10448 0 : }
10449 :
10450 :
10451 : /*************************************************************************
10452 : This function sets right part. By default, right part is zero.
10453 :
10454 : INPUT PARAMETERS:
10455 : B - right part, array[N].
10456 :
10457 : OUTPUT PARAMETERS:
10458 : State - structure which stores algorithm state
10459 :
10460 : -- ALGLIB --
10461 : Copyright 30.11.2011 by Bochkanov Sergey
10462 : *************************************************************************/
10463 0 : void linlsqrsetb(linlsqrstate* state,
10464 : /* Real */ ae_vector* b,
10465 : ae_state *_state)
10466 : {
10467 : ae_int_t i;
10468 :
10469 :
10470 0 : ae_assert(!state->running, "LinLSQRSetB: you can not change B when LinLSQRIteration is running", _state);
10471 0 : ae_assert(state->m<=b->cnt, "LinLSQRSetB: Length(B)<M", _state);
10472 0 : ae_assert(isfinitevector(b, state->m, _state), "LinLSQRSetB: B contains infinite or NaN values", _state);
10473 0 : state->bnorm2 = (double)(0);
10474 0 : for(i=0; i<=state->m-1; i++)
10475 : {
10476 0 : state->b.ptr.p_double[i] = b->ptr.p_double[i];
10477 0 : state->bnorm2 = state->bnorm2+b->ptr.p_double[i]*b->ptr.p_double[i];
10478 : }
10479 0 : }
10480 :
10481 :
10482 : /*************************************************************************
10483 : This function changes preconditioning settings of LinLSQQSolveSparse()
10484 : function. By default, SolveSparse() uses diagonal preconditioner, but if
10485 : you want to use solver without preconditioning, you can call this function
10486 : which forces solver to use unit matrix for preconditioning.
10487 :
10488 : INPUT PARAMETERS:
10489 : State - structure which stores algorithm state
10490 :
10491 : -- ALGLIB --
10492 : Copyright 19.11.2012 by Bochkanov Sergey
10493 : *************************************************************************/
10494 0 : void linlsqrsetprecunit(linlsqrstate* state, ae_state *_state)
10495 : {
10496 :
10497 :
10498 0 : ae_assert(!state->running, "LinLSQRSetPrecUnit: you can not change preconditioner, because function LinLSQRIteration is running!", _state);
10499 0 : state->prectype = -1;
10500 0 : }
10501 :
10502 :
10503 : /*************************************************************************
10504 : This function changes preconditioning settings of LinCGSolveSparse()
10505 : function. LinCGSolveSparse() will use diagonal of the system matrix as
10506 : preconditioner. This preconditioning mode is active by default.
10507 :
10508 : INPUT PARAMETERS:
10509 : State - structure which stores algorithm state
10510 :
10511 : -- ALGLIB --
10512 : Copyright 19.11.2012 by Bochkanov Sergey
10513 : *************************************************************************/
10514 0 : void linlsqrsetprecdiag(linlsqrstate* state, ae_state *_state)
10515 : {
10516 :
10517 :
10518 0 : ae_assert(!state->running, "LinLSQRSetPrecDiag: you can not change preconditioner, because function LinCGIteration is running!", _state);
10519 0 : state->prectype = 0;
10520 0 : }
10521 :
10522 :
10523 : /*************************************************************************
10524 : This function sets optional Tikhonov regularization coefficient.
10525 : It is zero by default.
10526 :
10527 : INPUT PARAMETERS:
10528 : LambdaI - regularization factor, LambdaI>=0
10529 :
10530 : OUTPUT PARAMETERS:
10531 : State - structure which stores algorithm state
10532 :
10533 : -- ALGLIB --
10534 : Copyright 30.11.2011 by Bochkanov Sergey
10535 : *************************************************************************/
10536 0 : void linlsqrsetlambdai(linlsqrstate* state,
10537 : double lambdai,
10538 : ae_state *_state)
10539 : {
10540 :
10541 :
10542 0 : ae_assert(!state->running, "LinLSQRSetLambdaI: you can not set LambdaI, because function LinLSQRIteration is running", _state);
10543 0 : ae_assert(ae_isfinite(lambdai, _state)&&ae_fp_greater_eq(lambdai,(double)(0)), "LinLSQRSetLambdaI: LambdaI is infinite or NaN", _state);
10544 0 : state->lambdai = lambdai;
10545 0 : }
10546 :
10547 :
10548 : /*************************************************************************
10549 :
10550 : -- ALGLIB --
10551 : Copyright 30.11.2011 by Bochkanov Sergey
10552 : *************************************************************************/
10553 0 : ae_bool linlsqriteration(linlsqrstate* state, ae_state *_state)
10554 : {
10555 : ae_int_t summn;
10556 : double bnorm;
10557 : ae_int_t i;
10558 : ae_bool result;
10559 :
10560 :
10561 :
10562 : /*
10563 : * Reverse communication preparations
10564 : * I know it looks ugly, but it works the same way
10565 : * anywhere from C++ to Python.
10566 : *
10567 : * This code initializes locals by:
10568 : * * random values determined during code
10569 : * generation - on first subroutine call
10570 : * * values from previous call - on subsequent calls
10571 : */
10572 0 : if( state->rstate.stage>=0 )
10573 : {
10574 0 : summn = state->rstate.ia.ptr.p_int[0];
10575 0 : i = state->rstate.ia.ptr.p_int[1];
10576 0 : bnorm = state->rstate.ra.ptr.p_double[0];
10577 : }
10578 : else
10579 : {
10580 0 : summn = 359;
10581 0 : i = -58;
10582 0 : bnorm = -919;
10583 : }
10584 0 : if( state->rstate.stage==0 )
10585 : {
10586 0 : goto lbl_0;
10587 : }
10588 0 : if( state->rstate.stage==1 )
10589 : {
10590 0 : goto lbl_1;
10591 : }
10592 0 : if( state->rstate.stage==2 )
10593 : {
10594 0 : goto lbl_2;
10595 : }
10596 0 : if( state->rstate.stage==3 )
10597 : {
10598 0 : goto lbl_3;
10599 : }
10600 0 : if( state->rstate.stage==4 )
10601 : {
10602 0 : goto lbl_4;
10603 : }
10604 0 : if( state->rstate.stage==5 )
10605 : {
10606 0 : goto lbl_5;
10607 : }
10608 0 : if( state->rstate.stage==6 )
10609 : {
10610 0 : goto lbl_6;
10611 : }
10612 :
10613 : /*
10614 : * Routine body
10615 : */
10616 0 : ae_assert(state->b.cnt>0, "LinLSQRIteration: using non-allocated array B", _state);
10617 0 : summn = state->m+state->n;
10618 0 : bnorm = ae_sqrt(state->bnorm2, _state);
10619 0 : state->userterminationneeded = ae_false;
10620 0 : state->running = ae_true;
10621 0 : state->repnmv = 0;
10622 0 : state->repiterationscount = 0;
10623 0 : state->r2 = state->bnorm2;
10624 0 : linlsqr_clearrfields(state, _state);
10625 :
10626 : /*
10627 : *estimate for ANorm
10628 : */
10629 0 : normestimatorrestart(&state->nes, _state);
10630 0 : lbl_7:
10631 0 : if( !normestimatoriteration(&state->nes, _state) )
10632 : {
10633 0 : goto lbl_8;
10634 : }
10635 0 : if( !state->nes.needmv )
10636 : {
10637 0 : goto lbl_9;
10638 : }
10639 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->nes.x.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10640 0 : state->repnmv = state->repnmv+1;
10641 0 : linlsqr_clearrfields(state, _state);
10642 0 : state->needmv = ae_true;
10643 0 : state->rstate.stage = 0;
10644 0 : goto lbl_rcomm;
10645 0 : lbl_0:
10646 0 : state->needmv = ae_false;
10647 0 : ae_v_move(&state->nes.mv.ptr.p_double[0], 1, &state->mv.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
10648 0 : goto lbl_7;
10649 0 : lbl_9:
10650 0 : if( !state->nes.needmtv )
10651 : {
10652 0 : goto lbl_11;
10653 : }
10654 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->nes.x.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
10655 :
10656 : /*
10657 : *matrix-vector multiplication
10658 : */
10659 0 : state->repnmv = state->repnmv+1;
10660 0 : linlsqr_clearrfields(state, _state);
10661 0 : state->needmtv = ae_true;
10662 0 : state->rstate.stage = 1;
10663 0 : goto lbl_rcomm;
10664 0 : lbl_1:
10665 0 : state->needmtv = ae_false;
10666 0 : ae_v_move(&state->nes.mtv.ptr.p_double[0], 1, &state->mtv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10667 0 : goto lbl_7;
10668 0 : lbl_11:
10669 0 : goto lbl_7;
10670 0 : lbl_8:
10671 0 : normestimatorresults(&state->nes, &state->anorm, _state);
10672 :
10673 : /*
10674 : *initialize .RX by zeros
10675 : */
10676 0 : for(i=0; i<=state->n-1; i++)
10677 : {
10678 0 : state->rx.ptr.p_double[i] = (double)(0);
10679 : }
10680 :
10681 : /*
10682 : *output first report
10683 : */
10684 0 : if( !state->xrep )
10685 : {
10686 0 : goto lbl_13;
10687 : }
10688 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10689 0 : linlsqr_clearrfields(state, _state);
10690 0 : state->xupdated = ae_true;
10691 0 : state->rstate.stage = 2;
10692 0 : goto lbl_rcomm;
10693 0 : lbl_2:
10694 0 : state->xupdated = ae_false;
10695 0 : lbl_13:
10696 :
10697 : /*
10698 : * LSQR, Step 0.
10699 : *
10700 : * Algorithm outline corresponds to one which was described at p.50 of
10701 : * "LSQR - an algorithm for sparse linear equations and sparse least
10702 : * squares" by C.Paige and M.Saunders with one small addition - we
10703 : * explicitly extend system matrix by additional N lines in order
10704 : * to handle non-zero lambda, i.e. original A is replaced by
10705 : * [ A ]
10706 : * A_mod = [ ]
10707 : * [ lambda*I ].
10708 : *
10709 : * Step 0:
10710 : * x[0] = 0
10711 : * beta[1]*u[1] = b
10712 : * alpha[1]*v[1] = A_mod'*u[1]
10713 : * w[1] = v[1]
10714 : * phiBar[1] = beta[1]
10715 : * rhoBar[1] = alpha[1]
10716 : * d[0] = 0
10717 : *
10718 : * NOTE:
10719 : * There are three criteria for stopping:
10720 : * (S0) maximum number of iterations
10721 : * (S1) ||Rk||<=EpsB*||B||;
10722 : * (S2) ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
10723 : * It is very important that S2 always checked AFTER S1. It is necessary
10724 : * to avoid division by zero when Rk=0.
10725 : */
10726 0 : state->betai = bnorm;
10727 0 : if( ae_fp_eq(state->betai,(double)(0)) )
10728 : {
10729 :
10730 : /*
10731 : * Zero right part
10732 : */
10733 0 : state->running = ae_false;
10734 0 : state->repterminationtype = 1;
10735 0 : result = ae_false;
10736 0 : return result;
10737 : }
10738 0 : for(i=0; i<=summn-1; i++)
10739 : {
10740 0 : if( i<state->m )
10741 : {
10742 0 : state->ui.ptr.p_double[i] = state->b.ptr.p_double[i]/state->betai;
10743 : }
10744 : else
10745 : {
10746 0 : state->ui.ptr.p_double[i] = (double)(0);
10747 : }
10748 0 : state->x.ptr.p_double[i] = state->ui.ptr.p_double[i];
10749 : }
10750 0 : state->repnmv = state->repnmv+1;
10751 0 : linlsqr_clearrfields(state, _state);
10752 0 : state->needmtv = ae_true;
10753 0 : state->rstate.stage = 3;
10754 0 : goto lbl_rcomm;
10755 0 : lbl_3:
10756 0 : state->needmtv = ae_false;
10757 0 : for(i=0; i<=state->n-1; i++)
10758 : {
10759 0 : state->mtv.ptr.p_double[i] = state->mtv.ptr.p_double[i]+state->lambdai*state->ui.ptr.p_double[state->m+i];
10760 : }
10761 0 : state->alphai = (double)(0);
10762 0 : for(i=0; i<=state->n-1; i++)
10763 : {
10764 0 : state->alphai = state->alphai+state->mtv.ptr.p_double[i]*state->mtv.ptr.p_double[i];
10765 : }
10766 0 : state->alphai = ae_sqrt(state->alphai, _state);
10767 0 : if( ae_fp_eq(state->alphai,(double)(0)) )
10768 : {
10769 :
10770 : /*
10771 : * Orthogonality stopping criterion is met
10772 : */
10773 0 : state->running = ae_false;
10774 0 : state->repterminationtype = 4;
10775 0 : result = ae_false;
10776 0 : return result;
10777 : }
10778 0 : for(i=0; i<=state->n-1; i++)
10779 : {
10780 0 : state->vi.ptr.p_double[i] = state->mtv.ptr.p_double[i]/state->alphai;
10781 0 : state->omegai.ptr.p_double[i] = state->vi.ptr.p_double[i];
10782 : }
10783 0 : state->phibari = state->betai;
10784 0 : state->rhobari = state->alphai;
10785 0 : for(i=0; i<=state->n-1; i++)
10786 : {
10787 0 : state->d.ptr.p_double[i] = (double)(0);
10788 : }
10789 0 : state->dnorm = (double)(0);
10790 :
10791 : /*
10792 : * Steps I=1, 2, ...
10793 : */
10794 0 : lbl_15:
10795 : if( ae_false )
10796 : {
10797 : goto lbl_16;
10798 : }
10799 :
10800 : /*
10801 : * At I-th step State.RepIterationsCount=I.
10802 : */
10803 0 : state->repiterationscount = state->repiterationscount+1;
10804 :
10805 : /*
10806 : * Bidiagonalization part:
10807 : * beta[i+1]*u[i+1] = A_mod*v[i]-alpha[i]*u[i]
10808 : * alpha[i+1]*v[i+1] = A_mod'*u[i+1] - beta[i+1]*v[i]
10809 : *
10810 : * NOTE: beta[i+1]=0 or alpha[i+1]=0 will lead to successful termination
10811 : * in the end of the current iteration. In this case u/v are zero.
10812 : * NOTE2: algorithm won't fail on zero alpha or beta (there will be no
10813 : * division by zero because it will be stopped BEFORE division
10814 : * occurs). However, near-zero alpha and beta won't stop algorithm
10815 : * and, although no division by zero will happen, orthogonality
10816 : * in U and V will be lost.
10817 : */
10818 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->vi.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10819 0 : state->repnmv = state->repnmv+1;
10820 0 : linlsqr_clearrfields(state, _state);
10821 0 : state->needmv = ae_true;
10822 0 : state->rstate.stage = 4;
10823 0 : goto lbl_rcomm;
10824 0 : lbl_4:
10825 0 : state->needmv = ae_false;
10826 0 : for(i=0; i<=state->n-1; i++)
10827 : {
10828 0 : state->mv.ptr.p_double[state->m+i] = state->lambdai*state->vi.ptr.p_double[i];
10829 : }
10830 0 : state->betaip1 = (double)(0);
10831 0 : for(i=0; i<=summn-1; i++)
10832 : {
10833 0 : state->uip1.ptr.p_double[i] = state->mv.ptr.p_double[i]-state->alphai*state->ui.ptr.p_double[i];
10834 0 : state->betaip1 = state->betaip1+state->uip1.ptr.p_double[i]*state->uip1.ptr.p_double[i];
10835 : }
10836 0 : if( ae_fp_neq(state->betaip1,(double)(0)) )
10837 : {
10838 0 : state->betaip1 = ae_sqrt(state->betaip1, _state);
10839 0 : for(i=0; i<=summn-1; i++)
10840 : {
10841 0 : state->uip1.ptr.p_double[i] = state->uip1.ptr.p_double[i]/state->betaip1;
10842 : }
10843 : }
10844 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->uip1.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
10845 0 : state->repnmv = state->repnmv+1;
10846 0 : linlsqr_clearrfields(state, _state);
10847 0 : state->needmtv = ae_true;
10848 0 : state->rstate.stage = 5;
10849 0 : goto lbl_rcomm;
10850 0 : lbl_5:
10851 0 : state->needmtv = ae_false;
10852 0 : for(i=0; i<=state->n-1; i++)
10853 : {
10854 0 : state->mtv.ptr.p_double[i] = state->mtv.ptr.p_double[i]+state->lambdai*state->uip1.ptr.p_double[state->m+i];
10855 : }
10856 0 : state->alphaip1 = (double)(0);
10857 0 : for(i=0; i<=state->n-1; i++)
10858 : {
10859 0 : state->vip1.ptr.p_double[i] = state->mtv.ptr.p_double[i]-state->betaip1*state->vi.ptr.p_double[i];
10860 0 : state->alphaip1 = state->alphaip1+state->vip1.ptr.p_double[i]*state->vip1.ptr.p_double[i];
10861 : }
10862 0 : if( ae_fp_neq(state->alphaip1,(double)(0)) )
10863 : {
10864 0 : state->alphaip1 = ae_sqrt(state->alphaip1, _state);
10865 0 : for(i=0; i<=state->n-1; i++)
10866 : {
10867 0 : state->vip1.ptr.p_double[i] = state->vip1.ptr.p_double[i]/state->alphaip1;
10868 : }
10869 : }
10870 :
10871 : /*
10872 : * Build next orthogonal transformation
10873 : */
10874 0 : state->rhoi = safepythag2(state->rhobari, state->betaip1, _state);
10875 0 : state->ci = state->rhobari/state->rhoi;
10876 0 : state->si = state->betaip1/state->rhoi;
10877 0 : state->theta = state->si*state->alphaip1;
10878 0 : state->rhobarip1 = -state->ci*state->alphaip1;
10879 0 : state->phii = state->ci*state->phibari;
10880 0 : state->phibarip1 = state->si*state->phibari;
10881 :
10882 : /*
10883 : * Update .RNorm
10884 : *
10885 : * This tricky formula is necessary because simply writing
10886 : * State.R2:=State.PhiBarIP1*State.PhiBarIP1 does NOT guarantees
10887 : * monotonic decrease of R2. Roundoff error combined with 80-bit
10888 : * precision used internally by Intel chips allows R2 to increase
10889 : * slightly in some rare, but possible cases. This property is
10890 : * undesirable, so we prefer to guard against R increase.
10891 : */
10892 0 : state->r2 = ae_minreal(state->r2, state->phibarip1*state->phibarip1, _state);
10893 :
10894 : /*
10895 : * Update d and DNorm, check condition-related stopping criteria
10896 : */
10897 0 : for(i=0; i<=state->n-1; i++)
10898 : {
10899 0 : state->d.ptr.p_double[i] = 1/state->rhoi*(state->vi.ptr.p_double[i]-state->theta*state->d.ptr.p_double[i]);
10900 0 : state->dnorm = state->dnorm+state->d.ptr.p_double[i]*state->d.ptr.p_double[i];
10901 : }
10902 0 : if( ae_fp_greater_eq(ae_sqrt(state->dnorm, _state)*state->anorm,state->epsc) )
10903 : {
10904 0 : state->running = ae_false;
10905 0 : state->repterminationtype = 7;
10906 0 : result = ae_false;
10907 0 : return result;
10908 : }
10909 :
10910 : /*
10911 : * Update x, output report
10912 : */
10913 0 : for(i=0; i<=state->n-1; i++)
10914 : {
10915 0 : state->rx.ptr.p_double[i] = state->rx.ptr.p_double[i]+state->phii/state->rhoi*state->omegai.ptr.p_double[i];
10916 : }
10917 0 : if( !state->xrep )
10918 : {
10919 0 : goto lbl_17;
10920 : }
10921 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10922 0 : linlsqr_clearrfields(state, _state);
10923 0 : state->xupdated = ae_true;
10924 0 : state->rstate.stage = 6;
10925 0 : goto lbl_rcomm;
10926 0 : lbl_6:
10927 0 : state->xupdated = ae_false;
10928 0 : lbl_17:
10929 :
10930 : /*
10931 : * Check stopping criteria
10932 : * 1. achieved required number of iterations;
10933 : * 2. ||Rk||<=EpsB*||B||;
10934 : * 3. ||A^T*Rk||/(||A||*||Rk||)<=EpsA;
10935 : */
10936 0 : if( state->maxits>0&&state->repiterationscount>=state->maxits )
10937 : {
10938 :
10939 : /*
10940 : * Achieved required number of iterations
10941 : */
10942 0 : state->running = ae_false;
10943 0 : state->repterminationtype = 5;
10944 0 : result = ae_false;
10945 0 : return result;
10946 : }
10947 0 : if( ae_fp_less_eq(state->phibarip1,state->epsb*bnorm) )
10948 : {
10949 :
10950 : /*
10951 : * ||Rk||<=EpsB*||B||, here ||Rk||=PhiBar
10952 : */
10953 0 : state->running = ae_false;
10954 0 : state->repterminationtype = 1;
10955 0 : result = ae_false;
10956 0 : return result;
10957 : }
10958 0 : if( ae_fp_less_eq(state->alphaip1*ae_fabs(state->ci, _state)/state->anorm,state->epsa) )
10959 : {
10960 :
10961 : /*
10962 : * ||A^T*Rk||/(||A||*||Rk||)<=EpsA, here ||A^T*Rk||=PhiBar*Alpha[i+1]*|.C|
10963 : */
10964 0 : state->running = ae_false;
10965 0 : state->repterminationtype = 4;
10966 0 : result = ae_false;
10967 0 : return result;
10968 : }
10969 0 : if( state->userterminationneeded )
10970 : {
10971 :
10972 : /*
10973 : * User requested termination
10974 : */
10975 0 : state->running = ae_false;
10976 0 : state->repterminationtype = 8;
10977 0 : result = ae_false;
10978 0 : return result;
10979 : }
10980 :
10981 : /*
10982 : * Update omega
10983 : */
10984 0 : for(i=0; i<=state->n-1; i++)
10985 : {
10986 0 : state->omegaip1.ptr.p_double[i] = state->vip1.ptr.p_double[i]-state->theta/state->rhoi*state->omegai.ptr.p_double[i];
10987 : }
10988 :
10989 : /*
10990 : * Prepare for the next iteration - rename variables:
10991 : * u[i] := u[i+1]
10992 : * v[i] := v[i+1]
10993 : * rho[i] := rho[i+1]
10994 : * ...
10995 : */
10996 0 : ae_v_move(&state->ui.ptr.p_double[0], 1, &state->uip1.ptr.p_double[0], 1, ae_v_len(0,summn-1));
10997 0 : ae_v_move(&state->vi.ptr.p_double[0], 1, &state->vip1.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10998 0 : ae_v_move(&state->omegai.ptr.p_double[0], 1, &state->omegaip1.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
10999 0 : state->alphai = state->alphaip1;
11000 0 : state->betai = state->betaip1;
11001 0 : state->phibari = state->phibarip1;
11002 0 : state->rhobari = state->rhobarip1;
11003 0 : goto lbl_15;
11004 : lbl_16:
11005 : result = ae_false;
11006 : return result;
11007 :
11008 : /*
11009 : * Saving state
11010 : */
11011 0 : lbl_rcomm:
11012 0 : result = ae_true;
11013 0 : state->rstate.ia.ptr.p_int[0] = summn;
11014 0 : state->rstate.ia.ptr.p_int[1] = i;
11015 0 : state->rstate.ra.ptr.p_double[0] = bnorm;
11016 0 : return result;
11017 : }
11018 :
11019 :
11020 : /*************************************************************************
11021 : Procedure for solution of A*x=b with sparse A.
11022 :
11023 : INPUT PARAMETERS:
11024 : State - algorithm state
11025 : A - sparse M*N matrix in the CRS format (you MUST contvert it
11026 : to CRS format by calling SparseConvertToCRS() function
11027 : BEFORE you pass it to this function).
11028 : B - right part, array[M]
11029 :
11030 : RESULT:
11031 : This function returns no result.
11032 : You can get solution by calling LinCGResults()
11033 :
11034 : NOTE: this function uses lightweight preconditioning - multiplication by
11035 : inverse of diag(A). If you want, you can turn preconditioning off by
11036 : calling LinLSQRSetPrecUnit(). However, preconditioning cost is low
11037 : and preconditioner is very important for solution of badly scaled
11038 : problems.
11039 :
11040 : -- ALGLIB --
11041 : Copyright 30.11.2011 by Bochkanov Sergey
11042 : *************************************************************************/
11043 0 : void linlsqrsolvesparse(linlsqrstate* state,
11044 : sparsematrix* a,
11045 : /* Real */ ae_vector* b,
11046 : ae_state *_state)
11047 : {
11048 : ae_int_t n;
11049 : ae_int_t i;
11050 : ae_int_t j;
11051 : ae_int_t t0;
11052 : ae_int_t t1;
11053 : double v;
11054 :
11055 :
11056 0 : n = state->n;
11057 0 : ae_assert(!state->running, "LinLSQRSolveSparse: you can not call this function when LinLSQRIteration is running", _state);
11058 0 : ae_assert(b->cnt>=state->m, "LinLSQRSolveSparse: Length(B)<M", _state);
11059 0 : ae_assert(isfinitevector(b, state->m, _state), "LinLSQRSolveSparse: B contains infinite or NaN values", _state);
11060 :
11061 : /*
11062 : * Allocate temporaries
11063 : */
11064 0 : rvectorsetlengthatleast(&state->tmpd, n, _state);
11065 0 : rvectorsetlengthatleast(&state->tmpx, n, _state);
11066 :
11067 : /*
11068 : * Compute diagonal scaling matrix D
11069 : */
11070 0 : if( state->prectype==0 )
11071 : {
11072 :
11073 : /*
11074 : * Default preconditioner - inverse of column norms
11075 : */
11076 0 : for(i=0; i<=n-1; i++)
11077 : {
11078 0 : state->tmpd.ptr.p_double[i] = (double)(0);
11079 : }
11080 0 : t0 = 0;
11081 0 : t1 = 0;
11082 0 : while(sparseenumerate(a, &t0, &t1, &i, &j, &v, _state))
11083 : {
11084 0 : state->tmpd.ptr.p_double[j] = state->tmpd.ptr.p_double[j]+ae_sqr(v, _state);
11085 : }
11086 0 : for(i=0; i<=n-1; i++)
11087 : {
11088 0 : if( ae_fp_greater(state->tmpd.ptr.p_double[i],(double)(0)) )
11089 : {
11090 0 : state->tmpd.ptr.p_double[i] = 1/ae_sqrt(state->tmpd.ptr.p_double[i], _state);
11091 : }
11092 : else
11093 : {
11094 0 : state->tmpd.ptr.p_double[i] = (double)(1);
11095 : }
11096 : }
11097 : }
11098 : else
11099 : {
11100 :
11101 : /*
11102 : * No diagonal scaling
11103 : */
11104 0 : for(i=0; i<=n-1; i++)
11105 : {
11106 0 : state->tmpd.ptr.p_double[i] = (double)(1);
11107 : }
11108 : }
11109 :
11110 : /*
11111 : * Solve.
11112 : *
11113 : * Instead of solving A*x=b we solve preconditioned system (A*D)*(inv(D)*x)=b.
11114 : * Transformed A is not calculated explicitly, we just modify multiplication
11115 : * by A or A'. After solution we modify State.RX so it will store untransformed
11116 : * variables
11117 : */
11118 0 : linlsqrsetb(state, b, _state);
11119 0 : linlsqrrestart(state, _state);
11120 0 : while(linlsqriteration(state, _state))
11121 : {
11122 0 : if( state->needmv )
11123 : {
11124 0 : for(i=0; i<=n-1; i++)
11125 : {
11126 0 : state->tmpx.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->x.ptr.p_double[i];
11127 : }
11128 0 : sparsemv(a, &state->tmpx, &state->mv, _state);
11129 : }
11130 0 : if( state->needmtv )
11131 : {
11132 0 : sparsemtv(a, &state->x, &state->mtv, _state);
11133 0 : for(i=0; i<=n-1; i++)
11134 : {
11135 0 : state->mtv.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->mtv.ptr.p_double[i];
11136 : }
11137 : }
11138 : }
11139 0 : for(i=0; i<=n-1; i++)
11140 : {
11141 0 : state->rx.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->rx.ptr.p_double[i];
11142 : }
11143 0 : }
11144 :
11145 :
11146 : /*************************************************************************
11147 : This function sets stopping criteria.
11148 :
11149 : INPUT PARAMETERS:
11150 : EpsA - algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
11151 : EpsB - algorithm will be stopped if ||Rk||<=EpsB*||B||
11152 : MaxIts - algorithm will be stopped if number of iterations
11153 : more than MaxIts.
11154 :
11155 : OUTPUT PARAMETERS:
11156 : State - structure which stores algorithm state
11157 :
11158 : NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
11159 : be setted as default values.
11160 :
11161 : -- ALGLIB --
11162 : Copyright 30.11.2011 by Bochkanov Sergey
11163 : *************************************************************************/
11164 0 : void linlsqrsetcond(linlsqrstate* state,
11165 : double epsa,
11166 : double epsb,
11167 : ae_int_t maxits,
11168 : ae_state *_state)
11169 : {
11170 :
11171 :
11172 0 : ae_assert(!state->running, "LinLSQRSetCond: you can not call this function when LinLSQRIteration is running", _state);
11173 0 : ae_assert(ae_isfinite(epsa, _state)&&ae_fp_greater_eq(epsa,(double)(0)), "LinLSQRSetCond: EpsA is negative, INF or NAN", _state);
11174 0 : ae_assert(ae_isfinite(epsb, _state)&&ae_fp_greater_eq(epsb,(double)(0)), "LinLSQRSetCond: EpsB is negative, INF or NAN", _state);
11175 0 : ae_assert(maxits>=0, "LinLSQRSetCond: MaxIts is negative", _state);
11176 0 : if( (ae_fp_eq(epsa,(double)(0))&&ae_fp_eq(epsb,(double)(0)))&&maxits==0 )
11177 : {
11178 0 : state->epsa = linlsqr_atol;
11179 0 : state->epsb = linlsqr_btol;
11180 0 : state->maxits = state->n;
11181 : }
11182 : else
11183 : {
11184 0 : state->epsa = epsa;
11185 0 : state->epsb = epsb;
11186 0 : state->maxits = maxits;
11187 : }
11188 0 : }
11189 :
11190 :
11191 : /*************************************************************************
11192 : LSQR solver: results.
11193 :
11194 : This function must be called after LinLSQRSolve
11195 :
11196 : INPUT PARAMETERS:
11197 : State - algorithm state
11198 :
11199 : OUTPUT PARAMETERS:
11200 : X - array[N], solution
11201 : Rep - optimization report:
11202 : * Rep.TerminationType completetion code:
11203 : * 1 ||Rk||<=EpsB*||B||
11204 : * 4 ||A^T*Rk||/(||A||*||Rk||)<=EpsA
11205 : * 5 MaxIts steps was taken
11206 : * 7 rounding errors prevent further progress,
11207 : X contains best point found so far.
11208 : (sometimes returned on singular systems)
11209 : * 8 user requested termination via calling
11210 : linlsqrrequesttermination()
11211 : * Rep.IterationsCount contains iterations count
11212 : * NMV countains number of matrix-vector calculations
11213 :
11214 : -- ALGLIB --
11215 : Copyright 30.11.2011 by Bochkanov Sergey
11216 : *************************************************************************/
11217 0 : void linlsqrresults(linlsqrstate* state,
11218 : /* Real */ ae_vector* x,
11219 : linlsqrreport* rep,
11220 : ae_state *_state)
11221 : {
11222 :
11223 0 : ae_vector_clear(x);
11224 0 : _linlsqrreport_clear(rep);
11225 :
11226 0 : ae_assert(!state->running, "LinLSQRResult: you can not call this function when LinLSQRIteration is running", _state);
11227 0 : if( x->cnt<state->n )
11228 : {
11229 0 : ae_vector_set_length(x, state->n, _state);
11230 : }
11231 0 : ae_v_move(&x->ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
11232 0 : rep->iterationscount = state->repiterationscount;
11233 0 : rep->nmv = state->repnmv;
11234 0 : rep->terminationtype = state->repterminationtype;
11235 0 : }
11236 :
11237 :
11238 : /*************************************************************************
11239 : This function turns on/off reporting.
11240 :
11241 : INPUT PARAMETERS:
11242 : State - structure which stores algorithm state
11243 : NeedXRep- whether iteration reports are needed or not
11244 :
11245 : If NeedXRep is True, algorithm will call rep() callback function if it is
11246 : provided to MinCGOptimize().
11247 :
11248 : -- ALGLIB --
11249 : Copyright 30.11.2011 by Bochkanov Sergey
11250 : *************************************************************************/
11251 0 : void linlsqrsetxrep(linlsqrstate* state,
11252 : ae_bool needxrep,
11253 : ae_state *_state)
11254 : {
11255 :
11256 :
11257 0 : state->xrep = needxrep;
11258 0 : }
11259 :
11260 :
11261 : /*************************************************************************
11262 : This function restarts LinLSQRIteration
11263 :
11264 : -- ALGLIB --
11265 : Copyright 30.11.2011 by Bochkanov Sergey
11266 : *************************************************************************/
11267 0 : void linlsqrrestart(linlsqrstate* state, ae_state *_state)
11268 : {
11269 :
11270 :
11271 0 : ae_vector_set_length(&state->rstate.ia, 1+1, _state);
11272 0 : ae_vector_set_length(&state->rstate.ra, 0+1, _state);
11273 0 : state->rstate.stage = -1;
11274 0 : linlsqr_clearrfields(state, _state);
11275 0 : state->repiterationscount = 0;
11276 0 : }
11277 :
11278 :
11279 : /*************************************************************************
11280 : This function is used to peek into LSQR solver and get current iteration
11281 : counter. You can safely "peek" into the solver from another thread.
11282 :
11283 : INPUT PARAMETERS:
11284 : S - solver object
11285 :
11286 : RESULT:
11287 : iteration counter, in [0,INF)
11288 :
11289 : -- ALGLIB --
11290 : Copyright 21.05.2018 by Bochkanov Sergey
11291 : *************************************************************************/
11292 0 : ae_int_t linlsqrpeekiterationscount(linlsqrstate* s, ae_state *_state)
11293 : {
11294 : ae_int_t result;
11295 :
11296 :
11297 0 : result = s->repiterationscount;
11298 0 : return result;
11299 : }
11300 :
11301 :
11302 : /*************************************************************************
11303 : This subroutine submits request for termination of the running solver. It
11304 : can be called from some other thread which wants LSQR solver to terminate
11305 : (obviously, the thread running LSQR solver can not request termination
11306 : because it is already busy working on LSQR).
11307 :
11308 : As result, solver stops at point which was "current accepted" when
11309 : termination request was submitted and returns error code 8 (successful
11310 : termination). Such termination is a smooth process which properly
11311 : deallocates all temporaries.
11312 :
11313 : INPUT PARAMETERS:
11314 : State - solver structure
11315 :
11316 : NOTE: calling this function on solver which is NOT running will have no
11317 : effect.
11318 :
11319 : NOTE: multiple calls to this function are possible. First call is counted,
11320 : subsequent calls are silently ignored.
11321 :
11322 : NOTE: solver clears termination flag on its start, it means that if some
11323 : other thread will request termination too soon, its request will went
11324 : unnoticed.
11325 :
11326 : -- ALGLIB --
11327 : Copyright 08.10.2014 by Bochkanov Sergey
11328 : *************************************************************************/
11329 0 : void linlsqrrequesttermination(linlsqrstate* state, ae_state *_state)
11330 : {
11331 :
11332 :
11333 0 : state->userterminationneeded = ae_true;
11334 0 : }
11335 :
11336 :
11337 : /*************************************************************************
11338 : Clears request fileds (to be sure that we don't forgot to clear something)
11339 : *************************************************************************/
11340 0 : static void linlsqr_clearrfields(linlsqrstate* state, ae_state *_state)
11341 : {
11342 :
11343 :
11344 0 : state->xupdated = ae_false;
11345 0 : state->needmv = ae_false;
11346 0 : state->needmtv = ae_false;
11347 0 : state->needmv2 = ae_false;
11348 0 : state->needvmv = ae_false;
11349 0 : state->needprec = ae_false;
11350 0 : }
11351 :
11352 :
11353 0 : void _linlsqrstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
11354 : {
11355 0 : linlsqrstate *p = (linlsqrstate*)_p;
11356 0 : ae_touch_ptr((void*)p);
11357 0 : _normestimatorstate_init(&p->nes, _state, make_automatic);
11358 0 : ae_vector_init(&p->rx, 0, DT_REAL, _state, make_automatic);
11359 0 : ae_vector_init(&p->b, 0, DT_REAL, _state, make_automatic);
11360 0 : ae_vector_init(&p->ui, 0, DT_REAL, _state, make_automatic);
11361 0 : ae_vector_init(&p->uip1, 0, DT_REAL, _state, make_automatic);
11362 0 : ae_vector_init(&p->vi, 0, DT_REAL, _state, make_automatic);
11363 0 : ae_vector_init(&p->vip1, 0, DT_REAL, _state, make_automatic);
11364 0 : ae_vector_init(&p->omegai, 0, DT_REAL, _state, make_automatic);
11365 0 : ae_vector_init(&p->omegaip1, 0, DT_REAL, _state, make_automatic);
11366 0 : ae_vector_init(&p->d, 0, DT_REAL, _state, make_automatic);
11367 0 : ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
11368 0 : ae_vector_init(&p->mv, 0, DT_REAL, _state, make_automatic);
11369 0 : ae_vector_init(&p->mtv, 0, DT_REAL, _state, make_automatic);
11370 0 : ae_vector_init(&p->tmpd, 0, DT_REAL, _state, make_automatic);
11371 0 : ae_vector_init(&p->tmpx, 0, DT_REAL, _state, make_automatic);
11372 0 : _rcommstate_init(&p->rstate, _state, make_automatic);
11373 0 : }
11374 :
11375 :
11376 0 : void _linlsqrstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
11377 : {
11378 0 : linlsqrstate *dst = (linlsqrstate*)_dst;
11379 0 : linlsqrstate *src = (linlsqrstate*)_src;
11380 0 : _normestimatorstate_init_copy(&dst->nes, &src->nes, _state, make_automatic);
11381 0 : ae_vector_init_copy(&dst->rx, &src->rx, _state, make_automatic);
11382 0 : ae_vector_init_copy(&dst->b, &src->b, _state, make_automatic);
11383 0 : dst->n = src->n;
11384 0 : dst->m = src->m;
11385 0 : dst->prectype = src->prectype;
11386 0 : ae_vector_init_copy(&dst->ui, &src->ui, _state, make_automatic);
11387 0 : ae_vector_init_copy(&dst->uip1, &src->uip1, _state, make_automatic);
11388 0 : ae_vector_init_copy(&dst->vi, &src->vi, _state, make_automatic);
11389 0 : ae_vector_init_copy(&dst->vip1, &src->vip1, _state, make_automatic);
11390 0 : ae_vector_init_copy(&dst->omegai, &src->omegai, _state, make_automatic);
11391 0 : ae_vector_init_copy(&dst->omegaip1, &src->omegaip1, _state, make_automatic);
11392 0 : dst->alphai = src->alphai;
11393 0 : dst->alphaip1 = src->alphaip1;
11394 0 : dst->betai = src->betai;
11395 0 : dst->betaip1 = src->betaip1;
11396 0 : dst->phibari = src->phibari;
11397 0 : dst->phibarip1 = src->phibarip1;
11398 0 : dst->phii = src->phii;
11399 0 : dst->rhobari = src->rhobari;
11400 0 : dst->rhobarip1 = src->rhobarip1;
11401 0 : dst->rhoi = src->rhoi;
11402 0 : dst->ci = src->ci;
11403 0 : dst->si = src->si;
11404 0 : dst->theta = src->theta;
11405 0 : dst->lambdai = src->lambdai;
11406 0 : ae_vector_init_copy(&dst->d, &src->d, _state, make_automatic);
11407 0 : dst->anorm = src->anorm;
11408 0 : dst->bnorm2 = src->bnorm2;
11409 0 : dst->dnorm = src->dnorm;
11410 0 : dst->r2 = src->r2;
11411 0 : ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
11412 0 : ae_vector_init_copy(&dst->mv, &src->mv, _state, make_automatic);
11413 0 : ae_vector_init_copy(&dst->mtv, &src->mtv, _state, make_automatic);
11414 0 : dst->epsa = src->epsa;
11415 0 : dst->epsb = src->epsb;
11416 0 : dst->epsc = src->epsc;
11417 0 : dst->maxits = src->maxits;
11418 0 : dst->xrep = src->xrep;
11419 0 : dst->xupdated = src->xupdated;
11420 0 : dst->needmv = src->needmv;
11421 0 : dst->needmtv = src->needmtv;
11422 0 : dst->needmv2 = src->needmv2;
11423 0 : dst->needvmv = src->needvmv;
11424 0 : dst->needprec = src->needprec;
11425 0 : dst->repiterationscount = src->repiterationscount;
11426 0 : dst->repnmv = src->repnmv;
11427 0 : dst->repterminationtype = src->repterminationtype;
11428 0 : dst->running = src->running;
11429 0 : dst->userterminationneeded = src->userterminationneeded;
11430 0 : ae_vector_init_copy(&dst->tmpd, &src->tmpd, _state, make_automatic);
11431 0 : ae_vector_init_copy(&dst->tmpx, &src->tmpx, _state, make_automatic);
11432 0 : _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
11433 0 : }
11434 :
11435 :
11436 0 : void _linlsqrstate_clear(void* _p)
11437 : {
11438 0 : linlsqrstate *p = (linlsqrstate*)_p;
11439 0 : ae_touch_ptr((void*)p);
11440 0 : _normestimatorstate_clear(&p->nes);
11441 0 : ae_vector_clear(&p->rx);
11442 0 : ae_vector_clear(&p->b);
11443 0 : ae_vector_clear(&p->ui);
11444 0 : ae_vector_clear(&p->uip1);
11445 0 : ae_vector_clear(&p->vi);
11446 0 : ae_vector_clear(&p->vip1);
11447 0 : ae_vector_clear(&p->omegai);
11448 0 : ae_vector_clear(&p->omegaip1);
11449 0 : ae_vector_clear(&p->d);
11450 0 : ae_vector_clear(&p->x);
11451 0 : ae_vector_clear(&p->mv);
11452 0 : ae_vector_clear(&p->mtv);
11453 0 : ae_vector_clear(&p->tmpd);
11454 0 : ae_vector_clear(&p->tmpx);
11455 0 : _rcommstate_clear(&p->rstate);
11456 0 : }
11457 :
11458 :
11459 0 : void _linlsqrstate_destroy(void* _p)
11460 : {
11461 0 : linlsqrstate *p = (linlsqrstate*)_p;
11462 0 : ae_touch_ptr((void*)p);
11463 0 : _normestimatorstate_destroy(&p->nes);
11464 0 : ae_vector_destroy(&p->rx);
11465 0 : ae_vector_destroy(&p->b);
11466 0 : ae_vector_destroy(&p->ui);
11467 0 : ae_vector_destroy(&p->uip1);
11468 0 : ae_vector_destroy(&p->vi);
11469 0 : ae_vector_destroy(&p->vip1);
11470 0 : ae_vector_destroy(&p->omegai);
11471 0 : ae_vector_destroy(&p->omegaip1);
11472 0 : ae_vector_destroy(&p->d);
11473 0 : ae_vector_destroy(&p->x);
11474 0 : ae_vector_destroy(&p->mv);
11475 0 : ae_vector_destroy(&p->mtv);
11476 0 : ae_vector_destroy(&p->tmpd);
11477 0 : ae_vector_destroy(&p->tmpx);
11478 0 : _rcommstate_destroy(&p->rstate);
11479 0 : }
11480 :
11481 :
11482 0 : void _linlsqrreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
11483 : {
11484 0 : linlsqrreport *p = (linlsqrreport*)_p;
11485 0 : ae_touch_ptr((void*)p);
11486 0 : }
11487 :
11488 :
11489 0 : void _linlsqrreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
11490 : {
11491 0 : linlsqrreport *dst = (linlsqrreport*)_dst;
11492 0 : linlsqrreport *src = (linlsqrreport*)_src;
11493 0 : dst->iterationscount = src->iterationscount;
11494 0 : dst->nmv = src->nmv;
11495 0 : dst->terminationtype = src->terminationtype;
11496 0 : }
11497 :
11498 :
11499 0 : void _linlsqrreport_clear(void* _p)
11500 : {
11501 0 : linlsqrreport *p = (linlsqrreport*)_p;
11502 0 : ae_touch_ptr((void*)p);
11503 0 : }
11504 :
11505 :
11506 0 : void _linlsqrreport_destroy(void* _p)
11507 : {
11508 0 : linlsqrreport *p = (linlsqrreport*)_p;
11509 0 : ae_touch_ptr((void*)p);
11510 0 : }
11511 :
11512 :
11513 : #endif
11514 : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
11515 :
11516 :
11517 : /*************************************************************************
11518 : Polynomial root finding.
11519 :
11520 : This function returns all roots of the polynomial
11521 : P(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
11522 : Both real and complex roots are returned (see below).
11523 :
11524 : INPUT PARAMETERS:
11525 : A - array[N+1], polynomial coefficients:
11526 : * A[0] is constant term
11527 : * A[N] is a coefficient of X^N
11528 : N - polynomial degree
11529 :
11530 : OUTPUT PARAMETERS:
11531 : X - array of complex roots:
11532 : * for isolated real root, X[I] is strictly real: IMAGE(X[I])=0
11533 : * complex roots are always returned in pairs - roots occupy
11534 : positions I and I+1, with:
11535 : * X[I+1]=Conj(X[I])
11536 : * IMAGE(X[I]) > 0
11537 : * IMAGE(X[I+1]) = -IMAGE(X[I]) < 0
11538 : * multiple real roots may have non-zero imaginary part due
11539 : to roundoff errors. There is no reliable way to distinguish
11540 : real root of multiplicity 2 from two complex roots in
11541 : the presence of roundoff errors.
11542 : Rep - report, additional information, following fields are set:
11543 : * Rep.MaxErr - max( |P(xi)| ) for i=0..N-1. This field
11544 : allows to quickly estimate "quality" of the roots being
11545 : returned.
11546 :
11547 : NOTE: this function uses companion matrix method to find roots. In case
11548 : internal EVD solver fails do find eigenvalues, exception is
11549 : generated.
11550 :
11551 : NOTE: roots are not "polished" and no matrix balancing is performed
11552 : for them.
11553 :
11554 : -- ALGLIB --
11555 : Copyright 24.02.2014 by Bochkanov Sergey
11556 : *************************************************************************/
11557 0 : void polynomialsolve(/* Real */ ae_vector* a,
11558 : ae_int_t n,
11559 : /* Complex */ ae_vector* x,
11560 : polynomialsolverreport* rep,
11561 : ae_state *_state)
11562 : {
11563 : ae_frame _frame_block;
11564 : ae_vector _a;
11565 : ae_matrix c;
11566 : ae_matrix vl;
11567 : ae_matrix vr;
11568 : ae_vector wr;
11569 : ae_vector wi;
11570 : ae_int_t i;
11571 : ae_int_t j;
11572 : ae_bool status;
11573 : ae_int_t nz;
11574 : ae_int_t ne;
11575 : ae_complex v;
11576 : ae_complex vv;
11577 :
11578 0 : ae_frame_make(_state, &_frame_block);
11579 0 : memset(&_a, 0, sizeof(_a));
11580 0 : memset(&c, 0, sizeof(c));
11581 0 : memset(&vl, 0, sizeof(vl));
11582 0 : memset(&vr, 0, sizeof(vr));
11583 0 : memset(&wr, 0, sizeof(wr));
11584 0 : memset(&wi, 0, sizeof(wi));
11585 0 : ae_vector_init_copy(&_a, a, _state, ae_true);
11586 0 : a = &_a;
11587 0 : ae_vector_clear(x);
11588 0 : _polynomialsolverreport_clear(rep);
11589 0 : ae_matrix_init(&c, 0, 0, DT_REAL, _state, ae_true);
11590 0 : ae_matrix_init(&vl, 0, 0, DT_REAL, _state, ae_true);
11591 0 : ae_matrix_init(&vr, 0, 0, DT_REAL, _state, ae_true);
11592 0 : ae_vector_init(&wr, 0, DT_REAL, _state, ae_true);
11593 0 : ae_vector_init(&wi, 0, DT_REAL, _state, ae_true);
11594 :
11595 0 : ae_assert(n>0, "PolynomialSolve: N<=0", _state);
11596 0 : ae_assert(a->cnt>=n+1, "PolynomialSolve: Length(A)<N+1", _state);
11597 0 : ae_assert(isfinitevector(a, n+1, _state), "PolynomialSolve: A contains infitite numbers", _state);
11598 0 : ae_assert(ae_fp_neq(a->ptr.p_double[n],(double)(0)), "PolynomialSolve: A[N]=0", _state);
11599 :
11600 : /*
11601 : * Prepare
11602 : */
11603 0 : ae_vector_set_length(x, n, _state);
11604 :
11605 : /*
11606 : * Normalize A:
11607 : * * analytically determine NZ zero roots
11608 : * * quick exit for NZ=N
11609 : * * make residual NE-th degree polynomial monic
11610 : * (here NE=N-NZ)
11611 : */
11612 0 : nz = 0;
11613 0 : while(nz<n&&ae_fp_eq(a->ptr.p_double[nz],(double)(0)))
11614 : {
11615 0 : nz = nz+1;
11616 : }
11617 0 : ne = n-nz;
11618 0 : for(i=nz; i<=n; i++)
11619 : {
11620 0 : a->ptr.p_double[i-nz] = a->ptr.p_double[i]/a->ptr.p_double[n];
11621 : }
11622 :
11623 : /*
11624 : * For NZ<N, build companion matrix and find NE non-zero roots
11625 : */
11626 0 : if( ne>0 )
11627 : {
11628 0 : ae_matrix_set_length(&c, ne, ne, _state);
11629 0 : for(i=0; i<=ne-1; i++)
11630 : {
11631 0 : for(j=0; j<=ne-1; j++)
11632 : {
11633 0 : c.ptr.pp_double[i][j] = (double)(0);
11634 : }
11635 : }
11636 0 : c.ptr.pp_double[0][ne-1] = -a->ptr.p_double[0];
11637 0 : for(i=1; i<=ne-1; i++)
11638 : {
11639 0 : c.ptr.pp_double[i][i-1] = (double)(1);
11640 0 : c.ptr.pp_double[i][ne-1] = -a->ptr.p_double[i];
11641 : }
11642 0 : status = rmatrixevd(&c, ne, 0, &wr, &wi, &vl, &vr, _state);
11643 0 : ae_assert(status, "PolynomialSolve: inernal error - EVD solver failed", _state);
11644 0 : for(i=0; i<=ne-1; i++)
11645 : {
11646 0 : x->ptr.p_complex[i].x = wr.ptr.p_double[i];
11647 0 : x->ptr.p_complex[i].y = wi.ptr.p_double[i];
11648 : }
11649 : }
11650 :
11651 : /*
11652 : * Remaining NZ zero roots
11653 : */
11654 0 : for(i=ne; i<=n-1; i++)
11655 : {
11656 0 : x->ptr.p_complex[i] = ae_complex_from_i(0);
11657 : }
11658 :
11659 : /*
11660 : * Rep
11661 : */
11662 0 : rep->maxerr = (double)(0);
11663 0 : for(i=0; i<=ne-1; i++)
11664 : {
11665 0 : v = ae_complex_from_i(0);
11666 0 : vv = ae_complex_from_i(1);
11667 0 : for(j=0; j<=ne; j++)
11668 : {
11669 0 : v = ae_c_add(v,ae_c_mul_d(vv,a->ptr.p_double[j]));
11670 0 : vv = ae_c_mul(vv,x->ptr.p_complex[i]);
11671 : }
11672 0 : rep->maxerr = ae_maxreal(rep->maxerr, ae_c_abs(v, _state), _state);
11673 : }
11674 0 : ae_frame_leave(_state);
11675 0 : }
11676 :
11677 :
11678 0 : void _polynomialsolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
11679 : {
11680 0 : polynomialsolverreport *p = (polynomialsolverreport*)_p;
11681 0 : ae_touch_ptr((void*)p);
11682 0 : }
11683 :
11684 :
11685 0 : void _polynomialsolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
11686 : {
11687 0 : polynomialsolverreport *dst = (polynomialsolverreport*)_dst;
11688 0 : polynomialsolverreport *src = (polynomialsolverreport*)_src;
11689 0 : dst->maxerr = src->maxerr;
11690 0 : }
11691 :
11692 :
11693 0 : void _polynomialsolverreport_clear(void* _p)
11694 : {
11695 0 : polynomialsolverreport *p = (polynomialsolverreport*)_p;
11696 0 : ae_touch_ptr((void*)p);
11697 0 : }
11698 :
11699 :
11700 0 : void _polynomialsolverreport_destroy(void* _p)
11701 : {
11702 0 : polynomialsolverreport *p = (polynomialsolverreport*)_p;
11703 0 : ae_touch_ptr((void*)p);
11704 0 : }
11705 :
11706 :
11707 : #endif
11708 : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
11709 :
11710 :
11711 : /*************************************************************************
11712 : LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
11713 :
11714 : DESCRIPTION:
11715 : This algorithm solves system of nonlinear equations
11716 : F[0](x[0], ..., x[n-1]) = 0
11717 : F[1](x[0], ..., x[n-1]) = 0
11718 : ...
11719 : F[M-1](x[0], ..., x[n-1]) = 0
11720 : with M/N do not necessarily coincide. Algorithm converges quadratically
11721 : under following conditions:
11722 : * the solution set XS is nonempty
11723 : * for some xs in XS there exist such neighbourhood N(xs) that:
11724 : * vector function F(x) and its Jacobian J(x) are continuously
11725 : differentiable on N
11726 : * ||F(x)|| provides local error bound on N, i.e. there exists such
11727 : c1, that ||F(x)||>c1*distance(x,XS)
11728 : Note that these conditions are much more weaker than usual non-singularity
11729 : conditions. For example, algorithm will converge for any affine function
11730 : F (whether its Jacobian singular or not).
11731 :
11732 :
11733 : REQUIREMENTS:
11734 : Algorithm will request following information during its operation:
11735 : * function vector F[] and Jacobian matrix at given point X
11736 : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
11737 :
11738 :
11739 : USAGE:
11740 : 1. User initializes algorithm state with NLEQCreateLM() call
11741 : 2. User tunes solver parameters with NLEQSetCond(), NLEQSetStpMax() and
11742 : other functions
11743 : 3. User calls NLEQSolve() function which takes algorithm state and
11744 : pointers (delegates, etc.) to callback functions which calculate merit
11745 : function value and Jacobian.
11746 : 4. User calls NLEQResults() to get solution
11747 : 5. Optionally, user may call NLEQRestartFrom() to solve another problem
11748 : with same parameters (N/M) but another starting point and/or another
11749 : function vector. NLEQRestartFrom() allows to reuse already initialized
11750 : structure.
11751 :
11752 :
11753 : INPUT PARAMETERS:
11754 : N - space dimension, N>1:
11755 : * if provided, only leading N elements of X are used
11756 : * if not provided, determined automatically from size of X
11757 : M - system size
11758 : X - starting point
11759 :
11760 :
11761 : OUTPUT PARAMETERS:
11762 : State - structure which stores algorithm state
11763 :
11764 :
11765 : NOTES:
11766 : 1. you may tune stopping conditions with NLEQSetCond() function
11767 : 2. if target function contains exp() or other fast growing functions, and
11768 : optimization algorithm makes too large steps which leads to overflow,
11769 : use NLEQSetStpMax() function to bound algorithm's steps.
11770 : 3. this algorithm is a slightly modified implementation of the method
11771 : described in 'Levenberg-Marquardt method for constrained nonlinear
11772 : equations with strong local convergence properties' by Christian Kanzow
11773 : Nobuo Yamashita and Masao Fukushima and further developed in 'On the
11774 : convergence of a New Levenberg-Marquardt Method' by Jin-yan Fan and
11775 : Ya-Xiang Yuan.
11776 :
11777 :
11778 : -- ALGLIB --
11779 : Copyright 20.08.2009 by Bochkanov Sergey
11780 : *************************************************************************/
11781 0 : void nleqcreatelm(ae_int_t n,
11782 : ae_int_t m,
11783 : /* Real */ ae_vector* x,
11784 : nleqstate* state,
11785 : ae_state *_state)
11786 : {
11787 :
11788 0 : _nleqstate_clear(state);
11789 :
11790 0 : ae_assert(n>=1, "NLEQCreateLM: N<1!", _state);
11791 0 : ae_assert(m>=1, "NLEQCreateLM: M<1!", _state);
11792 0 : ae_assert(x->cnt>=n, "NLEQCreateLM: Length(X)<N!", _state);
11793 0 : ae_assert(isfinitevector(x, n, _state), "NLEQCreateLM: X contains infinite or NaN values!", _state);
11794 :
11795 : /*
11796 : * Initialize
11797 : */
11798 0 : state->n = n;
11799 0 : state->m = m;
11800 0 : nleqsetcond(state, (double)(0), 0, _state);
11801 0 : nleqsetxrep(state, ae_false, _state);
11802 0 : nleqsetstpmax(state, (double)(0), _state);
11803 0 : ae_vector_set_length(&state->x, n, _state);
11804 0 : ae_vector_set_length(&state->xbase, n, _state);
11805 0 : ae_matrix_set_length(&state->j, m, n, _state);
11806 0 : ae_vector_set_length(&state->fi, m, _state);
11807 0 : ae_vector_set_length(&state->rightpart, n, _state);
11808 0 : ae_vector_set_length(&state->candstep, n, _state);
11809 0 : nleqrestartfrom(state, x, _state);
11810 0 : }
11811 :
11812 :
11813 : /*************************************************************************
11814 : This function sets stopping conditions for the nonlinear solver
11815 :
11816 : INPUT PARAMETERS:
11817 : State - structure which stores algorithm state
11818 : EpsF - >=0
11819 : The subroutine finishes its work if on k+1-th iteration
11820 : the condition ||F||<=EpsF is satisfied
11821 : MaxIts - maximum number of iterations. If MaxIts=0, the number of
11822 : iterations is unlimited.
11823 :
11824 : Passing EpsF=0 and MaxIts=0 simultaneously will lead to automatic
11825 : stopping criterion selection (small EpsF).
11826 :
11827 : NOTES:
11828 :
11829 : -- ALGLIB --
11830 : Copyright 20.08.2010 by Bochkanov Sergey
11831 : *************************************************************************/
11832 0 : void nleqsetcond(nleqstate* state,
11833 : double epsf,
11834 : ae_int_t maxits,
11835 : ae_state *_state)
11836 : {
11837 :
11838 :
11839 0 : ae_assert(ae_isfinite(epsf, _state), "NLEQSetCond: EpsF is not finite number!", _state);
11840 0 : ae_assert(ae_fp_greater_eq(epsf,(double)(0)), "NLEQSetCond: negative EpsF!", _state);
11841 0 : ae_assert(maxits>=0, "NLEQSetCond: negative MaxIts!", _state);
11842 0 : if( ae_fp_eq(epsf,(double)(0))&&maxits==0 )
11843 : {
11844 0 : epsf = 1.0E-6;
11845 : }
11846 0 : state->epsf = epsf;
11847 0 : state->maxits = maxits;
11848 0 : }
11849 :
11850 :
11851 : /*************************************************************************
11852 : This function turns on/off reporting.
11853 :
11854 : INPUT PARAMETERS:
11855 : State - structure which stores algorithm state
11856 : NeedXRep- whether iteration reports are needed or not
11857 :
11858 : If NeedXRep is True, algorithm will call rep() callback function if it is
11859 : provided to NLEQSolve().
11860 :
11861 : -- ALGLIB --
11862 : Copyright 20.08.2010 by Bochkanov Sergey
11863 : *************************************************************************/
11864 0 : void nleqsetxrep(nleqstate* state, ae_bool needxrep, ae_state *_state)
11865 : {
11866 :
11867 :
11868 0 : state->xrep = needxrep;
11869 0 : }
11870 :
11871 :
11872 : /*************************************************************************
11873 : This function sets maximum step length
11874 :
11875 : INPUT PARAMETERS:
11876 : State - structure which stores algorithm state
11877 : StpMax - maximum step length, >=0. Set StpMax to 0.0, if you don't
11878 : want to limit step length.
11879 :
11880 : Use this subroutine when target function contains exp() or other fast
11881 : growing functions, and algorithm makes too large steps which lead to
11882 : overflow. This function allows us to reject steps that are too large (and
11883 : therefore expose us to the possible overflow) without actually calculating
11884 : function value at the x+stp*d.
11885 :
11886 : -- ALGLIB --
11887 : Copyright 20.08.2010 by Bochkanov Sergey
11888 : *************************************************************************/
11889 0 : void nleqsetstpmax(nleqstate* state, double stpmax, ae_state *_state)
11890 : {
11891 :
11892 :
11893 0 : ae_assert(ae_isfinite(stpmax, _state), "NLEQSetStpMax: StpMax is not finite!", _state);
11894 0 : ae_assert(ae_fp_greater_eq(stpmax,(double)(0)), "NLEQSetStpMax: StpMax<0!", _state);
11895 0 : state->stpmax = stpmax;
11896 0 : }
11897 :
11898 :
11899 : /*************************************************************************
11900 :
11901 : -- ALGLIB --
11902 : Copyright 20.03.2009 by Bochkanov Sergey
11903 : *************************************************************************/
11904 0 : ae_bool nleqiteration(nleqstate* state, ae_state *_state)
11905 : {
11906 : ae_int_t n;
11907 : ae_int_t m;
11908 : ae_int_t i;
11909 : double lambdaup;
11910 : double lambdadown;
11911 : double lambdav;
11912 : double rho;
11913 : double mu;
11914 : double stepnorm;
11915 : ae_bool b;
11916 : ae_bool result;
11917 :
11918 :
11919 :
11920 : /*
11921 : * Reverse communication preparations
11922 : * I know it looks ugly, but it works the same way
11923 : * anywhere from C++ to Python.
11924 : *
11925 : * This code initializes locals by:
11926 : * * random values determined during code
11927 : * generation - on first subroutine call
11928 : * * values from previous call - on subsequent calls
11929 : */
11930 0 : if( state->rstate.stage>=0 )
11931 : {
11932 0 : n = state->rstate.ia.ptr.p_int[0];
11933 0 : m = state->rstate.ia.ptr.p_int[1];
11934 0 : i = state->rstate.ia.ptr.p_int[2];
11935 0 : b = state->rstate.ba.ptr.p_bool[0];
11936 0 : lambdaup = state->rstate.ra.ptr.p_double[0];
11937 0 : lambdadown = state->rstate.ra.ptr.p_double[1];
11938 0 : lambdav = state->rstate.ra.ptr.p_double[2];
11939 0 : rho = state->rstate.ra.ptr.p_double[3];
11940 0 : mu = state->rstate.ra.ptr.p_double[4];
11941 0 : stepnorm = state->rstate.ra.ptr.p_double[5];
11942 : }
11943 : else
11944 : {
11945 0 : n = 359;
11946 0 : m = -58;
11947 0 : i = -919;
11948 0 : b = ae_true;
11949 0 : lambdaup = 81;
11950 0 : lambdadown = 255;
11951 0 : lambdav = 74;
11952 0 : rho = -788;
11953 0 : mu = 809;
11954 0 : stepnorm = 205;
11955 : }
11956 0 : if( state->rstate.stage==0 )
11957 : {
11958 0 : goto lbl_0;
11959 : }
11960 0 : if( state->rstate.stage==1 )
11961 : {
11962 0 : goto lbl_1;
11963 : }
11964 0 : if( state->rstate.stage==2 )
11965 : {
11966 0 : goto lbl_2;
11967 : }
11968 0 : if( state->rstate.stage==3 )
11969 : {
11970 0 : goto lbl_3;
11971 : }
11972 0 : if( state->rstate.stage==4 )
11973 : {
11974 0 : goto lbl_4;
11975 : }
11976 :
11977 : /*
11978 : * Routine body
11979 : */
11980 :
11981 : /*
11982 : * Prepare
11983 : */
11984 0 : n = state->n;
11985 0 : m = state->m;
11986 0 : state->repterminationtype = 0;
11987 0 : state->repiterationscount = 0;
11988 0 : state->repnfunc = 0;
11989 0 : state->repnjac = 0;
11990 :
11991 : /*
11992 : * Calculate F/G, initialize algorithm
11993 : */
11994 0 : nleq_clearrequestfields(state, _state);
11995 0 : state->needf = ae_true;
11996 0 : state->rstate.stage = 0;
11997 0 : goto lbl_rcomm;
11998 0 : lbl_0:
11999 0 : state->needf = ae_false;
12000 0 : state->repnfunc = state->repnfunc+1;
12001 0 : ae_v_move(&state->xbase.ptr.p_double[0], 1, &state->x.ptr.p_double[0], 1, ae_v_len(0,n-1));
12002 0 : state->fbase = state->f;
12003 0 : state->fprev = ae_maxrealnumber;
12004 0 : if( !state->xrep )
12005 : {
12006 0 : goto lbl_5;
12007 : }
12008 :
12009 : /*
12010 : * progress report
12011 : */
12012 0 : nleq_clearrequestfields(state, _state);
12013 0 : state->xupdated = ae_true;
12014 0 : state->rstate.stage = 1;
12015 0 : goto lbl_rcomm;
12016 0 : lbl_1:
12017 0 : state->xupdated = ae_false;
12018 0 : lbl_5:
12019 0 : if( ae_fp_less_eq(state->f,ae_sqr(state->epsf, _state)) )
12020 : {
12021 0 : state->repterminationtype = 1;
12022 0 : result = ae_false;
12023 0 : return result;
12024 : }
12025 :
12026 : /*
12027 : * Main cycle
12028 : */
12029 0 : lambdaup = (double)(10);
12030 0 : lambdadown = 0.3;
12031 0 : lambdav = 0.001;
12032 0 : rho = (double)(1);
12033 0 : lbl_7:
12034 : if( ae_false )
12035 : {
12036 : goto lbl_8;
12037 : }
12038 :
12039 : /*
12040 : * Get Jacobian;
12041 : * before we get to this point we already have State.XBase filled
12042 : * with current point and State.FBase filled with function value
12043 : * at XBase
12044 : */
12045 0 : nleq_clearrequestfields(state, _state);
12046 0 : state->needfij = ae_true;
12047 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
12048 0 : state->rstate.stage = 2;
12049 0 : goto lbl_rcomm;
12050 0 : lbl_2:
12051 0 : state->needfij = ae_false;
12052 0 : state->repnfunc = state->repnfunc+1;
12053 0 : state->repnjac = state->repnjac+1;
12054 0 : rmatrixmv(n, m, &state->j, 0, 0, 1, &state->fi, 0, &state->rightpart, 0, _state);
12055 0 : ae_v_muld(&state->rightpart.ptr.p_double[0], 1, ae_v_len(0,n-1), -1);
12056 :
12057 : /*
12058 : * Inner cycle: find good lambda
12059 : */
12060 0 : lbl_9:
12061 : if( ae_false )
12062 : {
12063 : goto lbl_10;
12064 : }
12065 :
12066 : /*
12067 : * Solve (J^T*J + (Lambda+Mu)*I)*y = J^T*F
12068 : * to get step d=-y where:
12069 : * * Mu=||F|| - is damping parameter for nonlinear system
12070 : * * Lambda - is additional Levenberg-Marquardt parameter
12071 : * for better convergence when far away from minimum
12072 : */
12073 0 : for(i=0; i<=n-1; i++)
12074 : {
12075 0 : state->candstep.ptr.p_double[i] = (double)(0);
12076 : }
12077 0 : fblssolvecgx(&state->j, m, n, lambdav, &state->rightpart, &state->candstep, &state->cgbuf, _state);
12078 :
12079 : /*
12080 : * Normalize step (it must be no more than StpMax)
12081 : */
12082 0 : stepnorm = (double)(0);
12083 0 : for(i=0; i<=n-1; i++)
12084 : {
12085 0 : if( ae_fp_neq(state->candstep.ptr.p_double[i],(double)(0)) )
12086 : {
12087 0 : stepnorm = (double)(1);
12088 0 : break;
12089 : }
12090 : }
12091 0 : linminnormalized(&state->candstep, &stepnorm, n, _state);
12092 0 : if( ae_fp_neq(state->stpmax,(double)(0)) )
12093 : {
12094 0 : stepnorm = ae_minreal(stepnorm, state->stpmax, _state);
12095 : }
12096 :
12097 : /*
12098 : * Test new step - is it good enough?
12099 : * * if not, Lambda is increased and we try again.
12100 : * * if step is good, we decrease Lambda and move on.
12101 : *
12102 : * We can break this cycle on two occasions:
12103 : * * step is so small that x+step==x (in floating point arithmetics)
12104 : * * lambda is so large
12105 : */
12106 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
12107 0 : ae_v_addd(&state->x.ptr.p_double[0], 1, &state->candstep.ptr.p_double[0], 1, ae_v_len(0,n-1), stepnorm);
12108 0 : b = ae_true;
12109 0 : for(i=0; i<=n-1; i++)
12110 : {
12111 0 : if( ae_fp_neq(state->x.ptr.p_double[i],state->xbase.ptr.p_double[i]) )
12112 : {
12113 0 : b = ae_false;
12114 0 : break;
12115 : }
12116 : }
12117 0 : if( b )
12118 : {
12119 :
12120 : /*
12121 : * Step is too small, force zero step and break
12122 : */
12123 0 : stepnorm = (double)(0);
12124 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
12125 0 : state->f = state->fbase;
12126 0 : goto lbl_10;
12127 : }
12128 0 : nleq_clearrequestfields(state, _state);
12129 0 : state->needf = ae_true;
12130 0 : state->rstate.stage = 3;
12131 0 : goto lbl_rcomm;
12132 0 : lbl_3:
12133 0 : state->needf = ae_false;
12134 0 : state->repnfunc = state->repnfunc+1;
12135 0 : if( ae_fp_less(state->f,state->fbase) )
12136 : {
12137 :
12138 : /*
12139 : * function value decreased, move on
12140 : */
12141 0 : nleq_decreaselambda(&lambdav, &rho, lambdadown, _state);
12142 0 : goto lbl_10;
12143 : }
12144 0 : if( !nleq_increaselambda(&lambdav, &rho, lambdaup, _state) )
12145 : {
12146 :
12147 : /*
12148 : * Lambda is too large (near overflow), force zero step and break
12149 : */
12150 0 : stepnorm = (double)(0);
12151 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
12152 0 : state->f = state->fbase;
12153 0 : goto lbl_10;
12154 : }
12155 0 : goto lbl_9;
12156 0 : lbl_10:
12157 :
12158 : /*
12159 : * Accept step:
12160 : * * new position
12161 : * * new function value
12162 : */
12163 0 : state->fbase = state->f;
12164 0 : ae_v_addd(&state->xbase.ptr.p_double[0], 1, &state->candstep.ptr.p_double[0], 1, ae_v_len(0,n-1), stepnorm);
12165 0 : state->repiterationscount = state->repiterationscount+1;
12166 :
12167 : /*
12168 : * Report new iteration
12169 : */
12170 0 : if( !state->xrep )
12171 : {
12172 0 : goto lbl_11;
12173 : }
12174 0 : nleq_clearrequestfields(state, _state);
12175 0 : state->xupdated = ae_true;
12176 0 : state->f = state->fbase;
12177 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
12178 0 : state->rstate.stage = 4;
12179 0 : goto lbl_rcomm;
12180 0 : lbl_4:
12181 0 : state->xupdated = ae_false;
12182 0 : lbl_11:
12183 :
12184 : /*
12185 : * Test stopping conditions on F, step (zero/non-zero) and MaxIts;
12186 : * If one of the conditions is met, RepTerminationType is changed.
12187 : */
12188 0 : if( ae_fp_less_eq(ae_sqrt(state->f, _state),state->epsf) )
12189 : {
12190 0 : state->repterminationtype = 1;
12191 : }
12192 0 : if( ae_fp_eq(stepnorm,(double)(0))&&state->repterminationtype==0 )
12193 : {
12194 0 : state->repterminationtype = -4;
12195 : }
12196 0 : if( state->repiterationscount>=state->maxits&&state->maxits>0 )
12197 : {
12198 0 : state->repterminationtype = 5;
12199 : }
12200 0 : if( state->repterminationtype!=0 )
12201 : {
12202 0 : goto lbl_8;
12203 : }
12204 :
12205 : /*
12206 : * Now, iteration is finally over
12207 : */
12208 0 : goto lbl_7;
12209 0 : lbl_8:
12210 0 : result = ae_false;
12211 0 : return result;
12212 :
12213 : /*
12214 : * Saving state
12215 : */
12216 0 : lbl_rcomm:
12217 0 : result = ae_true;
12218 0 : state->rstate.ia.ptr.p_int[0] = n;
12219 0 : state->rstate.ia.ptr.p_int[1] = m;
12220 0 : state->rstate.ia.ptr.p_int[2] = i;
12221 0 : state->rstate.ba.ptr.p_bool[0] = b;
12222 0 : state->rstate.ra.ptr.p_double[0] = lambdaup;
12223 0 : state->rstate.ra.ptr.p_double[1] = lambdadown;
12224 0 : state->rstate.ra.ptr.p_double[2] = lambdav;
12225 0 : state->rstate.ra.ptr.p_double[3] = rho;
12226 0 : state->rstate.ra.ptr.p_double[4] = mu;
12227 0 : state->rstate.ra.ptr.p_double[5] = stepnorm;
12228 0 : return result;
12229 : }
12230 :
12231 :
12232 : /*************************************************************************
12233 : NLEQ solver results
12234 :
12235 : INPUT PARAMETERS:
12236 : State - algorithm state.
12237 :
12238 : OUTPUT PARAMETERS:
12239 : X - array[0..N-1], solution
12240 : Rep - optimization report:
12241 : * Rep.TerminationType completetion code:
12242 : * -4 ERROR: algorithm has converged to the
12243 : stationary point Xf which is local minimum of
12244 : f=F[0]^2+...+F[m-1]^2, but is not solution of
12245 : nonlinear system.
12246 : * 1 sqrt(f)<=EpsF.
12247 : * 5 MaxIts steps was taken
12248 : * 7 stopping conditions are too stringent,
12249 : further improvement is impossible
12250 : * Rep.IterationsCount contains iterations count
12251 : * NFEV countains number of function calculations
12252 : * ActiveConstraints contains number of active constraints
12253 :
12254 : -- ALGLIB --
12255 : Copyright 20.08.2009 by Bochkanov Sergey
12256 : *************************************************************************/
12257 0 : void nleqresults(nleqstate* state,
12258 : /* Real */ ae_vector* x,
12259 : nleqreport* rep,
12260 : ae_state *_state)
12261 : {
12262 :
12263 0 : ae_vector_clear(x);
12264 0 : _nleqreport_clear(rep);
12265 :
12266 0 : nleqresultsbuf(state, x, rep, _state);
12267 0 : }
12268 :
12269 :
12270 : /*************************************************************************
12271 : NLEQ solver results
12272 :
12273 : Buffered implementation of NLEQResults(), which uses pre-allocated buffer
12274 : to store X[]. If buffer size is too small, it resizes buffer. It is
12275 : intended to be used in the inner cycles of performance critical algorithms
12276 : where array reallocation penalty is too large to be ignored.
12277 :
12278 : -- ALGLIB --
12279 : Copyright 20.08.2009 by Bochkanov Sergey
12280 : *************************************************************************/
12281 0 : void nleqresultsbuf(nleqstate* state,
12282 : /* Real */ ae_vector* x,
12283 : nleqreport* rep,
12284 : ae_state *_state)
12285 : {
12286 :
12287 :
12288 0 : if( x->cnt<state->n )
12289 : {
12290 0 : ae_vector_set_length(x, state->n, _state);
12291 : }
12292 0 : ae_v_move(&x->ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
12293 0 : rep->iterationscount = state->repiterationscount;
12294 0 : rep->nfunc = state->repnfunc;
12295 0 : rep->njac = state->repnjac;
12296 0 : rep->terminationtype = state->repterminationtype;
12297 0 : }
12298 :
12299 :
12300 : /*************************************************************************
12301 : This subroutine restarts CG algorithm from new point. All optimization
12302 : parameters are left unchanged.
12303 :
12304 : This function allows to solve multiple optimization problems (which
12305 : must have same number of dimensions) without object reallocation penalty.
12306 :
12307 : INPUT PARAMETERS:
12308 : State - structure used for reverse communication previously
12309 : allocated with MinCGCreate call.
12310 : X - new starting point.
12311 : BndL - new lower bounds
12312 : BndU - new upper bounds
12313 :
12314 : -- ALGLIB --
12315 : Copyright 30.07.2010 by Bochkanov Sergey
12316 : *************************************************************************/
12317 0 : void nleqrestartfrom(nleqstate* state,
12318 : /* Real */ ae_vector* x,
12319 : ae_state *_state)
12320 : {
12321 :
12322 :
12323 0 : ae_assert(x->cnt>=state->n, "NLEQRestartFrom: Length(X)<N!", _state);
12324 0 : ae_assert(isfinitevector(x, state->n, _state), "NLEQRestartFrom: X contains infinite or NaN values!", _state);
12325 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
12326 0 : ae_vector_set_length(&state->rstate.ia, 2+1, _state);
12327 0 : ae_vector_set_length(&state->rstate.ba, 0+1, _state);
12328 0 : ae_vector_set_length(&state->rstate.ra, 5+1, _state);
12329 0 : state->rstate.stage = -1;
12330 0 : nleq_clearrequestfields(state, _state);
12331 0 : }
12332 :
12333 :
12334 : /*************************************************************************
12335 : Clears request fileds (to be sure that we don't forgot to clear something)
12336 : *************************************************************************/
12337 0 : static void nleq_clearrequestfields(nleqstate* state, ae_state *_state)
12338 : {
12339 :
12340 :
12341 0 : state->needf = ae_false;
12342 0 : state->needfij = ae_false;
12343 0 : state->xupdated = ae_false;
12344 0 : }
12345 :
12346 :
12347 : /*************************************************************************
12348 : Increases lambda, returns False when there is a danger of overflow
12349 : *************************************************************************/
12350 0 : static ae_bool nleq_increaselambda(double* lambdav,
12351 : double* nu,
12352 : double lambdaup,
12353 : ae_state *_state)
12354 : {
12355 : double lnlambda;
12356 : double lnnu;
12357 : double lnlambdaup;
12358 : double lnmax;
12359 : ae_bool result;
12360 :
12361 :
12362 0 : result = ae_false;
12363 0 : lnlambda = ae_log(*lambdav, _state);
12364 0 : lnlambdaup = ae_log(lambdaup, _state);
12365 0 : lnnu = ae_log(*nu, _state);
12366 0 : lnmax = 0.5*ae_log(ae_maxrealnumber, _state);
12367 0 : if( ae_fp_greater(lnlambda+lnlambdaup+lnnu,lnmax) )
12368 : {
12369 0 : return result;
12370 : }
12371 0 : if( ae_fp_greater(lnnu+ae_log((double)(2), _state),lnmax) )
12372 : {
12373 0 : return result;
12374 : }
12375 0 : *lambdav = *lambdav*lambdaup*(*nu);
12376 0 : *nu = *nu*2;
12377 0 : result = ae_true;
12378 0 : return result;
12379 : }
12380 :
12381 :
12382 : /*************************************************************************
12383 : Decreases lambda, but leaves it unchanged when there is danger of underflow.
12384 : *************************************************************************/
12385 0 : static void nleq_decreaselambda(double* lambdav,
12386 : double* nu,
12387 : double lambdadown,
12388 : ae_state *_state)
12389 : {
12390 :
12391 :
12392 0 : *nu = (double)(1);
12393 0 : if( ae_fp_less(ae_log(*lambdav, _state)+ae_log(lambdadown, _state),ae_log(ae_minrealnumber, _state)) )
12394 : {
12395 0 : *lambdav = ae_minrealnumber;
12396 : }
12397 : else
12398 : {
12399 0 : *lambdav = *lambdav*lambdadown;
12400 : }
12401 0 : }
12402 :
12403 :
12404 0 : void _nleqstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
12405 : {
12406 0 : nleqstate *p = (nleqstate*)_p;
12407 0 : ae_touch_ptr((void*)p);
12408 0 : ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
12409 0 : ae_vector_init(&p->fi, 0, DT_REAL, _state, make_automatic);
12410 0 : ae_matrix_init(&p->j, 0, 0, DT_REAL, _state, make_automatic);
12411 0 : _rcommstate_init(&p->rstate, _state, make_automatic);
12412 0 : ae_vector_init(&p->xbase, 0, DT_REAL, _state, make_automatic);
12413 0 : ae_vector_init(&p->candstep, 0, DT_REAL, _state, make_automatic);
12414 0 : ae_vector_init(&p->rightpart, 0, DT_REAL, _state, make_automatic);
12415 0 : ae_vector_init(&p->cgbuf, 0, DT_REAL, _state, make_automatic);
12416 0 : }
12417 :
12418 :
12419 0 : void _nleqstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
12420 : {
12421 0 : nleqstate *dst = (nleqstate*)_dst;
12422 0 : nleqstate *src = (nleqstate*)_src;
12423 0 : dst->n = src->n;
12424 0 : dst->m = src->m;
12425 0 : dst->epsf = src->epsf;
12426 0 : dst->maxits = src->maxits;
12427 0 : dst->xrep = src->xrep;
12428 0 : dst->stpmax = src->stpmax;
12429 0 : ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
12430 0 : dst->f = src->f;
12431 0 : ae_vector_init_copy(&dst->fi, &src->fi, _state, make_automatic);
12432 0 : ae_matrix_init_copy(&dst->j, &src->j, _state, make_automatic);
12433 0 : dst->needf = src->needf;
12434 0 : dst->needfij = src->needfij;
12435 0 : dst->xupdated = src->xupdated;
12436 0 : _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
12437 0 : dst->repiterationscount = src->repiterationscount;
12438 0 : dst->repnfunc = src->repnfunc;
12439 0 : dst->repnjac = src->repnjac;
12440 0 : dst->repterminationtype = src->repterminationtype;
12441 0 : ae_vector_init_copy(&dst->xbase, &src->xbase, _state, make_automatic);
12442 0 : dst->fbase = src->fbase;
12443 0 : dst->fprev = src->fprev;
12444 0 : ae_vector_init_copy(&dst->candstep, &src->candstep, _state, make_automatic);
12445 0 : ae_vector_init_copy(&dst->rightpart, &src->rightpart, _state, make_automatic);
12446 0 : ae_vector_init_copy(&dst->cgbuf, &src->cgbuf, _state, make_automatic);
12447 0 : }
12448 :
12449 :
12450 0 : void _nleqstate_clear(void* _p)
12451 : {
12452 0 : nleqstate *p = (nleqstate*)_p;
12453 0 : ae_touch_ptr((void*)p);
12454 0 : ae_vector_clear(&p->x);
12455 0 : ae_vector_clear(&p->fi);
12456 0 : ae_matrix_clear(&p->j);
12457 0 : _rcommstate_clear(&p->rstate);
12458 0 : ae_vector_clear(&p->xbase);
12459 0 : ae_vector_clear(&p->candstep);
12460 0 : ae_vector_clear(&p->rightpart);
12461 0 : ae_vector_clear(&p->cgbuf);
12462 0 : }
12463 :
12464 :
12465 0 : void _nleqstate_destroy(void* _p)
12466 : {
12467 0 : nleqstate *p = (nleqstate*)_p;
12468 0 : ae_touch_ptr((void*)p);
12469 0 : ae_vector_destroy(&p->x);
12470 0 : ae_vector_destroy(&p->fi);
12471 0 : ae_matrix_destroy(&p->j);
12472 0 : _rcommstate_destroy(&p->rstate);
12473 0 : ae_vector_destroy(&p->xbase);
12474 0 : ae_vector_destroy(&p->candstep);
12475 0 : ae_vector_destroy(&p->rightpart);
12476 0 : ae_vector_destroy(&p->cgbuf);
12477 0 : }
12478 :
12479 :
12480 0 : void _nleqreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
12481 : {
12482 0 : nleqreport *p = (nleqreport*)_p;
12483 0 : ae_touch_ptr((void*)p);
12484 0 : }
12485 :
12486 :
12487 0 : void _nleqreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
12488 : {
12489 0 : nleqreport *dst = (nleqreport*)_dst;
12490 0 : nleqreport *src = (nleqreport*)_src;
12491 0 : dst->iterationscount = src->iterationscount;
12492 0 : dst->nfunc = src->nfunc;
12493 0 : dst->njac = src->njac;
12494 0 : dst->terminationtype = src->terminationtype;
12495 0 : }
12496 :
12497 :
12498 0 : void _nleqreport_clear(void* _p)
12499 : {
12500 0 : nleqreport *p = (nleqreport*)_p;
12501 0 : ae_touch_ptr((void*)p);
12502 0 : }
12503 :
12504 :
12505 0 : void _nleqreport_destroy(void* _p)
12506 : {
12507 0 : nleqreport *p = (nleqreport*)_p;
12508 0 : ae_touch_ptr((void*)p);
12509 0 : }
12510 :
12511 :
12512 : #endif
12513 : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
12514 :
12515 :
12516 : /*************************************************************************
12517 : Sparse linear solver for A*x=b with N*N sparse real symmetric positive
12518 : definite matrix A, N*1 vectors x and b.
12519 :
12520 : This solver converts input matrix to SKS format, performs Cholesky
12521 : factorization using SKS Cholesky subroutine (works well for limited
12522 : bandwidth matrices) and uses sparse triangular solvers to get solution of
12523 : the original system.
12524 :
12525 : INPUT PARAMETERS
12526 : A - sparse matrix, must be NxN exactly
12527 : IsUpper - which half of A is provided (another half is ignored)
12528 : B - array[0..N-1], right part
12529 :
12530 : OUTPUT PARAMETERS
12531 : X - array[N], it contains:
12532 : * rep.terminationtype>0 => solution
12533 : * rep.terminationtype=-3 => filled by zeros
12534 : Rep - solver report, following fields are set:
12535 : * rep.terminationtype - solver status; >0 for success,
12536 : set to -3 on failure (degenerate or non-SPD system).
12537 :
12538 : -- ALGLIB --
12539 : Copyright 26.12.2017 by Bochkanov Sergey
12540 : *************************************************************************/
12541 0 : void sparsespdsolvesks(sparsematrix* a,
12542 : ae_bool isupper,
12543 : /* Real */ ae_vector* b,
12544 : /* Real */ ae_vector* x,
12545 : sparsesolverreport* rep,
12546 : ae_state *_state)
12547 : {
12548 : ae_frame _frame_block;
12549 : ae_int_t i;
12550 : sparsematrix a2;
12551 : ae_int_t n;
12552 :
12553 0 : ae_frame_make(_state, &_frame_block);
12554 0 : memset(&a2, 0, sizeof(a2));
12555 0 : ae_vector_clear(x);
12556 0 : _sparsesolverreport_clear(rep);
12557 0 : _sparsematrix_init(&a2, _state, ae_true);
12558 :
12559 0 : n = sparsegetnrows(a, _state);
12560 0 : ae_assert(n>0, "SparseSPDSolveSKS: N<=0", _state);
12561 0 : ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDSolveSKS: rows(A)!=N", _state);
12562 0 : ae_assert(sparsegetncols(a, _state)==n, "SparseSPDSolveSKS: cols(A)!=N", _state);
12563 0 : ae_assert(b->cnt>=n, "SparseSPDSolveSKS: length(B)<N", _state);
12564 0 : ae_assert(isfinitevector(b, n, _state), "SparseSPDSolveSKS: B contains infinities or NANs", _state);
12565 0 : directsparsesolvers_initreport(rep, _state);
12566 0 : ae_vector_set_length(x, n, _state);
12567 0 : sparsecopytosks(a, &a2, _state);
12568 0 : if( !sparsecholeskyskyline(&a2, n, isupper, _state) )
12569 : {
12570 0 : rep->terminationtype = -3;
12571 0 : for(i=0; i<=n-1; i++)
12572 : {
12573 0 : x->ptr.p_double[i] = (double)(0);
12574 : }
12575 0 : ae_frame_leave(_state);
12576 0 : return;
12577 : }
12578 0 : for(i=0; i<=n-1; i++)
12579 : {
12580 0 : x->ptr.p_double[i] = b->ptr.p_double[i];
12581 : }
12582 0 : if( isupper )
12583 : {
12584 0 : sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
12585 0 : sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
12586 : }
12587 : else
12588 : {
12589 0 : sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
12590 0 : sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
12591 : }
12592 0 : rep->terminationtype = 1;
12593 0 : ae_frame_leave(_state);
12594 : }
12595 :
12596 :
12597 : /*************************************************************************
12598 : Sparse linear solver for A*x=b with N*N sparse real symmetric positive
12599 : definite matrix A, N*1 vectors x and b.
12600 :
12601 : This solver converts input matrix to CRS format, performs Cholesky
12602 : factorization using supernodal Cholesky decomposition with permutation-
12603 : reducing ordering and uses sparse triangular solver to get solution of the
12604 : original system.
12605 :
12606 : INPUT PARAMETERS
12607 : A - sparse matrix, must be NxN exactly
12608 : IsUpper - which half of A is provided (another half is ignored)
12609 : B - array[N], right part
12610 :
12611 : OUTPUT PARAMETERS
12612 : X - array[N], it contains:
12613 : * rep.terminationtype>0 => solution
12614 : * rep.terminationtype=-3 => filled by zeros
12615 : Rep - solver report, following fields are set:
12616 : * rep.terminationtype - solver status; >0 for success,
12617 : set to -3 on failure (degenerate or non-SPD system).
12618 :
12619 : -- ALGLIB --
12620 : Copyright 26.12.2017 by Bochkanov Sergey
12621 : *************************************************************************/
12622 0 : void sparsespdsolve(sparsematrix* a,
12623 : ae_bool isupper,
12624 : /* Real */ ae_vector* b,
12625 : /* Real */ ae_vector* x,
12626 : sparsesolverreport* rep,
12627 : ae_state *_state)
12628 : {
12629 : ae_frame _frame_block;
12630 : ae_int_t i;
12631 : ae_int_t j;
12632 : sparsematrix a2;
12633 : ae_int_t n;
12634 : double v;
12635 : ae_vector p;
12636 :
12637 0 : ae_frame_make(_state, &_frame_block);
12638 0 : memset(&a2, 0, sizeof(a2));
12639 0 : memset(&p, 0, sizeof(p));
12640 0 : ae_vector_clear(x);
12641 0 : _sparsesolverreport_clear(rep);
12642 0 : _sparsematrix_init(&a2, _state, ae_true);
12643 0 : ae_vector_init(&p, 0, DT_INT, _state, ae_true);
12644 :
12645 0 : n = sparsegetnrows(a, _state);
12646 0 : ae_assert(n>0, "SparseSPDSolve: N<=0", _state);
12647 0 : ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDSolve: rows(A)!=N", _state);
12648 0 : ae_assert(sparsegetncols(a, _state)==n, "SparseSPDSolve: cols(A)!=N", _state);
12649 0 : ae_assert(b->cnt>=n, "SparseSPDSolve: length(B)<N", _state);
12650 0 : ae_assert(isfinitevector(b, n, _state), "SparseSPDSolve: B contains infinities or NANs", _state);
12651 0 : directsparsesolvers_initreport(rep, _state);
12652 0 : sparsecopytocrs(a, &a2, _state);
12653 0 : if( !sparsecholeskyp(&a2, isupper, &p, _state) )
12654 : {
12655 0 : rep->terminationtype = -3;
12656 0 : rsetallocv(n, 0.0, x, _state);
12657 0 : ae_frame_leave(_state);
12658 0 : return;
12659 : }
12660 0 : rcopyallocv(n, b, x, _state);
12661 0 : for(i=0; i<=n-1; i++)
12662 : {
12663 0 : j = p.ptr.p_int[i];
12664 0 : v = x->ptr.p_double[i];
12665 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12666 0 : x->ptr.p_double[j] = v;
12667 : }
12668 0 : if( isupper )
12669 : {
12670 0 : sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
12671 0 : sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
12672 : }
12673 : else
12674 : {
12675 0 : sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
12676 0 : sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
12677 : }
12678 0 : for(i=n-1; i>=0; i--)
12679 : {
12680 0 : j = p.ptr.p_int[i];
12681 0 : v = x->ptr.p_double[i];
12682 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12683 0 : x->ptr.p_double[j] = v;
12684 : }
12685 0 : rep->terminationtype = 1;
12686 0 : ae_frame_leave(_state);
12687 : }
12688 :
12689 :
12690 : /*************************************************************************
12691 : Sparse linear solver for A*x=b with N*N real symmetric positive definite
12692 : matrix A given by its Cholesky decomposition, and N*1 vectors x and b.
12693 :
12694 : IMPORTANT: this solver requires input matrix to be in the SKS (Skyline)
12695 : or CRS (compressed row storage) format. An exception will be
12696 : generated if you pass matrix in some other format.
12697 :
12698 : INPUT PARAMETERS
12699 : A - sparse NxN matrix stored in CRs or SKS format, must be NxN
12700 : exactly
12701 : IsUpper - which half of A is provided (another half is ignored)
12702 : B - array[N], right part
12703 :
12704 : OUTPUT PARAMETERS
12705 : X - array[N], it contains:
12706 : * rep.terminationtype>0 => solution
12707 : * rep.terminationtype=-3 => filled by zeros
12708 : Rep - solver report, following fields are set:
12709 : * rep.terminationtype - solver status; >0 for success,
12710 : set to -3 on failure (degenerate or non-SPD system).
12711 :
12712 : -- ALGLIB --
12713 : Copyright 26.12.2017 by Bochkanov Sergey
12714 : *************************************************************************/
12715 0 : void sparsespdcholeskysolve(sparsematrix* a,
12716 : ae_bool isupper,
12717 : /* Real */ ae_vector* b,
12718 : /* Real */ ae_vector* x,
12719 : sparsesolverreport* rep,
12720 : ae_state *_state)
12721 : {
12722 : ae_int_t i;
12723 : ae_int_t n;
12724 :
12725 0 : ae_vector_clear(x);
12726 0 : _sparsesolverreport_clear(rep);
12727 :
12728 0 : n = sparsegetnrows(a, _state);
12729 0 : ae_assert(n>0, "SparseSPDCholeskySolve: N<=0", _state);
12730 0 : ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDCholeskySolve: rows(A)!=N", _state);
12731 0 : ae_assert(sparsegetncols(a, _state)==n, "SparseSPDCholeskySolve: cols(A)!=N", _state);
12732 0 : ae_assert(sparseissks(a, _state)||sparseiscrs(a, _state), "SparseSPDCholeskySolve: A is not an SKS/CRS matrix", _state);
12733 0 : ae_assert(b->cnt>=n, "SparseSPDCholeskySolve: length(B)<N", _state);
12734 0 : ae_assert(isfinitevector(b, n, _state), "SparseSPDCholeskySolve: B contains infinities or NANs", _state);
12735 0 : directsparsesolvers_initreport(rep, _state);
12736 0 : ae_vector_set_length(x, n, _state);
12737 0 : for(i=0; i<=n-1; i++)
12738 : {
12739 0 : if( ae_fp_eq(sparseget(a, i, i, _state),0.0) )
12740 : {
12741 0 : rep->terminationtype = -3;
12742 0 : for(i=0; i<=n-1; i++)
12743 : {
12744 0 : x->ptr.p_double[i] = (double)(0);
12745 : }
12746 0 : return;
12747 : }
12748 : }
12749 0 : for(i=0; i<=n-1; i++)
12750 : {
12751 0 : x->ptr.p_double[i] = b->ptr.p_double[i];
12752 : }
12753 0 : if( isupper )
12754 : {
12755 0 : sparsetrsv(a, isupper, ae_false, 1, x, _state);
12756 0 : sparsetrsv(a, isupper, ae_false, 0, x, _state);
12757 : }
12758 : else
12759 : {
12760 0 : sparsetrsv(a, isupper, ae_false, 0, x, _state);
12761 0 : sparsetrsv(a, isupper, ae_false, 1, x, _state);
12762 : }
12763 0 : rep->terminationtype = 1;
12764 : }
12765 :
12766 :
12767 : /*************************************************************************
12768 : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
12769 : matrix A, N*1 vectors x and b.
12770 :
12771 : This solver converts input matrix to CRS format, performs LU factorization
12772 : and uses sparse triangular solvers to get solution of the original system.
12773 :
12774 : INPUT PARAMETERS
12775 : A - sparse matrix, must be NxN exactly, any storage format
12776 : N - size of A, N>0
12777 : B - array[0..N-1], right part
12778 :
12779 : OUTPUT PARAMETERS
12780 : X - array[N], it contains:
12781 : * rep.terminationtype>0 => solution
12782 : * rep.terminationtype=-3 => filled by zeros
12783 : Rep - solver report, following fields are set:
12784 : * rep.terminationtype - solver status; >0 for success,
12785 : set to -3 on failure (degenerate system).
12786 :
12787 : -- ALGLIB --
12788 : Copyright 26.12.2017 by Bochkanov Sergey
12789 : *************************************************************************/
12790 0 : void sparsesolve(sparsematrix* a,
12791 : /* Real */ ae_vector* b,
12792 : /* Real */ ae_vector* x,
12793 : sparsesolverreport* rep,
12794 : ae_state *_state)
12795 : {
12796 : ae_frame _frame_block;
12797 : ae_int_t i;
12798 : ae_int_t j;
12799 : ae_int_t n;
12800 : double v;
12801 : sparsematrix a2;
12802 : ae_vector pivp;
12803 : ae_vector pivq;
12804 :
12805 0 : ae_frame_make(_state, &_frame_block);
12806 0 : memset(&a2, 0, sizeof(a2));
12807 0 : memset(&pivp, 0, sizeof(pivp));
12808 0 : memset(&pivq, 0, sizeof(pivq));
12809 0 : ae_vector_clear(x);
12810 0 : _sparsesolverreport_clear(rep);
12811 0 : _sparsematrix_init(&a2, _state, ae_true);
12812 0 : ae_vector_init(&pivp, 0, DT_INT, _state, ae_true);
12813 0 : ae_vector_init(&pivq, 0, DT_INT, _state, ae_true);
12814 :
12815 0 : n = sparsegetnrows(a, _state);
12816 0 : ae_assert(n>0, "SparseSolve: N<=0", _state);
12817 0 : ae_assert(sparsegetnrows(a, _state)==n, "SparseSolve: rows(A)!=N", _state);
12818 0 : ae_assert(sparsegetncols(a, _state)==n, "SparseSolve: cols(A)!=N", _state);
12819 0 : ae_assert(b->cnt>=n, "SparseSolve: length(B)<N", _state);
12820 0 : ae_assert(isfinitevector(b, n, _state), "SparseSolve: B contains infinities or NANs", _state);
12821 0 : directsparsesolvers_initreport(rep, _state);
12822 0 : ae_vector_set_length(x, n, _state);
12823 0 : sparsecopytocrs(a, &a2, _state);
12824 0 : if( !sparselu(&a2, 0, &pivp, &pivq, _state) )
12825 : {
12826 0 : rep->terminationtype = -3;
12827 0 : for(i=0; i<=n-1; i++)
12828 : {
12829 0 : x->ptr.p_double[i] = (double)(0);
12830 : }
12831 0 : ae_frame_leave(_state);
12832 0 : return;
12833 : }
12834 0 : for(i=0; i<=n-1; i++)
12835 : {
12836 0 : x->ptr.p_double[i] = b->ptr.p_double[i];
12837 : }
12838 0 : for(i=0; i<=n-1; i++)
12839 : {
12840 0 : j = pivp.ptr.p_int[i];
12841 0 : v = x->ptr.p_double[i];
12842 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12843 0 : x->ptr.p_double[j] = v;
12844 : }
12845 0 : sparsetrsv(&a2, ae_false, ae_true, 0, x, _state);
12846 0 : sparsetrsv(&a2, ae_true, ae_false, 0, x, _state);
12847 0 : for(i=n-1; i>=0; i--)
12848 : {
12849 0 : j = pivq.ptr.p_int[i];
12850 0 : v = x->ptr.p_double[i];
12851 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12852 0 : x->ptr.p_double[j] = v;
12853 : }
12854 0 : rep->terminationtype = 1;
12855 0 : ae_frame_leave(_state);
12856 : }
12857 :
12858 :
12859 : /*************************************************************************
12860 : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
12861 : matrix A given by its LU factorization, N*1 vectors x and b.
12862 :
12863 : IMPORTANT: this solver requires input matrix to be in the CRS sparse
12864 : storage format. An exception will be generated if you pass
12865 : matrix in some other format (HASH or SKS).
12866 :
12867 : INPUT PARAMETERS
12868 : A - LU factorization of the sparse matrix, must be NxN exactly
12869 : in CRS storage format
12870 : P, Q - pivot indexes from LU factorization
12871 : N - size of A, N>0
12872 : B - array[0..N-1], right part
12873 :
12874 : OUTPUT PARAMETERS
12875 : X - array[N], it contains:
12876 : * rep.terminationtype>0 => solution
12877 : * rep.terminationtype=-3 => filled by zeros
12878 : Rep - solver report, following fields are set:
12879 : * rep.terminationtype - solver status; >0 for success,
12880 : set to -3 on failure (degenerate system).
12881 :
12882 : -- ALGLIB --
12883 : Copyright 26.12.2017 by Bochkanov Sergey
12884 : *************************************************************************/
12885 0 : void sparselusolve(sparsematrix* a,
12886 : /* Integer */ ae_vector* p,
12887 : /* Integer */ ae_vector* q,
12888 : /* Real */ ae_vector* b,
12889 : /* Real */ ae_vector* x,
12890 : sparsesolverreport* rep,
12891 : ae_state *_state)
12892 : {
12893 : ae_int_t i;
12894 : ae_int_t j;
12895 : double v;
12896 : ae_int_t n;
12897 :
12898 0 : ae_vector_clear(x);
12899 0 : _sparsesolverreport_clear(rep);
12900 :
12901 0 : n = sparsegetnrows(a, _state);
12902 0 : ae_assert(n>0, "SparseLUSolve: N<=0", _state);
12903 0 : ae_assert(sparsegetnrows(a, _state)==n, "SparseLUSolve: rows(A)!=N", _state);
12904 0 : ae_assert(sparsegetncols(a, _state)==n, "SparseLUSolve: cols(A)!=N", _state);
12905 0 : ae_assert(sparseiscrs(a, _state), "SparseLUSolve: A is not an SKS matrix", _state);
12906 0 : ae_assert(b->cnt>=n, "SparseLUSolve: length(B)<N", _state);
12907 0 : ae_assert(isfinitevector(b, n, _state), "SparseLUSolve: B contains infinities or NANs", _state);
12908 0 : ae_assert(p->cnt>=n, "SparseLUSolve: length(P)<N", _state);
12909 0 : ae_assert(q->cnt>=n, "SparseLUSolve: length(Q)<N", _state);
12910 0 : for(i=0; i<=n-1; i++)
12911 : {
12912 0 : ae_assert(p->ptr.p_int[i]>=i&&p->ptr.p_int[i]<n, "SparseLUSolve: P is corrupted", _state);
12913 0 : ae_assert(q->ptr.p_int[i]>=i&&q->ptr.p_int[i]<n, "SparseLUSolve: Q is corrupted", _state);
12914 : }
12915 0 : directsparsesolvers_initreport(rep, _state);
12916 0 : ae_vector_set_length(x, n, _state);
12917 0 : for(i=0; i<=n-1; i++)
12918 : {
12919 0 : if( a->didx.ptr.p_int[i]==a->uidx.ptr.p_int[i]||a->vals.ptr.p_double[a->didx.ptr.p_int[i]]==0.0 )
12920 : {
12921 0 : rep->terminationtype = -3;
12922 0 : for(i=0; i<=n-1; i++)
12923 : {
12924 0 : x->ptr.p_double[i] = (double)(0);
12925 : }
12926 0 : return;
12927 : }
12928 : }
12929 0 : for(i=0; i<=n-1; i++)
12930 : {
12931 0 : x->ptr.p_double[i] = b->ptr.p_double[i];
12932 : }
12933 0 : for(i=0; i<=n-1; i++)
12934 : {
12935 0 : j = p->ptr.p_int[i];
12936 0 : v = x->ptr.p_double[i];
12937 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12938 0 : x->ptr.p_double[j] = v;
12939 : }
12940 0 : sparsetrsv(a, ae_false, ae_true, 0, x, _state);
12941 0 : sparsetrsv(a, ae_true, ae_false, 0, x, _state);
12942 0 : for(i=n-1; i>=0; i--)
12943 : {
12944 0 : j = q->ptr.p_int[i];
12945 0 : v = x->ptr.p_double[i];
12946 0 : x->ptr.p_double[i] = x->ptr.p_double[j];
12947 0 : x->ptr.p_double[j] = v;
12948 : }
12949 0 : rep->terminationtype = 1;
12950 : }
12951 :
12952 :
12953 : /*************************************************************************
12954 : Reset report fields
12955 :
12956 : -- ALGLIB --
12957 : Copyright 26.12.2017 by Bochkanov Sergey
12958 : *************************************************************************/
12959 0 : static void directsparsesolvers_initreport(sparsesolverreport* rep,
12960 : ae_state *_state)
12961 : {
12962 :
12963 0 : _sparsesolverreport_clear(rep);
12964 :
12965 0 : rep->terminationtype = 0;
12966 0 : }
12967 :
12968 :
12969 0 : void _sparsesolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
12970 : {
12971 0 : sparsesolverreport *p = (sparsesolverreport*)_p;
12972 0 : ae_touch_ptr((void*)p);
12973 0 : }
12974 :
12975 :
12976 0 : void _sparsesolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
12977 : {
12978 0 : sparsesolverreport *dst = (sparsesolverreport*)_dst;
12979 0 : sparsesolverreport *src = (sparsesolverreport*)_src;
12980 0 : dst->terminationtype = src->terminationtype;
12981 0 : }
12982 :
12983 :
12984 0 : void _sparsesolverreport_clear(void* _p)
12985 : {
12986 0 : sparsesolverreport *p = (sparsesolverreport*)_p;
12987 0 : ae_touch_ptr((void*)p);
12988 0 : }
12989 :
12990 :
12991 0 : void _sparsesolverreport_destroy(void* _p)
12992 : {
12993 0 : sparsesolverreport *p = (sparsesolverreport*)_p;
12994 0 : ae_touch_ptr((void*)p);
12995 0 : }
12996 :
12997 :
12998 : #endif
12999 : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
13000 :
13001 :
13002 : /*************************************************************************
13003 : This function initializes linear CG Solver. This solver is used to solve
13004 : symmetric positive definite problems. If you want to solve nonsymmetric
13005 : (or non-positive definite) problem you may use LinLSQR solver provided by
13006 : ALGLIB.
13007 :
13008 : USAGE:
13009 : 1. User initializes algorithm state with LinCGCreate() call
13010 : 2. User tunes solver parameters with LinCGSetCond() and other functions
13011 : 3. Optionally, user sets starting point with LinCGSetStartingPoint()
13012 : 4. User calls LinCGSolveSparse() function which takes algorithm state and
13013 : SparseMatrix object.
13014 : 5. User calls LinCGResults() to get solution
13015 : 6. Optionally, user may call LinCGSolveSparse() again to solve another
13016 : problem with different matrix and/or right part without reinitializing
13017 : LinCGState structure.
13018 :
13019 : INPUT PARAMETERS:
13020 : N - problem dimension, N>0
13021 :
13022 : OUTPUT PARAMETERS:
13023 : State - structure which stores algorithm state
13024 :
13025 : -- ALGLIB --
13026 : Copyright 14.11.2011 by Bochkanov Sergey
13027 : *************************************************************************/
13028 0 : void lincgcreate(ae_int_t n, lincgstate* state, ae_state *_state)
13029 : {
13030 : ae_int_t i;
13031 :
13032 0 : _lincgstate_clear(state);
13033 :
13034 0 : ae_assert(n>0, "LinCGCreate: N<=0", _state);
13035 0 : state->n = n;
13036 0 : state->prectype = 0;
13037 0 : state->itsbeforerestart = n;
13038 0 : state->itsbeforerupdate = 10;
13039 0 : state->epsf = lincg_defaultprecision;
13040 0 : state->maxits = 0;
13041 0 : state->xrep = ae_false;
13042 0 : state->running = ae_false;
13043 :
13044 : /*
13045 : * * allocate arrays
13046 : * * set RX to NAN (just for the case user calls Results() without
13047 : * calling SolveSparse()
13048 : * * set starting point to zero
13049 : * * we do NOT initialize B here because we assume that user should
13050 : * initializate it using LinCGSetB() function. In case he forgets
13051 : * to do so, exception will be thrown in the LinCGIteration().
13052 : */
13053 0 : ae_vector_set_length(&state->rx, state->n, _state);
13054 0 : ae_vector_set_length(&state->startx, state->n, _state);
13055 0 : ae_vector_set_length(&state->b, state->n, _state);
13056 0 : for(i=0; i<=state->n-1; i++)
13057 : {
13058 0 : state->rx.ptr.p_double[i] = _state->v_nan;
13059 0 : state->startx.ptr.p_double[i] = 0.0;
13060 0 : state->b.ptr.p_double[i] = (double)(0);
13061 : }
13062 0 : ae_vector_set_length(&state->cx, state->n, _state);
13063 0 : ae_vector_set_length(&state->p, state->n, _state);
13064 0 : ae_vector_set_length(&state->r, state->n, _state);
13065 0 : ae_vector_set_length(&state->cr, state->n, _state);
13066 0 : ae_vector_set_length(&state->z, state->n, _state);
13067 0 : ae_vector_set_length(&state->cz, state->n, _state);
13068 0 : ae_vector_set_length(&state->x, state->n, _state);
13069 0 : ae_vector_set_length(&state->mv, state->n, _state);
13070 0 : ae_vector_set_length(&state->pv, state->n, _state);
13071 0 : lincg_updateitersdata(state, _state);
13072 0 : ae_vector_set_length(&state->rstate.ia, 0+1, _state);
13073 0 : ae_vector_set_length(&state->rstate.ra, 2+1, _state);
13074 0 : state->rstate.stage = -1;
13075 0 : }
13076 :
13077 :
13078 : /*************************************************************************
13079 : This function sets starting point.
13080 : By default, zero starting point is used.
13081 :
13082 : INPUT PARAMETERS:
13083 : X - starting point, array[N]
13084 :
13085 : OUTPUT PARAMETERS:
13086 : State - structure which stores algorithm state
13087 :
13088 : -- ALGLIB --
13089 : Copyright 14.11.2011 by Bochkanov Sergey
13090 : *************************************************************************/
13091 0 : void lincgsetstartingpoint(lincgstate* state,
13092 : /* Real */ ae_vector* x,
13093 : ae_state *_state)
13094 : {
13095 :
13096 :
13097 0 : ae_assert(!state->running, "LinCGSetStartingPoint: you can not change starting point because LinCGIteration() function is running", _state);
13098 0 : ae_assert(state->n<=x->cnt, "LinCGSetStartingPoint: Length(X)<N", _state);
13099 0 : ae_assert(isfinitevector(x, state->n, _state), "LinCGSetStartingPoint: X contains infinite or NaN values!", _state);
13100 0 : ae_v_move(&state->startx.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13101 0 : }
13102 :
13103 :
13104 : /*************************************************************************
13105 : This function sets right part. By default, right part is zero.
13106 :
13107 : INPUT PARAMETERS:
13108 : B - right part, array[N].
13109 :
13110 : OUTPUT PARAMETERS:
13111 : State - structure which stores algorithm state
13112 :
13113 : -- ALGLIB --
13114 : Copyright 14.11.2011 by Bochkanov Sergey
13115 : *************************************************************************/
13116 0 : void lincgsetb(lincgstate* state,
13117 : /* Real */ ae_vector* b,
13118 : ae_state *_state)
13119 : {
13120 :
13121 :
13122 0 : ae_assert(!state->running, "LinCGSetB: you can not set B, because function LinCGIteration is running!", _state);
13123 0 : ae_assert(b->cnt>=state->n, "LinCGSetB: Length(B)<N", _state);
13124 0 : ae_assert(isfinitevector(b, state->n, _state), "LinCGSetB: B contains infinite or NaN values!", _state);
13125 0 : ae_v_move(&state->b.ptr.p_double[0], 1, &b->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13126 0 : }
13127 :
13128 :
13129 : /*************************************************************************
13130 : This function changes preconditioning settings of LinCGSolveSparse()
13131 : function. By default, SolveSparse() uses diagonal preconditioner, but if
13132 : you want to use solver without preconditioning, you can call this function
13133 : which forces solver to use unit matrix for preconditioning.
13134 :
13135 : INPUT PARAMETERS:
13136 : State - structure which stores algorithm state
13137 :
13138 : -- ALGLIB --
13139 : Copyright 19.11.2012 by Bochkanov Sergey
13140 : *************************************************************************/
13141 0 : void lincgsetprecunit(lincgstate* state, ae_state *_state)
13142 : {
13143 :
13144 :
13145 0 : ae_assert(!state->running, "LinCGSetPrecUnit: you can not change preconditioner, because function LinCGIteration is running!", _state);
13146 0 : state->prectype = -1;
13147 0 : }
13148 :
13149 :
13150 : /*************************************************************************
13151 : This function changes preconditioning settings of LinCGSolveSparse()
13152 : function. LinCGSolveSparse() will use diagonal of the system matrix as
13153 : preconditioner. This preconditioning mode is active by default.
13154 :
13155 : INPUT PARAMETERS:
13156 : State - structure which stores algorithm state
13157 :
13158 : -- ALGLIB --
13159 : Copyright 19.11.2012 by Bochkanov Sergey
13160 : *************************************************************************/
13161 0 : void lincgsetprecdiag(lincgstate* state, ae_state *_state)
13162 : {
13163 :
13164 :
13165 0 : ae_assert(!state->running, "LinCGSetPrecDiag: you can not change preconditioner, because function LinCGIteration is running!", _state);
13166 0 : state->prectype = 0;
13167 0 : }
13168 :
13169 :
13170 : /*************************************************************************
13171 : This function sets stopping criteria.
13172 :
13173 : INPUT PARAMETERS:
13174 : EpsF - algorithm will be stopped if norm of residual is less than
13175 : EpsF*||b||.
13176 : MaxIts - algorithm will be stopped if number of iterations is more
13177 : than MaxIts.
13178 :
13179 : OUTPUT PARAMETERS:
13180 : State - structure which stores algorithm state
13181 :
13182 : NOTES:
13183 : If both EpsF and MaxIts are zero then small EpsF will be set to small
13184 : value.
13185 :
13186 : -- ALGLIB --
13187 : Copyright 14.11.2011 by Bochkanov Sergey
13188 : *************************************************************************/
13189 0 : void lincgsetcond(lincgstate* state,
13190 : double epsf,
13191 : ae_int_t maxits,
13192 : ae_state *_state)
13193 : {
13194 :
13195 :
13196 0 : ae_assert(!state->running, "LinCGSetCond: you can not change stopping criteria when LinCGIteration() is running", _state);
13197 0 : ae_assert(ae_isfinite(epsf, _state)&&ae_fp_greater_eq(epsf,(double)(0)), "LinCGSetCond: EpsF is negative or contains infinite or NaN values", _state);
13198 0 : ae_assert(maxits>=0, "LinCGSetCond: MaxIts is negative", _state);
13199 0 : if( ae_fp_eq(epsf,(double)(0))&&maxits==0 )
13200 : {
13201 0 : state->epsf = lincg_defaultprecision;
13202 0 : state->maxits = maxits;
13203 : }
13204 : else
13205 : {
13206 0 : state->epsf = epsf;
13207 0 : state->maxits = maxits;
13208 : }
13209 0 : }
13210 :
13211 :
13212 : /*************************************************************************
13213 : Reverse communication version of linear CG.
13214 :
13215 : -- ALGLIB --
13216 : Copyright 14.11.2011 by Bochkanov Sergey
13217 : *************************************************************************/
13218 0 : ae_bool lincgiteration(lincgstate* state, ae_state *_state)
13219 : {
13220 : ae_int_t i;
13221 : double uvar;
13222 : double bnorm;
13223 : double v;
13224 : ae_bool result;
13225 :
13226 :
13227 :
13228 : /*
13229 : * Reverse communication preparations
13230 : * I know it looks ugly, but it works the same way
13231 : * anywhere from C++ to Python.
13232 : *
13233 : * This code initializes locals by:
13234 : * * random values determined during code
13235 : * generation - on first subroutine call
13236 : * * values from previous call - on subsequent calls
13237 : */
13238 0 : if( state->rstate.stage>=0 )
13239 : {
13240 0 : i = state->rstate.ia.ptr.p_int[0];
13241 0 : uvar = state->rstate.ra.ptr.p_double[0];
13242 0 : bnorm = state->rstate.ra.ptr.p_double[1];
13243 0 : v = state->rstate.ra.ptr.p_double[2];
13244 : }
13245 : else
13246 : {
13247 0 : i = 359;
13248 0 : uvar = -58;
13249 0 : bnorm = -919;
13250 0 : v = -909;
13251 : }
13252 0 : if( state->rstate.stage==0 )
13253 : {
13254 0 : goto lbl_0;
13255 : }
13256 0 : if( state->rstate.stage==1 )
13257 : {
13258 0 : goto lbl_1;
13259 : }
13260 0 : if( state->rstate.stage==2 )
13261 : {
13262 0 : goto lbl_2;
13263 : }
13264 0 : if( state->rstate.stage==3 )
13265 : {
13266 0 : goto lbl_3;
13267 : }
13268 0 : if( state->rstate.stage==4 )
13269 : {
13270 0 : goto lbl_4;
13271 : }
13272 0 : if( state->rstate.stage==5 )
13273 : {
13274 0 : goto lbl_5;
13275 : }
13276 0 : if( state->rstate.stage==6 )
13277 : {
13278 0 : goto lbl_6;
13279 : }
13280 0 : if( state->rstate.stage==7 )
13281 : {
13282 0 : goto lbl_7;
13283 : }
13284 :
13285 : /*
13286 : * Routine body
13287 : */
13288 0 : ae_assert(state->b.cnt>0, "LinCGIteration: B is not initialized (you must initialize B by LinCGSetB() call", _state);
13289 0 : state->running = ae_true;
13290 0 : state->repnmv = 0;
13291 0 : lincg_clearrfields(state, _state);
13292 0 : lincg_updateitersdata(state, _state);
13293 :
13294 : /*
13295 : * Start 0-th iteration
13296 : */
13297 0 : ae_v_move(&state->rx.ptr.p_double[0], 1, &state->startx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13298 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13299 0 : state->repnmv = state->repnmv+1;
13300 0 : lincg_clearrfields(state, _state);
13301 0 : state->needvmv = ae_true;
13302 0 : state->rstate.stage = 0;
13303 0 : goto lbl_rcomm;
13304 0 : lbl_0:
13305 0 : state->needvmv = ae_false;
13306 0 : bnorm = (double)(0);
13307 0 : state->r2 = (double)(0);
13308 0 : state->meritfunction = (double)(0);
13309 0 : for(i=0; i<=state->n-1; i++)
13310 : {
13311 0 : state->r.ptr.p_double[i] = state->b.ptr.p_double[i]-state->mv.ptr.p_double[i];
13312 0 : state->r2 = state->r2+state->r.ptr.p_double[i]*state->r.ptr.p_double[i];
13313 0 : state->meritfunction = state->meritfunction+state->mv.ptr.p_double[i]*state->rx.ptr.p_double[i]-2*state->b.ptr.p_double[i]*state->rx.ptr.p_double[i];
13314 0 : bnorm = bnorm+state->b.ptr.p_double[i]*state->b.ptr.p_double[i];
13315 : }
13316 0 : bnorm = ae_sqrt(bnorm, _state);
13317 :
13318 : /*
13319 : * Output first report
13320 : */
13321 0 : if( !state->xrep )
13322 : {
13323 0 : goto lbl_8;
13324 : }
13325 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13326 0 : lincg_clearrfields(state, _state);
13327 0 : state->xupdated = ae_true;
13328 0 : state->rstate.stage = 1;
13329 0 : goto lbl_rcomm;
13330 0 : lbl_1:
13331 0 : state->xupdated = ae_false;
13332 0 : lbl_8:
13333 :
13334 : /*
13335 : * Is x0 a solution?
13336 : */
13337 0 : if( !ae_isfinite(state->r2, _state)||ae_fp_less_eq(ae_sqrt(state->r2, _state),state->epsf*bnorm) )
13338 : {
13339 0 : state->running = ae_false;
13340 0 : if( ae_isfinite(state->r2, _state) )
13341 : {
13342 0 : state->repterminationtype = 1;
13343 : }
13344 : else
13345 : {
13346 0 : state->repterminationtype = -4;
13347 : }
13348 0 : result = ae_false;
13349 0 : return result;
13350 : }
13351 :
13352 : /*
13353 : * Calculate Z and P
13354 : */
13355 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->r.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13356 0 : state->repnmv = state->repnmv+1;
13357 0 : lincg_clearrfields(state, _state);
13358 0 : state->needprec = ae_true;
13359 0 : state->rstate.stage = 2;
13360 0 : goto lbl_rcomm;
13361 0 : lbl_2:
13362 0 : state->needprec = ae_false;
13363 0 : for(i=0; i<=state->n-1; i++)
13364 : {
13365 0 : state->z.ptr.p_double[i] = state->pv.ptr.p_double[i];
13366 0 : state->p.ptr.p_double[i] = state->z.ptr.p_double[i];
13367 : }
13368 :
13369 : /*
13370 : * Other iterations(1..N)
13371 : */
13372 0 : state->repiterationscount = 0;
13373 0 : lbl_10:
13374 : if( ae_false )
13375 : {
13376 : goto lbl_11;
13377 : }
13378 0 : state->repiterationscount = state->repiterationscount+1;
13379 :
13380 : /*
13381 : * Calculate Alpha
13382 : */
13383 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->p.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13384 0 : state->repnmv = state->repnmv+1;
13385 0 : lincg_clearrfields(state, _state);
13386 0 : state->needvmv = ae_true;
13387 0 : state->rstate.stage = 3;
13388 0 : goto lbl_rcomm;
13389 0 : lbl_3:
13390 0 : state->needvmv = ae_false;
13391 0 : if( !ae_isfinite(state->vmv, _state)||ae_fp_less_eq(state->vmv,(double)(0)) )
13392 : {
13393 :
13394 : /*
13395 : * a) Overflow when calculating VMV
13396 : * b) non-positive VMV (non-SPD matrix)
13397 : */
13398 0 : state->running = ae_false;
13399 0 : if( ae_isfinite(state->vmv, _state) )
13400 : {
13401 0 : state->repterminationtype = -5;
13402 : }
13403 : else
13404 : {
13405 0 : state->repterminationtype = -4;
13406 : }
13407 0 : result = ae_false;
13408 0 : return result;
13409 : }
13410 0 : state->alpha = (double)(0);
13411 0 : for(i=0; i<=state->n-1; i++)
13412 : {
13413 0 : state->alpha = state->alpha+state->r.ptr.p_double[i]*state->z.ptr.p_double[i];
13414 : }
13415 0 : state->alpha = state->alpha/state->vmv;
13416 0 : if( !ae_isfinite(state->alpha, _state) )
13417 : {
13418 :
13419 : /*
13420 : * Overflow when calculating Alpha
13421 : */
13422 0 : state->running = ae_false;
13423 0 : state->repterminationtype = -4;
13424 0 : result = ae_false;
13425 0 : return result;
13426 : }
13427 :
13428 : /*
13429 : * Next step toward solution
13430 : */
13431 0 : for(i=0; i<=state->n-1; i++)
13432 : {
13433 0 : state->cx.ptr.p_double[i] = state->rx.ptr.p_double[i]+state->alpha*state->p.ptr.p_double[i];
13434 : }
13435 :
13436 : /*
13437 : * Calculate R:
13438 : * * use recurrent relation to update R
13439 : * * at every ItsBeforeRUpdate-th iteration recalculate it from scratch, using matrix-vector product
13440 : * in case R grows instead of decreasing, algorithm is terminated with positive completion code
13441 : */
13442 0 : if( !(state->itsbeforerupdate==0||state->repiterationscount%state->itsbeforerupdate!=0) )
13443 : {
13444 0 : goto lbl_12;
13445 : }
13446 :
13447 : /*
13448 : * Calculate R using recurrent formula
13449 : */
13450 0 : for(i=0; i<=state->n-1; i++)
13451 : {
13452 0 : state->cr.ptr.p_double[i] = state->r.ptr.p_double[i]-state->alpha*state->mv.ptr.p_double[i];
13453 0 : state->x.ptr.p_double[i] = state->cr.ptr.p_double[i];
13454 : }
13455 0 : goto lbl_13;
13456 0 : lbl_12:
13457 :
13458 : /*
13459 : * Calculate R using matrix-vector multiplication
13460 : */
13461 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->cx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13462 0 : state->repnmv = state->repnmv+1;
13463 0 : lincg_clearrfields(state, _state);
13464 0 : state->needmv = ae_true;
13465 0 : state->rstate.stage = 4;
13466 0 : goto lbl_rcomm;
13467 0 : lbl_4:
13468 0 : state->needmv = ae_false;
13469 0 : for(i=0; i<=state->n-1; i++)
13470 : {
13471 0 : state->cr.ptr.p_double[i] = state->b.ptr.p_double[i]-state->mv.ptr.p_double[i];
13472 0 : state->x.ptr.p_double[i] = state->cr.ptr.p_double[i];
13473 : }
13474 :
13475 : /*
13476 : * Calculating merit function
13477 : * Check emergency stopping criterion
13478 : */
13479 0 : v = (double)(0);
13480 0 : for(i=0; i<=state->n-1; i++)
13481 : {
13482 0 : v = v+state->mv.ptr.p_double[i]*state->cx.ptr.p_double[i]-2*state->b.ptr.p_double[i]*state->cx.ptr.p_double[i];
13483 : }
13484 0 : if( ae_fp_less(v,state->meritfunction) )
13485 : {
13486 0 : goto lbl_14;
13487 : }
13488 0 : for(i=0; i<=state->n-1; i++)
13489 : {
13490 0 : if( !ae_isfinite(state->rx.ptr.p_double[i], _state) )
13491 : {
13492 0 : state->running = ae_false;
13493 0 : state->repterminationtype = -4;
13494 0 : result = ae_false;
13495 0 : return result;
13496 : }
13497 : }
13498 :
13499 : /*
13500 : *output last report
13501 : */
13502 0 : if( !state->xrep )
13503 : {
13504 0 : goto lbl_16;
13505 : }
13506 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13507 0 : lincg_clearrfields(state, _state);
13508 0 : state->xupdated = ae_true;
13509 0 : state->rstate.stage = 5;
13510 0 : goto lbl_rcomm;
13511 0 : lbl_5:
13512 0 : state->xupdated = ae_false;
13513 0 : lbl_16:
13514 0 : state->running = ae_false;
13515 0 : state->repterminationtype = 7;
13516 0 : result = ae_false;
13517 0 : return result;
13518 0 : lbl_14:
13519 0 : state->meritfunction = v;
13520 0 : lbl_13:
13521 0 : ae_v_move(&state->rx.ptr.p_double[0], 1, &state->cx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13522 :
13523 : /*
13524 : * calculating RNorm
13525 : *
13526 : * NOTE: monotonic decrease of R2 is not guaranteed by algorithm.
13527 : */
13528 0 : state->r2 = (double)(0);
13529 0 : for(i=0; i<=state->n-1; i++)
13530 : {
13531 0 : state->r2 = state->r2+state->cr.ptr.p_double[i]*state->cr.ptr.p_double[i];
13532 : }
13533 :
13534 : /*
13535 : *output report
13536 : */
13537 0 : if( !state->xrep )
13538 : {
13539 0 : goto lbl_18;
13540 : }
13541 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13542 0 : lincg_clearrfields(state, _state);
13543 0 : state->xupdated = ae_true;
13544 0 : state->rstate.stage = 6;
13545 0 : goto lbl_rcomm;
13546 0 : lbl_6:
13547 0 : state->xupdated = ae_false;
13548 0 : lbl_18:
13549 :
13550 : /*
13551 : *stopping criterion
13552 : *achieved the required precision
13553 : */
13554 0 : if( !ae_isfinite(state->r2, _state)||ae_fp_less_eq(ae_sqrt(state->r2, _state),state->epsf*bnorm) )
13555 : {
13556 0 : state->running = ae_false;
13557 0 : if( ae_isfinite(state->r2, _state) )
13558 : {
13559 0 : state->repterminationtype = 1;
13560 : }
13561 : else
13562 : {
13563 0 : state->repterminationtype = -4;
13564 : }
13565 0 : result = ae_false;
13566 0 : return result;
13567 : }
13568 0 : if( state->repiterationscount>=state->maxits&&state->maxits>0 )
13569 : {
13570 0 : for(i=0; i<=state->n-1; i++)
13571 : {
13572 0 : if( !ae_isfinite(state->rx.ptr.p_double[i], _state) )
13573 : {
13574 0 : state->running = ae_false;
13575 0 : state->repterminationtype = -4;
13576 0 : result = ae_false;
13577 0 : return result;
13578 : }
13579 : }
13580 :
13581 : /*
13582 : *if X is finite number
13583 : */
13584 0 : state->running = ae_false;
13585 0 : state->repterminationtype = 5;
13586 0 : result = ae_false;
13587 0 : return result;
13588 : }
13589 0 : ae_v_move(&state->x.ptr.p_double[0], 1, &state->cr.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13590 :
13591 : /*
13592 : *prepere of parameters for next iteration
13593 : */
13594 0 : state->repnmv = state->repnmv+1;
13595 0 : lincg_clearrfields(state, _state);
13596 0 : state->needprec = ae_true;
13597 0 : state->rstate.stage = 7;
13598 0 : goto lbl_rcomm;
13599 0 : lbl_7:
13600 0 : state->needprec = ae_false;
13601 0 : ae_v_move(&state->cz.ptr.p_double[0], 1, &state->pv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13602 0 : if( state->repiterationscount%state->itsbeforerestart!=0 )
13603 : {
13604 0 : state->beta = (double)(0);
13605 0 : uvar = (double)(0);
13606 0 : for(i=0; i<=state->n-1; i++)
13607 : {
13608 0 : state->beta = state->beta+state->cz.ptr.p_double[i]*state->cr.ptr.p_double[i];
13609 0 : uvar = uvar+state->z.ptr.p_double[i]*state->r.ptr.p_double[i];
13610 : }
13611 :
13612 : /*
13613 : *check that UVar is't INF or is't zero
13614 : */
13615 0 : if( !ae_isfinite(uvar, _state)||ae_fp_eq(uvar,(double)(0)) )
13616 : {
13617 0 : state->running = ae_false;
13618 0 : state->repterminationtype = -4;
13619 0 : result = ae_false;
13620 0 : return result;
13621 : }
13622 :
13623 : /*
13624 : *calculate .BETA
13625 : */
13626 0 : state->beta = state->beta/uvar;
13627 :
13628 : /*
13629 : *check that .BETA neither INF nor NaN
13630 : */
13631 0 : if( !ae_isfinite(state->beta, _state) )
13632 : {
13633 0 : state->running = ae_false;
13634 0 : state->repterminationtype = -1;
13635 0 : result = ae_false;
13636 0 : return result;
13637 : }
13638 0 : for(i=0; i<=state->n-1; i++)
13639 : {
13640 0 : state->p.ptr.p_double[i] = state->cz.ptr.p_double[i]+state->beta*state->p.ptr.p_double[i];
13641 : }
13642 : }
13643 : else
13644 : {
13645 0 : ae_v_move(&state->p.ptr.p_double[0], 1, &state->cz.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13646 : }
13647 :
13648 : /*
13649 : *prepere data for next iteration
13650 : */
13651 0 : for(i=0; i<=state->n-1; i++)
13652 : {
13653 :
13654 : /*
13655 : *write (k+1)th iteration to (k )th iteration
13656 : */
13657 0 : state->r.ptr.p_double[i] = state->cr.ptr.p_double[i];
13658 0 : state->z.ptr.p_double[i] = state->cz.ptr.p_double[i];
13659 : }
13660 0 : goto lbl_10;
13661 : lbl_11:
13662 : result = ae_false;
13663 : return result;
13664 :
13665 : /*
13666 : * Saving state
13667 : */
13668 0 : lbl_rcomm:
13669 0 : result = ae_true;
13670 0 : state->rstate.ia.ptr.p_int[0] = i;
13671 0 : state->rstate.ra.ptr.p_double[0] = uvar;
13672 0 : state->rstate.ra.ptr.p_double[1] = bnorm;
13673 0 : state->rstate.ra.ptr.p_double[2] = v;
13674 0 : return result;
13675 : }
13676 :
13677 :
13678 : /*************************************************************************
13679 : Procedure for solution of A*x=b with sparse A.
13680 :
13681 : INPUT PARAMETERS:
13682 : State - algorithm state
13683 : A - sparse matrix in the CRS format (you MUST contvert it to
13684 : CRS format by calling SparseConvertToCRS() function).
13685 : IsUpper - whether upper or lower triangle of A is used:
13686 : * IsUpper=True => only upper triangle is used and lower
13687 : triangle is not referenced at all
13688 : * IsUpper=False => only lower triangle is used and upper
13689 : triangle is not referenced at all
13690 : B - right part, array[N]
13691 :
13692 : RESULT:
13693 : This function returns no result.
13694 : You can get solution by calling LinCGResults()
13695 :
13696 : NOTE: this function uses lightweight preconditioning - multiplication by
13697 : inverse of diag(A). If you want, you can turn preconditioning off by
13698 : calling LinCGSetPrecUnit(). However, preconditioning cost is low and
13699 : preconditioner is very important for solution of badly scaled
13700 : problems.
13701 :
13702 : -- ALGLIB --
13703 : Copyright 14.11.2011 by Bochkanov Sergey
13704 : *************************************************************************/
13705 0 : void lincgsolvesparse(lincgstate* state,
13706 : sparsematrix* a,
13707 : ae_bool isupper,
13708 : /* Real */ ae_vector* b,
13709 : ae_state *_state)
13710 : {
13711 : ae_int_t n;
13712 : ae_int_t i;
13713 : double v;
13714 : double vmv;
13715 :
13716 :
13717 0 : n = state->n;
13718 0 : ae_assert(b->cnt>=state->n, "LinCGSetB: Length(B)<N", _state);
13719 0 : ae_assert(isfinitevector(b, state->n, _state), "LinCGSetB: B contains infinite or NaN values!", _state);
13720 :
13721 : /*
13722 : * Allocate temporaries
13723 : */
13724 0 : rvectorsetlengthatleast(&state->tmpd, n, _state);
13725 :
13726 : /*
13727 : * Compute diagonal scaling matrix D
13728 : */
13729 0 : if( state->prectype==0 )
13730 : {
13731 :
13732 : /*
13733 : * Default preconditioner - inverse of matrix diagonal
13734 : */
13735 0 : for(i=0; i<=n-1; i++)
13736 : {
13737 0 : v = sparsegetdiagonal(a, i, _state);
13738 0 : if( ae_fp_greater(v,(double)(0)) )
13739 : {
13740 0 : state->tmpd.ptr.p_double[i] = 1/ae_sqrt(v, _state);
13741 : }
13742 : else
13743 : {
13744 0 : state->tmpd.ptr.p_double[i] = (double)(1);
13745 : }
13746 : }
13747 : }
13748 : else
13749 : {
13750 :
13751 : /*
13752 : * No diagonal scaling
13753 : */
13754 0 : for(i=0; i<=n-1; i++)
13755 : {
13756 0 : state->tmpd.ptr.p_double[i] = (double)(1);
13757 : }
13758 : }
13759 :
13760 : /*
13761 : * Solve
13762 : */
13763 0 : lincgrestart(state, _state);
13764 0 : lincgsetb(state, b, _state);
13765 0 : while(lincgiteration(state, _state))
13766 : {
13767 :
13768 : /*
13769 : * Process different requests from optimizer
13770 : */
13771 0 : if( state->needmv )
13772 : {
13773 0 : sparsesmv(a, isupper, &state->x, &state->mv, _state);
13774 : }
13775 0 : if( state->needvmv )
13776 : {
13777 0 : sparsesmv(a, isupper, &state->x, &state->mv, _state);
13778 0 : vmv = ae_v_dotproduct(&state->x.ptr.p_double[0], 1, &state->mv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13779 0 : state->vmv = vmv;
13780 : }
13781 0 : if( state->needprec )
13782 : {
13783 0 : for(i=0; i<=n-1; i++)
13784 : {
13785 0 : state->pv.ptr.p_double[i] = state->x.ptr.p_double[i]*ae_sqr(state->tmpd.ptr.p_double[i], _state);
13786 : }
13787 : }
13788 : }
13789 0 : }
13790 :
13791 :
13792 : /*************************************************************************
13793 : CG-solver: results.
13794 :
13795 : This function must be called after LinCGSolve
13796 :
13797 : INPUT PARAMETERS:
13798 : State - algorithm state
13799 :
13800 : OUTPUT PARAMETERS:
13801 : X - array[N], solution
13802 : Rep - optimization report:
13803 : * Rep.TerminationType completetion code:
13804 : * -5 input matrix is either not positive definite,
13805 : too large or too small
13806 : * -4 overflow/underflow during solution
13807 : (ill conditioned problem)
13808 : * 1 ||residual||<=EpsF*||b||
13809 : * 5 MaxIts steps was taken
13810 : * 7 rounding errors prevent further progress,
13811 : best point found is returned
13812 : * Rep.IterationsCount contains iterations count
13813 : * NMV countains number of matrix-vector calculations
13814 :
13815 : -- ALGLIB --
13816 : Copyright 14.11.2011 by Bochkanov Sergey
13817 : *************************************************************************/
13818 0 : void lincgresults(lincgstate* state,
13819 : /* Real */ ae_vector* x,
13820 : lincgreport* rep,
13821 : ae_state *_state)
13822 : {
13823 :
13824 0 : ae_vector_clear(x);
13825 0 : _lincgreport_clear(rep);
13826 :
13827 0 : ae_assert(!state->running, "LinCGResult: you can not get result, because function LinCGIteration has been launched!", _state);
13828 0 : if( x->cnt<state->n )
13829 : {
13830 0 : ae_vector_set_length(x, state->n, _state);
13831 : }
13832 0 : ae_v_move(&x->ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
13833 0 : rep->iterationscount = state->repiterationscount;
13834 0 : rep->nmv = state->repnmv;
13835 0 : rep->terminationtype = state->repterminationtype;
13836 0 : rep->r2 = state->r2;
13837 0 : }
13838 :
13839 :
13840 : /*************************************************************************
13841 : This function sets restart frequency. By default, algorithm is restarted
13842 : after N subsequent iterations.
13843 :
13844 : -- ALGLIB --
13845 : Copyright 14.11.2011 by Bochkanov Sergey
13846 : *************************************************************************/
13847 0 : void lincgsetrestartfreq(lincgstate* state,
13848 : ae_int_t srf,
13849 : ae_state *_state)
13850 : {
13851 :
13852 :
13853 0 : ae_assert(!state->running, "LinCGSetRestartFreq: you can not change restart frequency when LinCGIteration() is running", _state);
13854 0 : ae_assert(srf>0, "LinCGSetRestartFreq: non-positive SRF", _state);
13855 0 : state->itsbeforerestart = srf;
13856 0 : }
13857 :
13858 :
13859 : /*************************************************************************
13860 : This function sets frequency of residual recalculations.
13861 :
13862 : Algorithm updates residual r_k using iterative formula, but recalculates
13863 : it from scratch after each 10 iterations. It is done to avoid accumulation
13864 : of numerical errors and to stop algorithm when r_k starts to grow.
13865 :
13866 : Such low update frequence (1/10) gives very little overhead, but makes
13867 : algorithm a bit more robust against numerical errors. However, you may
13868 : change it
13869 :
13870 : INPUT PARAMETERS:
13871 : Freq - desired update frequency, Freq>=0.
13872 : Zero value means that no updates will be done.
13873 :
13874 : -- ALGLIB --
13875 : Copyright 14.11.2011 by Bochkanov Sergey
13876 : *************************************************************************/
13877 0 : void lincgsetrupdatefreq(lincgstate* state,
13878 : ae_int_t freq,
13879 : ae_state *_state)
13880 : {
13881 :
13882 :
13883 0 : ae_assert(!state->running, "LinCGSetRUpdateFreq: you can not change update frequency when LinCGIteration() is running", _state);
13884 0 : ae_assert(freq>=0, "LinCGSetRUpdateFreq: non-positive Freq", _state);
13885 0 : state->itsbeforerupdate = freq;
13886 0 : }
13887 :
13888 :
13889 : /*************************************************************************
13890 : This function turns on/off reporting.
13891 :
13892 : INPUT PARAMETERS:
13893 : State - structure which stores algorithm state
13894 : NeedXRep- whether iteration reports are needed or not
13895 :
13896 : If NeedXRep is True, algorithm will call rep() callback function if it is
13897 : provided to MinCGOptimize().
13898 :
13899 : -- ALGLIB --
13900 : Copyright 14.11.2011 by Bochkanov Sergey
13901 : *************************************************************************/
13902 0 : void lincgsetxrep(lincgstate* state, ae_bool needxrep, ae_state *_state)
13903 : {
13904 :
13905 :
13906 0 : state->xrep = needxrep;
13907 0 : }
13908 :
13909 :
13910 : /*************************************************************************
13911 : Procedure for restart function LinCGIteration
13912 :
13913 : -- ALGLIB --
13914 : Copyright 14.11.2011 by Bochkanov Sergey
13915 : *************************************************************************/
13916 0 : void lincgrestart(lincgstate* state, ae_state *_state)
13917 : {
13918 :
13919 :
13920 0 : ae_vector_set_length(&state->rstate.ia, 0+1, _state);
13921 0 : ae_vector_set_length(&state->rstate.ra, 2+1, _state);
13922 0 : state->rstate.stage = -1;
13923 0 : lincg_clearrfields(state, _state);
13924 0 : }
13925 :
13926 :
13927 : /*************************************************************************
13928 : Clears request fileds (to be sure that we don't forgot to clear something)
13929 : *************************************************************************/
13930 0 : static void lincg_clearrfields(lincgstate* state, ae_state *_state)
13931 : {
13932 :
13933 :
13934 0 : state->xupdated = ae_false;
13935 0 : state->needmv = ae_false;
13936 0 : state->needmtv = ae_false;
13937 0 : state->needmv2 = ae_false;
13938 0 : state->needvmv = ae_false;
13939 0 : state->needprec = ae_false;
13940 0 : }
13941 :
13942 :
13943 : /*************************************************************************
13944 : Clears request fileds (to be sure that we don't forgot to clear something)
13945 : *************************************************************************/
13946 0 : static void lincg_updateitersdata(lincgstate* state, ae_state *_state)
13947 : {
13948 :
13949 :
13950 0 : state->repiterationscount = 0;
13951 0 : state->repnmv = 0;
13952 0 : state->repterminationtype = 0;
13953 0 : }
13954 :
13955 :
13956 0 : void _lincgstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
13957 : {
13958 0 : lincgstate *p = (lincgstate*)_p;
13959 0 : ae_touch_ptr((void*)p);
13960 0 : ae_vector_init(&p->rx, 0, DT_REAL, _state, make_automatic);
13961 0 : ae_vector_init(&p->b, 0, DT_REAL, _state, make_automatic);
13962 0 : ae_vector_init(&p->cx, 0, DT_REAL, _state, make_automatic);
13963 0 : ae_vector_init(&p->cr, 0, DT_REAL, _state, make_automatic);
13964 0 : ae_vector_init(&p->cz, 0, DT_REAL, _state, make_automatic);
13965 0 : ae_vector_init(&p->p, 0, DT_REAL, _state, make_automatic);
13966 0 : ae_vector_init(&p->r, 0, DT_REAL, _state, make_automatic);
13967 0 : ae_vector_init(&p->z, 0, DT_REAL, _state, make_automatic);
13968 0 : ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
13969 0 : ae_vector_init(&p->mv, 0, DT_REAL, _state, make_automatic);
13970 0 : ae_vector_init(&p->pv, 0, DT_REAL, _state, make_automatic);
13971 0 : ae_vector_init(&p->startx, 0, DT_REAL, _state, make_automatic);
13972 0 : ae_vector_init(&p->tmpd, 0, DT_REAL, _state, make_automatic);
13973 0 : _rcommstate_init(&p->rstate, _state, make_automatic);
13974 0 : }
13975 :
13976 :
13977 0 : void _lincgstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
13978 : {
13979 0 : lincgstate *dst = (lincgstate*)_dst;
13980 0 : lincgstate *src = (lincgstate*)_src;
13981 0 : ae_vector_init_copy(&dst->rx, &src->rx, _state, make_automatic);
13982 0 : ae_vector_init_copy(&dst->b, &src->b, _state, make_automatic);
13983 0 : dst->n = src->n;
13984 0 : dst->prectype = src->prectype;
13985 0 : ae_vector_init_copy(&dst->cx, &src->cx, _state, make_automatic);
13986 0 : ae_vector_init_copy(&dst->cr, &src->cr, _state, make_automatic);
13987 0 : ae_vector_init_copy(&dst->cz, &src->cz, _state, make_automatic);
13988 0 : ae_vector_init_copy(&dst->p, &src->p, _state, make_automatic);
13989 0 : ae_vector_init_copy(&dst->r, &src->r, _state, make_automatic);
13990 0 : ae_vector_init_copy(&dst->z, &src->z, _state, make_automatic);
13991 0 : dst->alpha = src->alpha;
13992 0 : dst->beta = src->beta;
13993 0 : dst->r2 = src->r2;
13994 0 : dst->meritfunction = src->meritfunction;
13995 0 : ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
13996 0 : ae_vector_init_copy(&dst->mv, &src->mv, _state, make_automatic);
13997 0 : ae_vector_init_copy(&dst->pv, &src->pv, _state, make_automatic);
13998 0 : dst->vmv = src->vmv;
13999 0 : ae_vector_init_copy(&dst->startx, &src->startx, _state, make_automatic);
14000 0 : dst->epsf = src->epsf;
14001 0 : dst->maxits = src->maxits;
14002 0 : dst->itsbeforerestart = src->itsbeforerestart;
14003 0 : dst->itsbeforerupdate = src->itsbeforerupdate;
14004 0 : dst->xrep = src->xrep;
14005 0 : dst->xupdated = src->xupdated;
14006 0 : dst->needmv = src->needmv;
14007 0 : dst->needmtv = src->needmtv;
14008 0 : dst->needmv2 = src->needmv2;
14009 0 : dst->needvmv = src->needvmv;
14010 0 : dst->needprec = src->needprec;
14011 0 : dst->repiterationscount = src->repiterationscount;
14012 0 : dst->repnmv = src->repnmv;
14013 0 : dst->repterminationtype = src->repterminationtype;
14014 0 : dst->running = src->running;
14015 0 : ae_vector_init_copy(&dst->tmpd, &src->tmpd, _state, make_automatic);
14016 0 : _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
14017 0 : }
14018 :
14019 :
14020 0 : void _lincgstate_clear(void* _p)
14021 : {
14022 0 : lincgstate *p = (lincgstate*)_p;
14023 0 : ae_touch_ptr((void*)p);
14024 0 : ae_vector_clear(&p->rx);
14025 0 : ae_vector_clear(&p->b);
14026 0 : ae_vector_clear(&p->cx);
14027 0 : ae_vector_clear(&p->cr);
14028 0 : ae_vector_clear(&p->cz);
14029 0 : ae_vector_clear(&p->p);
14030 0 : ae_vector_clear(&p->r);
14031 0 : ae_vector_clear(&p->z);
14032 0 : ae_vector_clear(&p->x);
14033 0 : ae_vector_clear(&p->mv);
14034 0 : ae_vector_clear(&p->pv);
14035 0 : ae_vector_clear(&p->startx);
14036 0 : ae_vector_clear(&p->tmpd);
14037 0 : _rcommstate_clear(&p->rstate);
14038 0 : }
14039 :
14040 :
14041 0 : void _lincgstate_destroy(void* _p)
14042 : {
14043 0 : lincgstate *p = (lincgstate*)_p;
14044 0 : ae_touch_ptr((void*)p);
14045 0 : ae_vector_destroy(&p->rx);
14046 0 : ae_vector_destroy(&p->b);
14047 0 : ae_vector_destroy(&p->cx);
14048 0 : ae_vector_destroy(&p->cr);
14049 0 : ae_vector_destroy(&p->cz);
14050 0 : ae_vector_destroy(&p->p);
14051 0 : ae_vector_destroy(&p->r);
14052 0 : ae_vector_destroy(&p->z);
14053 0 : ae_vector_destroy(&p->x);
14054 0 : ae_vector_destroy(&p->mv);
14055 0 : ae_vector_destroy(&p->pv);
14056 0 : ae_vector_destroy(&p->startx);
14057 0 : ae_vector_destroy(&p->tmpd);
14058 0 : _rcommstate_destroy(&p->rstate);
14059 0 : }
14060 :
14061 :
14062 0 : void _lincgreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
14063 : {
14064 0 : lincgreport *p = (lincgreport*)_p;
14065 0 : ae_touch_ptr((void*)p);
14066 0 : }
14067 :
14068 :
14069 0 : void _lincgreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
14070 : {
14071 0 : lincgreport *dst = (lincgreport*)_dst;
14072 0 : lincgreport *src = (lincgreport*)_src;
14073 0 : dst->iterationscount = src->iterationscount;
14074 0 : dst->nmv = src->nmv;
14075 0 : dst->terminationtype = src->terminationtype;
14076 0 : dst->r2 = src->r2;
14077 0 : }
14078 :
14079 :
14080 0 : void _lincgreport_clear(void* _p)
14081 : {
14082 0 : lincgreport *p = (lincgreport*)_p;
14083 0 : ae_touch_ptr((void*)p);
14084 0 : }
14085 :
14086 :
14087 0 : void _lincgreport_destroy(void* _p)
14088 : {
14089 0 : lincgreport *p = (lincgreport*)_p;
14090 0 : ae_touch_ptr((void*)p);
14091 0 : }
14092 :
14093 :
14094 : #endif
14095 :
14096 : }
14097 :
|