bugGNU Octave - Bugs: bug #46123, diagonal matrix and diagonality...

 
 

bug #46123: diagonal matrix and diagonality preserving matrix operations

Submitter:  jan <pfa>
Submitted:  Sun 04 Oct 2015 06:53:44 PM UTC
   
 
Category:  Libraries Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Performance
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Wed 28 Oct 2015 03:40:29 AM UTC, comment #2: 

I checked in a change to preserve the diagonal property of matrices for 2-D calls to permute/ipermute.  See http://hg.savannah.gnu.org/hgweb/octave/rev/5c3dc2650e4f.  If other examples arise where it is easy to preserve the diagonal property those can also be fixed.

Rik <rik5>
Group administrator
Wed 07 Oct 2015 04:03:31 PM UTC, comment #1: 

I think there is a difference in goals between what you are proposing and what Octave is trying to do.  The diagonal class in Octave is intended to be merely a memory-efficient way of handling certain specific matrices.  Matlab does not implement this so there is no API to match.  Instead, the "match" is to the behavior of regular full matrices.  Users shouldn't need to know that there is anything different happening.

That is one reason why issparse (diag (...)) returns false.  Because a diagonal matrix has different "rules" than a sparse matrix and it will automatically convert to a full matrix whenever it needs to.  Thus,


x = diag (1:2)
x =

Diagonal Matrix

   1   0
   0   2

cos (x)
ans =

   0.54030   1.00000
   1.00000  -0.41615


In the diagonal matrix, the zeros really are zeros just like a full matrix and so cos (0) == 1.

I don't see anything wrong in trying to accomodate the mathematician's view of diagonal matrices as a closed set where possible, although the first principle will still be to behave like a full matrix when necessary.

I think the best course of action is to continue to identify places where Octave can be upgraded without impacting the Matlab-compatible behavior.

For permute/ipermute, Octave returns a full matrix because it doesn't know in advance whether you are permuting just rows/columns or perhaps introducing a third or fourth dimension.

For example,


x = diag (1:2);
y = permute (x, [3 1 2])
y =

ans(:,:,1) =

   1   0

ans(:,:,2) =

   0   2


It seems that one could write a special case in do_permute() in libinterp/corefcn/data.cc to check whether the input was a diagonal matrix, and that the permute vector had only two elements, and that the elements were either [1 2] or [2 1].  If all that was true then one could just return the original diagonal matrix.

The do_permute code is shown below:


static octave_value
do_permute (const octave_value_list& args, bool inv)
{
  octave_value retval;

  if (args.length () == 2 && args(1).length () >= args(1).ndims ())
    {
      Array<int> vec = args(1).int_vector_value ();

      // FIXME: maybe we should create an idx_vector object
      // here and pass that to permute?

      int n = vec.numel ();

      for (int i = 0; i < n; i++)
        vec(i)--;

      octave_value ret = args(0).permute (vec, inv);

      retval = ret;
    }
  else
    print_usage ();

  return retval;
}



Rik <rik5>
Group administrator
Sun 04 Oct 2015 06:53:44 PM UTC, original submission:  


Diagonal matrix is essentially a sparse representation. However, functions like permute produce full matrix, even if they are sparsity preserving. [Permute is in fact identity function for diagonal matrix]. In comparision e.g. inv() or expmI() preserve diagonality.

As a goal I believe the basic matrix functions/operations (excluding the elementwise functions) should preferably preserve the structure when the operatin is closed in the class of diagonal matrices.

More generally, this relates to treating diagonal matrix sparse or not (i.e. sparse(diag(1:2)) returns false, which is missleading for many uses.) The memory usage is very different N vs. N^2, so this is somewhat supprising result.

As a side note, and somewhat supprisingly, elementwise function sqrt() preserves the diagonal structure, whereas other elementswise functions like sin() (for which sin(0)=0) do not. In general elementwise functions preserve sparsity even if e.g. cos(0)=1.



>> permute(sparse(diag(1:2)),[1,2])
ans =

Compressed Column Sparse (rows = 2, cols = 2, nnz = 2 [50%])

  (1, 1) ->  1
  (2, 2) ->  2

>> permute((diag(1:2)),[1,2])
ans =

   1   0
   0   2


jan <pfa>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by pfa (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-10-28 rik5 StatusNone Fixed
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code