octave-maintainers
[Top][All Lists]
Advanced

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

Re: 2.9.15 --> 3.0


From: David Bateman
Subject: Re: 2.9.15 --> 3.0
Date: Mon, 08 Oct 2007 15:08:25 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

David Bateman wrote:
> John W. Eaton wrote:
>   
>>   * diag should preserve class/type
>>   
>>   
>>     
> What about the attached.. I'll create a changelog if you accept it, as
> the changelog is almost as much to write as the patch itself..
>
> D.
>   
You might want to add

#if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
static octave_value
make_diag (const Matrix& v, octave_idx_type k);
#endif

etc to the patch for consistency. Though is there any C++ compiler that
Octave supports that needs declaration of template functions like that
before their use? In any case if you prefer a patch with the above
declarations, use the attached version instead..

D.

-- 
David Bateman                                address@hidden
Motorola Labs - Paris                        +33 1 69 35 48 04 (Ph) 
Parc Les Algorithmes, Commune de St Aubin    +33 6 72 01 06 33 (Mob) 
91193 Gif-Sur-Yvette FRANCE                  +33 1 69 35 77 01 (Fax) 

The information contained in this communication has been classified as: 

[x] General Business Information 
[ ] Motorola Internal Use Only 
[ ] Motorola Confidential Proprietary

*** ./liboctave/CMatrix.h.orig21        2007-10-08 12:37:31.006465620 +0200
--- ./liboctave/CMatrix.h       2007-10-08 12:41:22.691742165 +0200
***************
*** 47,52 ****
--- 47,57 ----
    ComplexMatrix (octave_idx_type r, octave_idx_type c, const Complex& val)
      : MArray2<Complex> (r, c, val) { }
  
+   ComplexMatrix (const dim_vector& dv) : MArray2<Complex> (dv) { }
+ 
+   ComplexMatrix (const dim_vector& dv, const Complex& val) 
+     : MArray2<Complex> (dv, val) { }
+ 
    ComplexMatrix (const ComplexMatrix& a) : MArray2<Complex> (a) { }
  
    ComplexMatrix (const MArray2<Complex>& a) : MArray2<Complex> (a) { }
*** ./liboctave/chNDArray.h.orig21      2007-10-08 14:07:32.322028921 +0200
--- ./liboctave/chNDArray.h     2007-10-08 14:06:12.645033254 +0200
***************
*** 38,46 ****
  
    charNDArray (void) : MArrayN<char> () { }
  
!   charNDArray (dim_vector& dv) : MArrayN<char> (dv) { }
  
!   charNDArray (dim_vector& dv, char val) : MArrayN<char> (dv, val) { }
    
    charNDArray (const charNDArray& a) : MArrayN<char> (a) { }
  
--- 38,46 ----
  
    charNDArray (void) : MArrayN<char> () { }
  
!   charNDArray (const dim_vector& dv) : MArrayN<char> (dv) { }
  
!   charNDArray (const dim_vector& dv, char val) : MArrayN<char> (dv, val) { }
    
    charNDArray (const charNDArray& a) : MArrayN<char> (a) { }
  
*** ./liboctave/intNDArray.cc.orig21    2007-10-08 10:23:39.944392550 +0200
--- ./liboctave/intNDArray.cc   2007-10-08 11:36:00.215617877 +0200
***************
*** 61,66 ****
--- 61,128 ----
    return false;
  }
  
