Sparse-perm-op-defs.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002 
00003 Copyright (C) 2009-2012 Jason Riedy
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #if !defined (octave_sparse_perm_op_defs_h)
00024 #define octave_sparse_perm_op_defs_h 1
00025 
00026 // Matrix multiplication
00027 
00028 template <typename SM>
00029 SM octinternal_do_mul_colpm_sm (const octave_idx_type *pcol, const SM& a)
00030 // Relabel the rows according to pcol.
00031 {
00032   const octave_idx_type nr = a.rows ();
00033   const octave_idx_type nc = a.cols ();
00034   const octave_idx_type nent = a.nnz ();
00035   SM r (nr, nc, nent);
00036 
00037   octave_sort<octave_idx_type> sort;
00038 
00039   for (octave_idx_type j = 0; j <= nc; ++j)
00040     r.xcidx (j) = a.cidx (j);
00041 
00042   for (octave_idx_type j = 0; j < nc; j++)
00043     {
00044       octave_quit ();
00045 
00046       OCTAVE_LOCAL_BUFFER (octave_idx_type, sidx, r.xcidx(j+1) - r.xcidx(j));
00047       for (octave_idx_type i = r.xcidx(j), ii = 0; i < r.xcidx(j+1); i++)
00048         {
00049           sidx[ii++]=i;
00050           r.xridx (i) = pcol[a.ridx (i)];
00051         }
00052       sort.sort (r.xridx() + r.xcidx(j), sidx, r.xcidx(j+1) - r.xcidx(j));
00053       for (octave_idx_type i = r.xcidx(j), ii = 0; i < r.xcidx(j+1); i++)
00054         r.xdata(i) = a.data (sidx[ii++]);
00055     }
00056 
00057   return r;
00058 }
00059 
00060 template <typename SM>
00061 SM octinternal_do_mul_pm_sm (const PermMatrix& p, const SM& a)
00062 {
00063   const octave_idx_type nr = a.rows ();
00064   if (p.cols () != nr)
00065     {
00066       gripe_nonconformant ("operator *", p.rows (), p.cols (), a.rows (), a.cols ());
00067       return SM ();
00068     }
00069 
00070   if (p.is_row_perm ())
00071     {
00072       // Form the column permutation and then call the colpm_sm routine.
00073       const octave_idx_type *prow = p.pvec ().data ();
00074       OCTAVE_LOCAL_BUFFER(octave_idx_type, pcol, nr);
00075       for (octave_idx_type i = 0; i < nr; ++i)
00076         pcol[prow[i]] = i;
00077       return octinternal_do_mul_colpm_sm (pcol, a);
00078     }
00079   else
00080     return octinternal_do_mul_colpm_sm (p.pvec ().data (), a);
00081 }
00082 
00083 template <typename SM>
00084 SM octinternal_do_mul_sm_rowpm (const SM& a, const octave_idx_type *prow)
00085 // For a row permutation, iterate across the source a and stuff the
00086 // results into the correct destination column in r.
00087 {
00088   const octave_idx_type nr = a.rows ();
00089   const octave_idx_type nc = a.cols ();
00090   const octave_idx_type nent = a.nnz ();
00091   SM r (nr, nc, nent);
00092 
00093   for (octave_idx_type j_src = 0; j_src < nc; ++j_src)
00094     r.xcidx (prow[j_src]) = a.cidx (j_src+1) - a.cidx (j_src);
00095   octave_idx_type k = 0;
00096   for (octave_idx_type j = 0; j < nc; ++j)
00097     {
00098       const octave_idx_type tmp = r.xcidx (j);
00099       r.xcidx (j) = k;
00100       k += tmp;
00101     }
00102   r.xcidx (nc) = nent;
00103 
00104   octave_idx_type k_src = 0;
00105   for (octave_idx_type j_src = 0; j_src < nc; ++j_src)
00106     {
00107       octave_quit ();
00108       const octave_idx_type j = prow[j_src];
00109       const octave_idx_type kend_src = a.cidx (j_src + 1);
00110       for (k = r.xcidx (j); k_src < kend_src; ++k, ++k_src)
00111         {
00112           r.xridx (k) = a.ridx (k_src);
00113           r.xdata (k) = a.data (k_src);
00114         }
00115     }
00116   assert (k_src == nent);
00117 
00118   return r;
00119 }
00120 
00121 template <typename SM>
00122 SM octinternal_do_mul_sm_colpm (const SM& a, const octave_idx_type *pcol)
00123 // For a column permutation, iterate across the destination r and pull
00124 // data from the correct column of a.
00125 {
00126   const octave_idx_type nr = a.rows ();
00127   const octave_idx_type nc = a.cols ();
00128   const octave_idx_type nent = a.nnz ();
00129   SM r (nr, nc, nent);
00130 
00131   for (octave_idx_type j = 0; j < nc; ++j)
00132     {
00133       const octave_idx_type j_src = pcol[j];
00134       r.xcidx (j+1) = r.xcidx (j) + (a.cidx (j_src+1) - a.cidx (j_src));
00135     }
00136   assert (r.xcidx (nc) == nent);
00137 
00138   octave_idx_type k = 0;
00139   for (octave_idx_type j = 0; j < nc; ++j)
00140     {
00141       octave_quit ();
00142       const octave_idx_type j_src = pcol[j];
00143       octave_idx_type k_src;
00144       const octave_idx_type kend_src = a.cidx (j_src + 1);
00145       for (k_src = a.cidx (j_src); k_src < kend_src; ++k_src, ++k)
00146         {
00147           r.xridx (k) = a.ridx (k_src);
00148           r.xdata (k) = a.data (k_src);
00149         }
00150     }
00151   assert (k == nent);
00152 
00153   return r;
00154 }
00155 
00156 template <typename SM>
00157 SM octinternal_do_mul_sm_pm (const SM& a, const PermMatrix& p)
00158 {
00159   const octave_idx_type nc = a.cols ();
00160   if (p.rows () != nc)
00161     {
00162       gripe_nonconformant ("operator *", a.rows (), a.cols (), p.rows (), p.cols ());
00163       return SM ();
00164     }
00165 
00166   if (p.is_row_perm ())
00167     return octinternal_do_mul_sm_rowpm (a, p.pvec ().data ());
00168   else
00169     return octinternal_do_mul_sm_colpm (a, p.pvec ().data ());
00170 }
00171 
00172 #endif // octave_sparse_perm_op_defs_h
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines