comparison liboctave/dMatrix.cc @ 3466:9ff5622c993e

[project @ 2000-01-21 19:30:46 by hodelas] Fixed expm to use direct application of scaling, permutation operations in step (2) and reverse step (2).
author hodelas
date Fri, 21 Jan 2000 19:30:46 +0000
parents 87721841efd7
children a2dc6de198f9
comparison
equal deleted inserted replaced
3465:996bb7ea4507 3466:9ff5622c993e
1354 // Preconditioning step 2: balancing; code follows development 1354 // Preconditioning step 2: balancing; code follows development
1355 // in AEPBAL 1355 // in AEPBAL
1356 1356
1357 double *p_m = m.fortran_vec (); 1357 double *p_m = m.fortran_vec ();
1358 1358
1359 Array<double> scale(nc); 1359 int info, ilo, ihi,ilos,ihis, ii, jj;
1360 double *pscale = scale.fortran_vec (); 1360 Array<double> dpermute(nc);
1361 1361 Array<double> dscale(nc);
1362 int info, ilo, ihi; 1362 double *dp;
1363 1363
1364 // both scale and permute 1364 char job = 'P'; // permutation first
1365 char job = 'B'; 1365 dp = dpermute.fortran_vec();
1366 1366 F77_XFCN (dgebal, DGEBAL, (&job, nc, p_m, nc, ilo, ihi, dp, info, 1L, 1L));
1367 F77_XFCN (dgebal, DGEBAL, (&job, nc, p_m, nc, ilo, ihi, pscale, info, 1367
1368 1L, 1L)); 1368 job = 'S'; // then scaling
1369 dp = dscale.fortran_vec();
1370 F77_XFCN (dgebal, DGEBAL, (&job, nc, p_m, nc, ilos, ihis, dp, info, 1L, 1L));
1369 1371
1370 if (f77_exception_encountered) 1372 if (f77_exception_encountered)
1371 { 1373 {
1372 (*current_liboctave_error_handler) ("unrecoverable error in dgebal"); 1374 (*current_liboctave_error_handler) ("unrecoverable error in dgebal");
1373 return retval;
1374 }
1375
1376 // construct balancing matrices D, Dinv
1377
1378 Matrix dmat = Matrix (nc, nc, 0.0);
1379 Matrix dinv = Matrix (nc, nc, 0.0);
1380
1381 for (int i = 0; i < nc; i++)
1382 dmat(i,i) = dinv(i,i) = 1.0;
1383
1384 // dgebak, dside=R => dmat := D*dmat
1385 char dside = 'R';
1386 F77_XFCN (dgebak, DGEBAK, (&job, &dside, nc, ilo, ihi, pscale, nc,
1387 dmat.fortran_vec(), nc, info, 1L, 1L));
1388
1389 if (f77_exception_encountered)
1390 {
1391 (*current_liboctave_error_handler) ("unrecoverable error in dgebak");
1392 return retval;
1393 }
1394
1395 // dgebak, dside=L => dinv := dinv*D^{-1}
1396 dside = 'L';
1397 F77_XFCN (dgebak, DGEBAK, (&job, &dside, nc, ilo, ihi, pscale, nc,
1398 dinv.fortran_vec(), nc, info, 1L, 1L));
1399
1400 if (f77_exception_encountered)
1401 {
1402 (*current_liboctave_error_handler) ("unrecoverable error in dgebak");
1403 return retval; 1375 return retval;
1404 } 1376 }
1405 1377
1406 // Preconditioning step 3: scaling. 1378 // Preconditioning step 3: scaling.
1407 1379
1470 retval = retval * retval; 1442 retval = retval * retval;
1471 sqpow--; 1443 sqpow--;
1472 } 1444 }
1473 1445
1474 // Reverse preconditioning step 2: inverse balancing. 1446 // Reverse preconditioning step 2: inverse balancing.
1475 retval = dmat*retval*dinv; 1447 // apply inverse scaling to computed exponential
1476 1448 for(ii = 0; ii < nc ; ii++)
1449 for(jj=0; jj < nc ; jj++)
1450 retval(ii,jj) *= dscale(ii)/dscale(jj);
1451
1452 // construct balancing permutation vector
1453 Array<int> ipermute(nc);
1454 for(ii=0 ; ii < nc ; ii++) ipermute(ii) = ii; // identity permutation
1455
1456 // leading permutations in forward order
1457 for( ii = 0 ; ii < (ilo-1) ; ii++)
1458 {
1459 int swapidx = ( (int) dpermute(ii) ) -1;
1460 int tmp = ipermute(ii);
1461 ipermute(ii) = ipermute( swapidx );
1462 ipermute(swapidx) = tmp;
1463 }
1464
1465 // trailing permutations must be done in reverse order
1466 for( ii = nc-1 ; ii >= ihi ; ii--)
1467 {
1468 int swapidx = ( (int) dpermute(ii) ) -1;
1469 int tmp = ipermute(ii);
1470 ipermute(ii) = ipermute( swapidx );
1471 ipermute(swapidx) = tmp;
1472 }
1473
1474 // construct inverse balancing permutation vector
1475 Array<int> invpvec(nc);
1476 for( ii = 0 ; ii < nc ; ii++)
1477 invpvec(ipermute(ii)) = ii ; // Thanks to R. A. Lippert for this method
1478
1479 Matrix tmpMat = retval;
1480 for( ii = 0 ; ii < nc ; ii ++)
1481 for( jj= 0 ; jj < nc ; jj++ )
1482 retval(ii,jj) = tmpMat(invpvec(ii),invpvec(jj));
1483
1477 // Reverse preconditioning step 1: fix trace normalization. 1484 // Reverse preconditioning step 1: fix trace normalization.
1478 1485
1479 if (trshift > 0.0) 1486 if (trshift > 0.0)
1480 retval = exp (trshift) * retval; 1487 retval = exp (trshift) * retval;
1481 1488