+ 
+ template <class T>
+ intNDArray<T>
+ intNDArray<T>::diag (void) const
+ {
+   return diag (0);
+ }
+ 
+ template <class T>
+ intNDArray<T>
+ intNDArray<T>::diag (octave_idx_type k) const
+ {
+   dim_vector dv = this->dims ();
+   octave_idx_type nd = dv.length ();
+ 
+   if (nd > 2)
+     {
+       (*current_liboctave_error_handler) ("Matrix must be 2-dimensional");    
+       return intNDArray<T>();
+     }
+   else
+     {
+       octave_idx_type nnr = dv (0);
+       octave_idx_type nnc = dv (1);
+ 
+       if (k > 0)
+       nnc -= k;
+       else if (k < 0)
+       nnr += k;
+ 
+       intNDArray<T> d;
+ 
+       if (nnr > 0 && nnc > 0)
+       {
+         octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
+ 
+         d.resize (dim_vector (ndiag, 1));
+ 
+         if (k > 0)
+           {
+             for (octave_idx_type i = 0; i < ndiag; i++)
+               d.xelem (i) = this->elem (i, i+k);
+           }
+         else if (k < 0)
+           {
+             for (octave_idx_type i = 0; i < ndiag; i++)
+               d.xelem (i) = this->elem (i-k, i);
+           }
+         else
+           {
+             for (octave_idx_type i = 0; i < ndiag; i++)
+               d.xelem (i) = this->elem (i, i);
+           }
+       }
+       else
+       (*current_liboctave_error_handler)
+         ("diag: requested diagonal out of range");
+ 
+       return d;
+     }
+ }
+ 
  // FIXME -- this is not quite the right thing.
  
  template <class T>
*** ./liboctave/intNDArray.h.orig21     2007-10-08 10:23:48.361689381 +0200
--- ./liboctave/intNDArray.h    2007-10-08 10:24:26.592958475 +0200
***************
*** 66,71 ****
--- 66,74 ----
  
    bool any_element_not_one_or_zero (void) const;
  
+   intNDArray diag (void) const;
+   intNDArray diag (octave_idx_type k) const;
+ 
    // FIXME -- this is not quite the right thing.
  
    boolNDArray all (int dim = -1) const;
*** ./liboctave/boolMatrix.h.orig21     2007-10-08 10:49:02.794970032 +0200
--- ./liboctave/boolMatrix.h    2007-10-08 12:54:17.566950404 +0200
***************
*** 38,43 ****
--- 38,45 ----
    boolMatrix (void) : Array2<bool> () { }
    boolMatrix (octave_idx_type r, octave_idx_type c) : Array2<bool> (r, c) { }
    boolMatrix (octave_idx_type r, octave_idx_type c, bool val) : Array2<bool> 
(r, c, val) { }
+   boolMatrix (const dim_vector& dv) : Array2<bool> (dv) { }
+   boolMatrix (const dim_vector& dv, bool val) : Array2<bool> (dv, val) { }
    boolMatrix (const Array2<bool>& a) : Array2<bool> (a) { }
    boolMatrix (const boolMatrix& a) : Array2<bool> (a) { }
  
***************
*** 62,67 ****
--- 64,72 ----
  
    // other operations
  
+   boolMatrix diag (void) const;
+   boolMatrix diag (octave_idx_type k) const;
+ 
    boolMatrix all (int dim = -1) const;
    boolMatrix any (int dim = -1) const;
  
*** ./liboctave/boolMatrix.cc.orig21    2007-10-08 10:49:07.628619774 +0200
--- ./liboctave/boolMatrix.cc   2007-10-08 10:51:53.999920662 +0200
***************
*** 77,82 ****
--- 77,129 ----
  
  // other operations
  
+ boolMatrix
+ boolMatrix::diag (void) const
+ {
+   return diag (0);
+ }
+ 
+ boolMatrix
+ boolMatrix::diag (octave_idx_type k) const
+ {
+   octave_idx_type nnr = rows ();
+   octave_idx_type nnc = cols ();
+   if (k > 0)
+     nnc -= k;
+   else if (k < 0)
+     nnr += k;
+ 
+   boolMatrix d;
+ 
+   if (nnr > 0 && nnc > 0)
+     {
+       octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
+ 
+       d.resize (ndiag, 1);
+ 
+       if (k > 0)
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i, i+k);
+       }
+       else if (k < 0)
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i-k, i);
+       }
+       else
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i, i);
+       }
+     }
+   else
+     (*current_liboctave_error_handler)
+       ("diag: requested diagonal out of range");
+ 
+   return d;
+ }
+ 
  // FIXME Do these really belong here?  Maybe they should be
  // in a base class?
  
