octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Expm giving NaN


From: Marco Caliari
Subject: Re: Expm giving NaN
Date: Tue, 2 Oct 2007 09:31:17 +0200 (CEST)

On Mon, 1 Oct 2007, John W. Eaton wrote:

> On 28-Sep-2007, Marco Caliari wrote:
> 
> | On Fri, 28 Sep 2007, David Bateman wrote:
> | 
> | > Marco Caliari wrote:
> | > > Dear maintainers,
> | > >
> | > > the patch against CMatrix.cc in 2.9.14 fixing the "expm giving NaN" bug.
> | > > Here the result:
> | > >
> | > > octave:1> version                        
> | > > ans = 2.9.14
> | > > octave:2> expm(1000*i-10)
> | > > ans = 2.5532e-05 + 3.7540e-05i
> | > > octave:3> expm([1000*i-10 0;0 1000*i-10])
> | > > ans =
> | > >
> | > >   2.5532e-05 + 3.7540e-05i  0.0000e+00 + 0.0000e+00i
> | > >   0.0000e+00 + 0.0000e+00i  2.5532e-05 + 3.7540e-05i
> | > >
> | > >
> | > > I also rewrote the computation of the rational approximation avoiding a 
> | > > matrix-scalar product and including a for loop. I'm not sure if it is 
> | > > better. 
> | > >
> | > > Best regards,
> | > >
> | > > Marco
> | > >   
> | > 
> | > Marco,
> | > 
> | > John should probably comment on this patch before it is committed, but
> | > can you resupply to patch as a diff with context. The type of patch you
> | > sent is difficult to apply if the code has changed (and in fact it has).
> | > To generate a diff with context, do something like
> | > 
> | > diff -u liboctave/CMatrix.cc.orig liboctave/CMatrix.cc
> | 
> | Enclosed.
> | 
> | Best regards,
> | 
> | Marco
> | --- liboctave/CMatrix.orig  2007-09-24 14:20:52.000000000 +0200
> | +++ liboctave/CMatrix.cc    2007-09-24 14:28:49.000000000 +0200
> | @@ -2622,9 +2622,6 @@
> |  
> |    ComplexMatrix m = *this;
> |  
> | -  if (numel () == 1)
> | -    return ComplexMatrix (1, 1, exp (m(0)));
> | -
> |    octave_idx_type nc = columns ();
> |  
> |    // Preconditioning step 1: trace normalization to reduce dynamic
> | @@ -2639,7 +2636,11 @@
> |    trshift /= nc;
> |  
> |    if (trshift.real () < 0.0)
> | -    trshift = trshift.imag ();
> | +    {
> | +      trshift = trshift.imag ();
> | +      if (trshift.real () > 709.0)
> | +   trshift = 709.0;
> | +    }
> |  
> |    for (octave_idx_type i = 0; i < nc; i++)
> |      m.elem (i, i) -= trshift;
> | @@ -2724,8 +2725,13 @@
> |    int minus_one_j = -1;
> |    for (octave_idx_type j = 7; j >= 0; j--)
> |      {
> | -      npp = m * npp + m * padec[j];
> | -      dpp = m * dpp + m * (minus_one_j * padec[j]);
> | +      for (octave_idx_type i = 0; i < nc; i++)
> | +   {
> | +     npp.elem (i, i) += padec[j];
> | +     dpp.elem (i, i) += minus_one_j * pade0c[j];
> | +   }      
> | +      npp = m * npp;
> | +      dpp = m * dpp;
> |        minus_one_j *= -1;
> |      }
> |  
> 
> OK, I think the limit on trshift is OK.  I see that the other part of
> the change could speed things up, but will M always be a diagonal
> matrix here?  

M is not supposed to be diagonal. I just used

M*P+M*a=M*(P+I*a)

> You could probably further improve performance by
> using fortran_vec and avoiding elem.

I'm sorry, but I don't know how to use it. I used elem because it was 
already used twice in expm.

Marco



reply via email to

[Prev in Thread] Current Thread [Next in Thread]