comparison liboctave/SparseCmplxLU.cc @ 5282:5bdc3f24cd5f

[project @ 2005-04-14 22:17:26 by dbateman]
author dbateman
date Thu, 14 Apr 2005 22:17:27 +0000
parents 23b37da9fd5b
children 4c8a2e4e0717
comparison
equal deleted inserted replaced
5281:f3266e7dbb99 5282:5bdc3f24cd5f
221 #endif 221 #endif
222 } 222 }
223 223
224 SparseComplexLU::SparseComplexLU (const SparseComplexMatrix& a, 224 SparseComplexLU::SparseComplexLU (const SparseComplexMatrix& a,
225 const ColumnVector& Qinit, 225 const ColumnVector& Qinit,
226 double piv_thres, bool FixedQ) 226 double piv_thres, bool FixedQ,
227 double droptol, bool milu, bool udiag)
227 { 228 {
228 #ifdef HAVE_UMFPACK 229 #ifdef HAVE_UMFPACK
229 octave_idx_type nr = a.rows (); 230 if (milu)
230 octave_idx_type nc = a.cols (); 231 (*current_liboctave_error_handler)
231 232 ("Modified incomplete LU not implemented");
232 // Setup the control parameters
233 Matrix Control (UMFPACK_CONTROL, 1);
234 double *control = Control.fortran_vec ();
235 umfpack_zi_defaults (control);
236
237 double tmp = Voctave_sparse_controls.get_key ("spumoni");
238 if (!xisnan (tmp))
239 Control (UMFPACK_PRL) = tmp;
240 if (piv_thres >= 0.)
241 {
242 piv_thres = (piv_thres > 1. ? 1. : piv_thres);
243 Control (UMFPACK_SYM_PIVOT_TOLERANCE) = piv_thres;
244 Control (UMFPACK_PIVOT_TOLERANCE) = piv_thres;
245 }
246 else 233 else
247 { 234 {
248 tmp = Voctave_sparse_controls.get_key ("piv_tol"); 235 octave_idx_type nr = a.rows ();
236 octave_idx_type nc = a.cols ();
237
238 // Setup the control parameters
239 Matrix Control (UMFPACK_CONTROL, 1);
240 double *control = Control.fortran_vec ();
241 umfpack_zi_defaults (control);
242
243 double tmp = Voctave_sparse_controls.get_key ("spumoni");
249 if (!xisnan (tmp)) 244 if (!xisnan (tmp))
250 { 245 Control (UMFPACK_PRL) = tmp;
251 Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp; 246 if (piv_thres >= 0.)
252 Control (UMFPACK_PIVOT_TOLERANCE) = tmp; 247 {
253 } 248 piv_thres = (piv_thres > 1. ? 1. : piv_thres);
254 } 249 Control (UMFPACK_SYM_PIVOT_TOLERANCE) = piv_thres;
255 250 Control (UMFPACK_PIVOT_TOLERANCE) = piv_thres;
256 // Set whether we are allowed to modify Q or not 251 }
257 if (FixedQ) 252 else
258 Control (UMFPACK_FIXQ) = 1.0; 253 {
259 else 254 tmp = Voctave_sparse_controls.get_key ("piv_tol");
260 { 255 if (!xisnan (tmp))
261 tmp = Voctave_sparse_controls.get_key ("autoamd"); 256 {
262 if (!xisnan (tmp)) 257 Control (UMFPACK_SYM_PIVOT_TOLERANCE) = tmp;
263 Control (UMFPACK_FIXQ) = tmp; 258 Control (UMFPACK_PIVOT_TOLERANCE) = tmp;
264 } 259 }
265 260 }
266 // Turn-off UMFPACK scaling for LU 261
267 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE; 262 if (droptol >= 0.)
268 263 Control (UMFPACK_DROPTOL) = droptol;
269 umfpack_zi_report_control (control); 264
270 265 // Set whether we are allowed to modify Q or not
271 const octave_idx_type *Ap = a.cidx (); 266 if (FixedQ)
272 const octave_idx_type *Ai = a.ridx (); 267 Control (UMFPACK_FIXQ) = 1.0;
273 const Complex *Ax = a.data (); 268 else
274 269 {
275 umfpack_zi_report_matrix (nr, nc, Ap, Ai, X_CAST (const double *, Ax), NULL, 270 tmp = Voctave_sparse_controls.get_key ("autoamd");
276 1, control); 271 if (!xisnan (tmp))
277 272 Control (UMFPACK_FIXQ) = tmp;
278 void *Symbolic; 273 }
279 Matrix Info (1, UMFPACK_INFO); 274
280 double *info = Info.fortran_vec (); 275 // Turn-off UMFPACK scaling for LU
281 int status; 276 Control (UMFPACK_SCALE) = UMFPACK_SCALE_NONE;
282 277
283 // Null loop so that qinit is imediately deallocated when not needed 278 umfpack_zi_report_control (control);
284 do { 279
285 OCTAVE_LOCAL_BUFFER (int, qinit, nc); 280 const octave_idx_type *Ap = a.cidx ();
286 281 const octave_idx_type *Ai = a.ridx ();
287 for (int i = 0; i < nc; i++) 282 const Complex *Ax = a.data ();
288 qinit [i] = static_cast<int> (Qinit (i)); 283
289 284 umfpack_zi_report_matrix (nr, nc, Ap, Ai,
290 status = umfpack_zi_qsymbolic (nr, nc, Ap, Ai, X_CAST (const double *, Ax), 285 X_CAST (const double *, Ax), NULL,
291 NULL, qinit, &Symbolic, control, info); 286 1, control);
292 } while (0); 287
293 288 void *Symbolic;
294 if (status < 0) 289 Matrix Info (1, UMFPACK_INFO);
295 { 290 double *info = Info.fortran_vec ();
296 (*current_liboctave_error_handler) 291 int status;
292
293 // Null loop so that qinit is imediately deallocated when not
294 // needed
295 do {
296 OCTAVE_LOCAL_BUFFER (int, qinit, nc);
297
298 for (int i = 0; i < nc; i++)
299 qinit [i] = static_cast<int> (Qinit (i));
300
301 status = umfpack_zi_qsymbolic (nr, nc, Ap, Ai,
302 X_CAST (const double *, Ax),
303 NULL, qinit, &Symbolic, control,
304 info);
305 } while (0);
306
307 if (status < 0)
308 {
309 (*current_liboctave_error_handler)
297 ("SparseComplexLU::SparseComplexLU symbolic factorization failed"); 310 ("SparseComplexLU::SparseComplexLU symbolic factorization failed");
298
299 umfpack_zi_report_status (control, status);
300 umfpack_zi_report_info (control, info);
301
302 umfpack_zi_free_symbolic (&Symbolic) ;
303 }
304 else
305 {
306 umfpack_zi_report_symbolic (Symbolic, control);
307
308 void *Numeric;
309 status = umfpack_zi_numeric (Ap, Ai, X_CAST (const double *, Ax), NULL,
310 Symbolic, &Numeric, control, info) ;
311 umfpack_zi_free_symbolic (&Symbolic) ;
312
313 cond = Info (UMFPACK_RCOND);
314
315 if (status < 0)
316 {
317 (*current_liboctave_error_handler)
318 ("SparseComplexLU::SparseComplexLU numeric factorization failed");
319 311
320 umfpack_zi_report_status (control, status); 312 umfpack_zi_report_status (control, status);
321 umfpack_zi_report_info (control, info); 313 umfpack_zi_report_info (control, info);
322 314
323 umfpack_zi_free_numeric (&Numeric); 315 umfpack_zi_free_symbolic (&Symbolic) ;
324 } 316 }
325 else 317 else
326 { 318 {
327 umfpack_zi_report_numeric (Numeric, control); 319 umfpack_zi_report_symbolic (Symbolic, control);
328 320
329 int lnz, unz, ignore1, ignore2, ignore3; 321 void *Numeric;
330 status = umfpack_zi_get_lunz (&lnz, &unz, &ignore1, &ignore2, 322 status = umfpack_zi_numeric (Ap, Ai,
331 &ignore3, Numeric) ; 323 X_CAST (const double *, Ax), NULL,
332 324 Symbolic, &Numeric, control, info) ;
325 umfpack_zi_free_symbolic (&Symbolic) ;
326
327 cond = Info (UMFPACK_RCOND);
328
333 if (status < 0) 329 if (status < 0)
334 { 330 {
335 (*current_liboctave_error_handler) 331 (*current_liboctave_error_handler)
336 ("SparseComplexLU::SparseComplexLU extracting LU factors failed"); 332 ("SparseComplexLU::SparseComplexLU numeric factorization failed");
337 333
338 umfpack_zi_report_status (control, status); 334 umfpack_zi_report_status (control, status);
339 umfpack_zi_report_info (control, info); 335 umfpack_zi_report_info (control, info);
340 336
341 umfpack_zi_free_numeric (&Numeric); 337 umfpack_zi_free_numeric (&Numeric);
342 } 338 }
343 else 339 else
344 { 340 {
345 int n_inner = (nr < nc ? nr : nc); 341 umfpack_zi_report_numeric (Numeric, control);
346 342
347 if (lnz < 1) 343 int lnz, unz, ignore1, ignore2, ignore3;
348 Lfact = SparseComplexMatrix (static_cast<octave_idx_type> (n_inner), nr, 344 status = umfpack_zi_get_lunz (&lnz, &unz, &ignore1,
349 static_cast<octave_idx_type> (1)); 345 &ignore2, &ignore3, Numeric);
350 else 346
351 Lfact = SparseComplexMatrix (static_cast<octave_idx_type> (n_inner), nr, 347 if (status < 0)
352 static_cast<octave_idx_type> (lnz));
353
354 octave_idx_type *Ltp = Lfact.cidx ();
355 octave_idx_type *Ltj = Lfact.ridx ();
356 Complex *Ltx = Lfact.data ();
357
358 if (unz < 1)
359 Ufact = SparseComplexMatrix (static_cast<octave_idx_type> (n_inner), nc,
360 static_cast<octave_idx_type> (1));
361 else
362 Ufact = SparseComplexMatrix (static_cast<octave_idx_type> (n_inner), nc, unz);
363
364 octave_idx_type *Up = Ufact.cidx ();
365 octave_idx_type *Uj = Ufact.ridx ();
366 Complex *Ux = Ufact.data ();
367
368 P.resize (nr);
369 int *p = P.fortran_vec ();
370
371 Q.resize (nc);
372 int *q = Q.fortran_vec ();
373
374 int do_recip;
375 status = umfpack_zi_get_numeric (Ltp, Ltj, X_CAST (double *, Ltx),
376 NULL, Up, Uj,
377 X_CAST (double *, Ux), NULL, p,
378 q, NULL, NULL, &do_recip,
379 NULL, Numeric) ;
380
381 umfpack_zi_free_numeric (&Numeric) ;
382
383 if (status < 0 || do_recip)
384 { 348 {
385 (*current_liboctave_error_handler) 349 (*current_liboctave_error_handler)
386 ("SparseComplexLU::SparseComplexLU extracting LU factors failed"); 350 ("SparseComplexLU::SparseComplexLU extracting LU factors failed");
387 351
388 umfpack_zi_report_status (control, status); 352 umfpack_zi_report_status (control, status);
353 umfpack_zi_report_info (control, info);
354
355 umfpack_zi_free_numeric (&Numeric);
389 } 356 }
390 else 357 else
391 { 358 {
392 Lfact = Lfact.transpose (); 359 int n_inner = (nr < nc ? nr : nc);
393 360
394 umfpack_zi_report_matrix (nr, n_inner, Lfact.cidx (), 361 if (lnz < 1)
395 Lfact.ridx (), 362 Lfact = SparseComplexMatrix
396 X_CAST (double *, Lfact.data()), 363 (static_cast<octave_idx_type> (n_inner), nr,
397 NULL, 1, control); 364 static_cast<octave_idx_type> (1));
398 365 else
399 umfpack_zi_report_matrix (n_inner, nc, Ufact.cidx (), 366 Lfact = SparseComplexMatrix
400 Ufact.ridx (), 367 (static_cast<octave_idx_type> (n_inner), nr,
401 X_CAST (double *, Ufact.data()), 368 static_cast<octave_idx_type> (lnz));
402 NULL, 1, control); 369
403 umfpack_zi_report_perm (nr, p, control); 370 octave_idx_type *Ltp = Lfact.cidx ();
404 umfpack_zi_report_perm (nc, q, control); 371 octave_idx_type *Ltj = Lfact.ridx ();
372 Complex *Ltx = Lfact.data ();
373
374 if (unz < 1)
375 Ufact = SparseComplexMatrix
376 (static_cast<octave_idx_type> (n_inner), nc,
377 static_cast<octave_idx_type> (1));
378 else
379 Ufact = SparseComplexMatrix
380 (static_cast<octave_idx_type> (n_inner), nc, unz);
381
382 octave_idx_type *Up = Ufact.cidx ();
383 octave_idx_type *Uj = Ufact.ridx ();
384 Complex *Ux = Ufact.data ();
385
386 P.resize (nr);
387 int *p = P.fortran_vec ();
388
389 Q.resize (nc);
390 int *q = Q.fortran_vec ();
391
392 int do_recip;
393 status =
394 umfpack_zi_get_numeric (Ltp, Ltj,
395 X_CAST (double *, Ltx),
396 NULL, Up, Uj,
397 X_CAST (double *, Ux),
398 NULL, p, q, NULL, NULL,
399 &do_recip, NULL, Numeric) ;
400
401 umfpack_zi_free_numeric (&Numeric) ;
402
403 if (status < 0 || do_recip)
404 {
405 (*current_liboctave_error_handler)
406 ("SparseComplexLU::SparseComplexLU extracting LU factors failed");
407
408 umfpack_zi_report_status (control, status);
409 }
410 else
411 {
412 Lfact = Lfact.transpose ();
413
414 umfpack_zi_report_matrix (nr, n_inner,
415 Lfact.cidx (),
416 Lfact.ridx (),
417 X_CAST (double *, Lfact.data()),
418 NULL, 1, control);
419
420 umfpack_zi_report_matrix (n_inner, nc,
421 Ufact.cidx (),
422 Ufact.ridx (),
423 X_CAST (double *, Ufact.data()),
424 NULL, 1, control);
425 umfpack_zi_report_perm (nr, p, control);
426 umfpack_zi_report_perm (nc, q, control);
427 }
428
429 umfpack_zi_report_info (control, info);
405 } 430 }
406
407 umfpack_zi_report_info (control, info);
408 } 431 }
409 } 432 }
433
434 if (udiag)
435 (*current_liboctave_error_handler)
436 ("Option udiag of incomplete LU not implemented");
410 } 437 }
411 #else 438 #else
412 (*current_liboctave_error_handler) ("UMFPACK not installed"); 439 (*current_liboctave_error_handler) ("UMFPACK not installed");
413 #endif 440 #endif
414 } 441 }