*** ./liboctave/chMatrix.h.orig21       2007-10-08 11:21:34.115522679 +0200
--- ./liboctave/chMatrix.h      2007-10-08 12:40:46.188187304 +0200
***************
*** 42,47 ****
--- 42,49 ----
    charMatrix (void) : MArray2<char> () { }
    charMatrix (octave_idx_type r, octave_idx_type c) : MArray2<char> (r, c) { }
    charMatrix (octave_idx_type r, octave_idx_type c, char val) : MArray2<char> 
(r, c, val) { }
+   charMatrix (const dim_vector& dv) : MArray2<char> (dv) { }
+   charMatrix (const dim_vector& dv, char val) : MArray2<char> (dv, val) { }
    charMatrix (const MArray2<char>& a) : MArray2<char> (a) { }
    charMatrix (const charMatrix& a) : MArray2<char> (a) { }
    charMatrix (char c);
***************
*** 71,76 ****
--- 73,81 ----
  
    charMatrix extract (octave_idx_type r1, octave_idx_type c1, octave_idx_type 
r2, octave_idx_type c2) const;
  
+   charMatrix diag (void) const;
+   charMatrix diag (octave_idx_type k) const;
+ 
    boolMatrix all (int dim = -1) const;
    boolMatrix any (int dim = -1) const;
  
*** ./liboctave/chMatrix.cc.orig21      2007-10-08 11:21:38.261189965 +0200
--- ./liboctave/chMatrix.cc     2007-10-08 11:22:47.500800382 +0200
***************
*** 189,194 ****
--- 189,241 ----
    return result;
  }
  
+ charMatrix
+ charMatrix::diag (void) const
+ {
+   return diag (0);
+ }
+ 
+ charMatrix
+ charMatrix::diag (octave_idx_type k) const
+ {
+   octave_idx_type nnr = rows ();
+   octave_idx_type nnc = cols ();
+   if (k > 0)
+     nnc -= k;
+   else if (k < 0)
+     nnr += k;
+ 
+   charMatrix d;
+ 
+   if (nnr > 0 && nnc > 0)
+     {
+       octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
+ 
+       d.resize (ndiag, 1);
+ 
+       if (k > 0)
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i, i+k);
+       }
+       else if (k < 0)
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i-k, i);
+       }
+       else
+       {
+         for (octave_idx_type i = 0; i < ndiag; i++)
+           d.xelem (i) = elem (i, i);
+       }
+     }
+   else
+     (*current_liboctave_error_handler)
+       ("diag: requested diagonal out of range");
+ 
+   return d;
+ }
+ 
  // FIXME Do these really belong here?  Maybe they should be
  // in a base class?
  
*** ./liboctave/MArray2.h.orig21        2007-10-08 12:35:39.236057216 +0200
--- ./liboctave/MArray2.h       2007-10-08 12:35:50.959379037 +0200
***************
*** 51,56 ****
--- 51,60 ----
  
    MArray2 (octave_idx_type n, octave_idx_type m, const T& val) : Array2<T> 
(n, m, val) { }
  
+   MArray2 (const dim_vector& dv) : Array2<T> (dv) { }
+ 
+   MArray2 (const dim_vector& dv, const T& val) : Array2<T> (dv, val) { }
+ 
    MArray2 (const MArray2<T>& a) : Array2<T> (a) { }
  
    MArray2 (const Array2<T>& a) : Array2<T> (a) { }
*** ./liboctave/Array2.h.orig21 2007-10-08 12:35:43.086834808 +0200
--- ./liboctave/Array2.h        2007-10-08 12:37:04.921028543 +0200
***************
*** 56,61 ****
--- 56,66 ----
    Array2 (octave_idx_type r, octave_idx_type c, const T& val)
      : Array<T> (dim_vector (r, c), val) { }
  
+   Array2 (const dim_vector& dv) : Array<T> (dv) { }
+ 
+   Array2 (const dim_vector& dv, const T& val) 
+     : Array<T> (dv) { Array<T>::fill (val); }
+ 
    Array2 (const Array2<T>& a) : Array<T> (a, a.dims ()) { }
  
    Array2 (const Array<T>& a, octave_idx_type r, octave_idx_type c)
*** ./liboctave/dMatrix.h.orig21        2007-10-08 12:37:27.005706264 +0200
--- ./liboctave/dMatrix.h       2007-10-08 12:41:07.936544043 +0200
***************
*** 45,50 ****
--- 45,54 ----
  
    Matrix (octave_idx_type r, octave_idx_type c, double val) : MArray2<double> 
(r, c, val) { }
  
+   Matrix (const dim_vector& dv) : MArray2<double> (dv) { }
+ 
+   Matrix (const dim_vector& dv, double val) : MArray2<double> (dv, val) { }
+ 
    Matrix (const Matrix& a) : MArray2<double> (a) { }
  
    Matrix (const MArray2<double>& a) : MArray2<double> (a) { }
*** ./src/data.cc.orig21        2007-10-08 10:36:36.772566827 +0200
--- ./src/data.cc       2007-10-08 15:04:15.956235128 +0200
***************
*** 436,583 ****
  // FIXME -- we could eliminate some duplicate code here with
  // some template functions or macros.
  
  static octave_value
! make_diag (const Matrix& v, octave_idx_type k)
  {
-   octave_idx_type nr = v.rows ();
-   octave_idx_type nc = v.columns ();
-   assert (nc == 1 || nr == 1);
- 
    octave_value retval;
  
!   octave_idx_type roff = 0;
!   octave_idx_type coff = 0;
!   if (k > 0)
!     {
!       roff = 0;
!       coff = k;
!     }
!   else if (k < 0)
!     {
!       roff = -k;
!       coff = 0;
!     }
! 
!   if (nr == 1)
!     {
!       octave_idx_type n = nc + std::abs (k);
!       Matrix m (n, n, 0.0);
!       for (octave_idx_type i = 0; i < nc; i++)
!       m (i+roff, i+coff) = v (0, i);
!       retval = m;
!     }
    else
      {
!       octave_idx_type n = nr + std::abs (k);
!       Matrix m (n, n, 0.0);
!       for (octave_idx_type i = 0; i < nr; i++)
!       m (i+roff, i+coff) = v (i, 0);
!       retval = m;
!     }
  
    return retval;
  }
  
  static octave_value
! make_diag (const ComplexMatrix& v, octave_idx_type k)
! {
!   octave_idx_type nr = v.rows ();
!   octave_idx_type nc = v.columns ();
!   assert (nc == 1 || nr == 1);
  
!   octave_value retval;
  
!   octave_idx_type roff = 0;
!   octave_idx_type coff = 0;
!   if (k > 0)
!     {
!       roff = 0;
!       coff = k;
!     }
!   else if (k < 0)
!     {
!       roff = -k;
!       coff = 0;
!     }
  
!   if (nr == 1)
!     {
!       octave_idx_type n = nc + std::abs (k);
!       ComplexMatrix m (n, n, 0.0);
!       for (octave_idx_type i = 0; i < nc; i++)
!       m (i+roff, i+coff) = v (0, i);
!       retval = m;
!     }
!   else
!     {
!       octave_idx_type n = nr + std::abs (k);
!       ComplexMatrix m (n, n, 0.0);
!       for (octave_idx_type i = 0; i < nr; i++)
!       m (i+roff, i+coff) = v (i, 0);
!       retval = m;
!     }
  
!   return retval;
! }
  
  static octave_value
! make_diag (const octave_value& arg)
  {
    octave_value retval;
  
!   if (arg.is_real_type ())
      {
!       Matrix m = arg.matrix_value ();
! 
!       if (! error_state)
        {
!         octave_idx_type nr = m.rows ();
!         octave_idx_type nc = m.columns ();
! 
!         if (nr == 0 || nc == 0)
!           retval = Matrix ();
!         else if (nr == 1 || nc == 1)
!           retval = make_diag (m, 0);
!         else
!           {
!             ColumnVector v = m.diag ();
!             if (v.numel () > 0)
!               retval = v;
!           }
        }
        else
!       gripe_wrong_type_arg ("diag", arg);
      }
!   else if (arg.is_complex_type ())
      {
!       ComplexMatrix cm = arg.complex_matrix_value ();
! 
!       if (! error_state)
        {
!         octave_idx_type nr = cm.rows ();
!         octave_idx_type nc = cm.columns ();
! 
!         if (nr == 0 || nc == 0)
!           retval = Matrix ();
!         else if (nr == 1 || nc == 1)
!           retval = make_diag (cm, 0);
!         else
!           {
!             ComplexColumnVector v = cm.diag ();
!             if (v.numel () > 0)
!               retval = v;
!           }
        }
-       else
-       gripe_wrong_type_arg ("diag", arg);
      }
    else
!     gripe_wrong_type_arg ("diag", arg);
  
    return retval;
  }
  
  static octave_value
  make_diag (const octave_value& a, const octave_value& b)
  {
    octave_value retval;
--- 436,607 ----
  // FIXME -- we could eliminate some duplicate code here with
  // some template functions or macros.
  
+ 
+ template <class T>
  static octave_value
! make_diag (const T& v, octave_idx_type k)
  {
    octave_value retval;
+   dim_vector dv = v.dims ();
+   octave_idx_type nd = dv.length ();
  
!   if (nd > 2)
!     error ("diag: expecting 2-dimensional matrix");
    else
      {
!       octave_idx_type nr = dv (0);
!       octave_idx_type nc = dv (1);
  
+       if (nr == 0 || nc == 0)
+       retval = T ();
+       else if (nr != 1 && nc != 1)
+       retval = v.diag (k);
+       else
+       {
+         octave_idx_type roff = 0;
+         octave_idx_type coff = 0;
+         if (k > 0)
+           {
+             roff = 0;
+             coff = k;
+           }
+         else if (k < 0)
+           {
+             roff = -k;
+             coff = 0;
+           }
+ 
+         if (nr == 1)
+           {
+             octave_idx_type n = nc + std::abs (k);
+             T m (dim_vector (n, n), T::resize_fill_value ());
+ 
+             for (octave_idx_type i = 0; i < nc; i++)
+               m (i+roff, i+coff) = v (0, i);
+             retval = m;
+           }
+         else
+           {
+             octave_idx_type n = nr + std::abs (k);
+             T m (dim_vector (n, n), T::resize_fill_value ());
+             for (octave_idx_type i = 0; i < nr; i++)
+               m (i+roff, i+coff) = v (i, 0);
+             retval = m;
+           }
+       }
+     }
+   
    return retval;
  }
  
+ #if !defined (CXX_NEW_FRIEND_TEMPLATE_DECL)
  static octave_value
! make_diag (const Matrix& v, octave_idx_type k);
  
! static octave_value
! make_diag (const ComplexMatrix& v, octave_idx_type k);
  
! static octave_value
! make_diag (const charMatrix& v, octave_idx_type k);
  
! static octave_value
! make_diag (const boolMatrix& v, octave_idx_type k);
  
! static octave_value
! make_diag (const int8NDArray& v, octave_idx_type k);
  
  static octave_value
! make_diag (const int16NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const int32NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const int64NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const uint8NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const uint16NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const uint32NDArray& v, octave_idx_type k);
! 
! static octave_value
! make_diag (const uint64NDArray& v, octave_idx_type k);
! #endif
! 
! static octave_value
! make_diag (const octave_value& a, octave_idx_type k)
  {
    octave_value retval;
+   std::string result_type = a.class_name ();
  
!   if (result_type == "double")
      {
!       if (a.is_real_type ())
        {
!         Matrix m = a.matrix_value ();
!         if (!error_state)
!           retval = make_diag (m, k);
        }
        else
!       {
!         ComplexMatrix m = a.complex_matrix_value ();
!         if (!error_state)
!           retval = make_diag (m, k);
!       }
      }
! #if 0
!   else if (result_type == "single")
!     retval = make_diag (a.single_array_value (), k);
! #endif
!   else if (result_type == "char")
      {
!       charMatrix m = a.char_matrix_value ();
!       if (!error_state)
        {
!         retval = make_diag (m, k);
!         if (a.is_sq_string ())
!           retval = octave_value (retval.char_array_value (), true, '\'');
        }
      }
+   else if (result_type == "logical")
+     {
+       boolMatrix m = a.bool_matrix_value ();
+       if (!error_state)
+       retval = make_diag (m, k);
+     }
+   else if (result_type == "int8")
+     retval = make_diag (a.int8_array_value (), k);
+   else if (result_type == "int16")
+     retval = make_diag (a.int16_array_value (), k);
+   else if (result_type == "int32")
+     retval = make_diag (a.int32_array_value (), k);
+   else if (result_type == "int64")
+     retval = make_diag (a.int64_array_value (), k);
+   else if (result_type == "uint8")
+     retval = make_diag (a.uint8_array_value (), k);
+   else if (result_type == "uint16")
+     retval = make_diag (a.uint16_array_value (), k);
+   else if (result_type == "uint32")
+     retval = make_diag (a.uint32_array_value (), k);
+   else if (result_type == "uint64")
+     retval = make_diag (a.uint64_array_value (), k);
    else
!     gripe_wrong_type_arg ("diag", a);
  
    return retval;
  }
  
  static octave_value
+ make_diag (const octave_value& arg)
+ {
+   return make_diag (arg, 0);
+ }
+ 
+ static octave_value
  make_diag (const octave_value& a, const octave_value& b)
  {
    octave_value retval;
***************
*** 585,637 ****
    octave_idx_type k = b.int_value ();
  
    if (error_state)
!     {
!       error ("diag: invalid second argument");      
!       return retval;
!     }
! 
!   if (a.is_real_type ())
!     {
!       Matrix m = a.matrix_value ();
! 
!       if (! error_state)
!       {
!         octave_idx_type nr = m.rows ();
!         octave_idx_type nc = m.columns ();
! 
!         if (nr == 1 || nc == 1)
!           retval = make_diag (m, k);
!         else if (nr == 0 || nc == 0)
!           retval = Matrix ();
!         else
!           {
!             ColumnVector d = m.diag (k);
!             retval = d;
!           }
!       }
!     }
!   else if (a.is_complex_type ())
!     {
!       ComplexMatrix cm = a.complex_matrix_value ();
! 
!       if (! error_state)
!       {
!         octave_idx_type nr = cm.rows ();
!         octave_idx_type nc = cm.columns ();
! 
!         if (nr == 1 || nc == 1)
!           retval = make_diag (cm, k);
!         else if (nr == 0 || nc == 0)
!           retval = Matrix ();
!         else
!           {
!             ComplexColumnVector d = cm.diag (k);
!             retval = d;
!           }
!       }
!     }
    else
!     gripe_wrong_type_arg ("diag", a);
  
    return retval;
  }
--- 609,617 ----
    octave_idx_type k = b.int_value ();
  
    if (error_state)
!     error ("diag: invalid second argument");      
    else
!     retval = make_diag (a, k);
  
    return retval;
  }

reply via email to

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