[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3 of 4] Implement diag \ sparse and sparse / diag
From: |
Jason Riedy |
Subject: |
[PATCH 3 of 4] Implement diag \ sparse and sparse / diag |
Date: |
Mon, 09 Mar 2009 17:52:21 -0400 |
# HG changeset patch
# User Jason Riedy <address@hidden>
# Date 1236635354 14400
# Node ID 64103815307e702a6de6ddc2115e84c3636369cf
# Parent 6f9fc3415a747112998fbaa662bbbccef5c11631
Implement diag \ sparse and sparse / diag.
>From 363b5095de889c45639dd7c150cfea023d2fb007 Mon Sep 17 00:00:00 2001
Date: Mon, 9 Mar 2009 17:29:01 -0400
Not pretty, but somewhat efficient and preserves sparsity.
Signed-off-by: Jason Riedy <address@hidden>
---
src/ChangeLog | 31 ++++++++
src/OPERATORS/op-dm-scm.cc | 101 +++++++++++++++++++++++++
src/OPERATORS/op-dm-sm.cc | 34 +++++++++
src/sparse-xdiv.cc | 178 +++++++++++++++++++++++++++++++++++++++++--
src/sparse-xdiv.h | 19 +++++
test/ChangeLog | 4 +
test/test_diag_perm.m | 35 +++++++++
7 files changed, 393 insertions(+), 9 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,34 @@
+2009-03-08 Jason Riedy <address@hidden>
+
+ * sparse-xdiv.h (xleftdiv): Declare overrides for
+ xleftdiv (diagonal, sparse), both real and complex.
+ (xdiv): Declare overrides for xdiv (sparse, diagonal), both real
+ and complex.
+
+ * sparse-xdiv.cc (do_rightdiv_sm_dm): New template function.
+ Implementation for xdiv (sparse, diagonal).
+ (xdiv): Call do_rightdiv_sm_dm to implement overrides, real and
+ complex.
+ (do_leftdiv_dm_sm): New template function. Implementation for
+ xleftdiv (diagonal, sparse).
+ (xleftdiv): Call do_leftdiv_dm_sm to implement overrides, real and
+ complex.
+
+ * OPERATORS/op-dm-sm.cc (ldiv_dm_sm): Octave binding for real left
+ division, diagonal into sparse.
+ (div_sm_dm): Octave binding for real right division, sparse by
+ diagonal.
+ (install_dm_sm_ops): Install above bindings.
+
+ * OPERATORS/op-dm-scm.cc (ldiv_dm_scm): Octave binding for real
+ diagonal \ complex sparse.
+ (ldiv_cdm_sm): Octave binding for complex diagonal \ real sparse.
+ (ldiv_cdm_scm): Octave binding for complex diagonal \ complex sparse.
+ (div_scm_dm): Octave binding for complex sparse / real diagonal.
+ (div_sm_cdm): Octave binding for real sparse / complex diagonal.
+ (div_scm_cdm): Octave binding for complex sparse / complex diagonal.
+ (install_dm_scm_ops): Install above bindings.
+
2009-03-08 Jason Riedy <address@hidden>
* OPERATORS/op-dm-scm.cc: New file. Implement multiplication
diff --git a/src/OPERATORS/op-dm-scm.cc b/src/OPERATORS/op-dm-scm.cc
--- a/src/OPERATORS/op-dm-scm.cc
+++ b/src/OPERATORS/op-dm-scm.cc
@@ -35,6 +35,8 @@
#include "ov-re-sparse.h"
#include "ov-cx-sparse.h"
+#include "sparse-xdiv.h"
+
// diagonal matrix by sparse matrix ops
DEFBINOP (mul_dm_scm, diag_matrix, sparse_complex_matrix)
@@ -196,6 +198,36 @@
}
}
+DEFBINOP (ldiv_dm_scm, diag_matrix, sparse_complex_matrix)
+{
+ CAST_BINOP_ARGS (const octave_diag_matrix&,
+ const octave_sparse_complex_matrix&);
+
+ MatrixType typ = v2.matrix_type ();
+ return xleftdiv (v1.diag_matrix_value (), v2.sparse_complex_matrix_value (),
+ typ);
+}
+
+DEFBINOP (ldiv_cdm_sm, complex_diag_matrix, sparse_matrix)
+{
+ CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
+ const octave_sparse_matrix&);
+
+ MatrixType typ = v2.matrix_type ();
+ return xleftdiv (v1.complex_diag_matrix_value (), v2.sparse_matrix_value (),
+ typ);
+}
+
+DEFBINOP (ldiv_cdm_scm, complex_diag_matrix, sparse_complex_matrix)
+{
+ CAST_BINOP_ARGS (const octave_complex_diag_matrix&,
+ const octave_sparse_complex_matrix&);
+
+ MatrixType typ = v2.matrix_type ();
+ return xleftdiv (v1.complex_diag_matrix_value (),
v2.sparse_complex_matrix_value (),
+ typ);
+}
+
// sparse matrix by diagonal matrix ops
DEFBINOP (mul_scm_dm, sparse_complex_matrix, diag_matrix)
@@ -356,6 +388,66 @@
}
}
+DEFBINOP (div_scm_dm, sparse_complex_matrix, diag_matrix)
+{
+ CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const
octave_diag_matrix&);
+
+ if (v2.rows() == 1 && v2.columns() == 1)
+ {
+ double d = v2.scalar_value ();
+
+ if (d == 0.0)
+ gripe_divide_by_zero ();
+
+ return octave_value (v1.sparse_complex_matrix_value () / d);
+ }
+ else
+ {
+ MatrixType typ = v2.matrix_type ();
+ return xdiv (v1.sparse_complex_matrix_value (), v2.diag_matrix_value (),
typ);
+ }
+}
+
+DEFBINOP (div_sm_cdm, sparse_matrix, complex_diag_matrix)
+{
+ CAST_BINOP_ARGS (const octave_sparse_matrix&, const
octave_complex_diag_matrix&);
+
+ if (v2.rows() == 1 && v2.columns() == 1)
+ {
+ std::complex<double> d = v2.complex_value ();
+
+ if (d == 0.0)
+ gripe_divide_by_zero ();
+
+ return octave_value (v1.sparse_matrix_value () / d);
+ }
+ else
+ {
+ MatrixType typ = v2.matrix_type ();
+ return xdiv (v1.sparse_matrix_value (), v2.complex_diag_matrix_value (),
typ);
+ }
+}
+
+DEFBINOP (div_scm_cdm, sparse_complex_matrix, complex_diag_matrix)
+{
+ CAST_BINOP_ARGS (const octave_sparse_complex_matrix&, const
octave_complex_diag_matrix&);
+
+ if (v2.rows() == 1 && v2.columns() == 1)
+ {
+ std::complex<double> d = v2.complex_value ();
+
+ if (d == 0.0)
+ gripe_divide_by_zero ();
+
+ return octave_value (v1.sparse_complex_matrix_value () / d);
+ }
+ else
+ {
+ MatrixType typ = v2.matrix_type ();
+ return xdiv (v1.sparse_complex_matrix_value (),
v2.complex_diag_matrix_value (), typ);
+ }
+}
+
void
install_dm_scm_ops (void)
{
@@ -380,6 +472,11 @@
INSTALL_BINOP (op_herm_mul, octave_complex_diag_matrix,
octave_sparse_complex_matrix,
herm_mul_cdm_scm);
+ INSTALL_BINOP (op_ldiv, octave_diag_matrix, octave_sparse_complex_matrix,
ldiv_dm_scm);
+ INSTALL_BINOP (op_ldiv, octave_complex_diag_matrix, octave_sparse_matrix,
ldiv_cdm_sm);
+ INSTALL_BINOP (op_ldiv, octave_complex_diag_matrix,
octave_sparse_complex_matrix,
+ ldiv_cdm_scm);
+
INSTALL_BINOP (op_mul, octave_sparse_complex_matrix, octave_diag_matrix,
mul_scm_dm);
INSTALL_BINOP (op_mul_trans, octave_sparse_complex_matrix,
octave_diag_matrix,
@@ -400,4 +497,8 @@
mul_scm_cdm);
INSTALL_BINOP (op_mul_herm, octave_sparse_complex_matrix,
octave_complex_diag_matrix,
mul_herm_scm_cdm);
+
+ INSTALL_BINOP (op_div, octave_sparse_complex_matrix, octave_diag_matrix,
div_scm_dm);
+ INSTALL_BINOP (op_div, octave_sparse_matrix, octave_complex_diag_matrix,
div_sm_cdm);
+ INSTALL_BINOP (op_div, octave_sparse_complex_matrix,
octave_complex_diag_matrix, div_scm_cdm);
}
diff --git a/src/OPERATORS/op-dm-sm.cc b/src/OPERATORS/op-dm-sm.cc
--- a/src/OPERATORS/op-dm-sm.cc
+++ b/src/OPERATORS/op-dm-sm.cc
@@ -33,6 +33,8 @@
#include "ov-re-diag.h"
#include "ov-re-sparse.h"
+#include "sparse-xdiv.h"
+
// diagonal matrix by sparse matrix ops
DEFBINOP (mul_dm_sm, diag_matrix, sparse_matrix)
@@ -66,6 +68,14 @@
}
}
+DEFBINOP (ldiv_dm_sm, diag_matrix, sparse_matrix)
+{
+ CAST_BINOP_ARGS (const octave_diag_matrix&, const octave_sparse_matrix&);
+
+ MatrixType typ = v2.matrix_type ();
+ return xleftdiv (v1.diag_matrix_value (), v2.sparse_matrix_value (), typ);
+}
+
// sparse matrix by diagonal matrix ops
DEFBINOP (mul_sm_dm, sparse_matrix, diag_matrix)
@@ -99,6 +109,26 @@
}
}
+DEFBINOP (div_sm_dm, sparse_matrix, diag_matrix)
+{
+ CAST_BINOP_ARGS (const octave_sparse_matrix&, const octave_diag_matrix&);
+
+ if (v2.rows() == 1 && v2.columns() == 1)
+ {
+ double d = v2.scalar_value ();
+
+ if (d == 0.0)
+ gripe_divide_by_zero ();
+
+ return octave_value (v1.sparse_matrix_value () / d);
+ }
+ else
+ {
+ MatrixType typ = v2.matrix_type ();
+ return xdiv (v1.sparse_matrix_value (), v2.diag_matrix_value (), typ);
+ }
+}
+
void
install_dm_sm_ops (void)
{
@@ -109,10 +139,14 @@
INSTALL_BINOP (op_herm_mul, octave_diag_matrix, octave_sparse_matrix,
mul_dm_sm);
+ INSTALL_BINOP (op_ldiv, octave_diag_matrix, octave_sparse_matrix,
ldiv_dm_sm);
+
INSTALL_BINOP (op_mul, octave_sparse_matrix, octave_diag_matrix,
mul_sm_dm);
INSTALL_BINOP (op_trans_mul, octave_sparse_matrix, octave_diag_matrix,
mul_sm_dm);
INSTALL_BINOP (op_herm_mul, octave_sparse_matrix, octave_diag_matrix,
mul_sm_dm);
+
+ INSTALL_BINOP (op_div, octave_sparse_matrix, octave_diag_matrix, div_sm_dm);
}
diff --git a/src/sparse-xdiv.cc b/src/sparse-xdiv.cc
--- a/src/sparse-xdiv.cc
+++ b/src/sparse-xdiv.cc
@@ -33,7 +33,9 @@
#include "error.h"
#include "dSparse.h"
+#include "dDiagMatrix.h"
#include "CSparse.h"
+#include "CDiagMatrix.h"
#include "oct-spparms.h"
#include "sparse-xdiv.h"
@@ -74,6 +76,10 @@
INSTANTIATE_MX_LEFTDIV_CONFORM (SparseMatrix, ComplexMatrix);
INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, Matrix);
INSTANTIATE_MX_LEFTDIV_CONFORM (SparseComplexMatrix, ComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (DiagMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (DiagMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexDiagMatrix, SparseMatrix);
+INSTANTIATE_MX_LEFTDIV_CONFORM (ComplexDiagMatrix, SparseComplexMatrix);
template <class T1, class T2>
bool
@@ -105,15 +111,23 @@
INSTANTIATE_MX_DIV_CONFORM (Matrix, SparseComplexMatrix);
INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, SparseMatrix);
INSTANTIATE_MX_DIV_CONFORM (ComplexMatrix, SparseComplexMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, DiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseMatrix, ComplexDiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, DiagMatrix);
+INSTANTIATE_MX_DIV_CONFORM (SparseComplexMatrix, ComplexDiagMatrix);
-// Right division functions.
+// Right division functions. X / Y = X * inv(Y) = (inv (Y') * X')'
//
-// op2 / op1: m cm sm scm
+// Y / X: m cm sm scm
// +-- +---+----+----+----+
// sparse matrix | 1 | 3 | 5 | 7 |
// +---+----+----+----+
// sparse complex_matrix | 2 | 4 | 6 | 8 |
// +---+----+----+----+
+// diagonal matrix | 9 | 11 |
+// +----+----+
+// complex diag. matrix | 10 | 12 |
+// +----+----+
// -*- 1 -*-
Matrix
@@ -275,6 +289,76 @@
return result.hermitian ();
}
+namespace {
+template <typename RT, typename SM, typename DM>
+RT do_rightdiv_sm_dm (const SM& a, const DM& d)
+{
+ const octave_idx_type d_nr = d.rows ();
+
+ const octave_idx_type a_nr = a.rows ();
+ const octave_idx_type a_nc = a.cols ();
+
+ using std::min;
+ const octave_idx_type nc = min (d_nr, a_nc);
+
+ if ( ! mx_div_conform (a, d))
+ return RT ();
+
+ const octave_idx_type nz = a.nnz ();
+ RT r (a_nr, nc, nz);
+
+ const typename DM::element_type zero = typename DM::element_type ();
+
+ octave_idx_type k_result = 0;
+ for (octave_idx_type j = 0; j < nc; ++j)
+ {
+ OCTAVE_QUIT;
+ const typename DM::element_type s = d.dgelem (j);
+ const octave_idx_type colend = a.cidx (j+1);
+ r.xcidx (j) = k_result;
+ if (s != zero)
+ for (octave_idx_type k = a.cidx (j); k < colend; ++k)
+ {
+ r.xdata (k_result) = a.data (k) / s;
+ r.xridx (k_result) = a.ridx (k);
+ ++k_result;
+ }
+ }
+ r.xcidx (nc) = k_result;
+
+ r.maybe_compress (true);
+ return r;
+}
+} // anonymous namespace
+
+// -*- 9 -*-
+SparseMatrix
+xdiv (const SparseMatrix& a, const DiagMatrix& b, MatrixType &)
+{
+ return do_rightdiv_sm_dm<SparseMatrix> (a, b);
+}
+
+// -*- 10 -*-
+SparseComplexMatrix
+xdiv (const SparseMatrix& a, const ComplexDiagMatrix& b, MatrixType &)
+{
+ return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
+// -*- 11 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const DiagMatrix& b, MatrixType &)
+{
+ return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
+// -*- 12 -*-
+SparseComplexMatrix
+xdiv (const SparseComplexMatrix& a, const ComplexDiagMatrix& b, MatrixType &)
+{
+ return do_rightdiv_sm_dm<SparseComplexMatrix> (a, b);
+}
+
// Funny element by element division operations.
//
// op2 \ op1: s cs
@@ -363,18 +447,18 @@
return result;
}
-// Left division functions.
+// Left division functions. X \ Y = inv(X) * Y
//
-// op2 \ op1: m cm
+// Y \ X : sm scm dm dcm
// +-- +---+----+
// matrix | 1 | 5 |
// +---+----+
// complex_matrix | 2 | 6 |
-// +---+----+
-// sparse matrix | 3 | 7 |
-// +---+----+
-// sparse complex_matrix | 4 | 8 |
-// +---+----+
+// +---+----+----+----+
+// sparse matrix | 3 | 7 | 9 | 11 |
+// +---+----+----+----+
+// sparse complex_matrix | 4 | 8 | 10 | 12 |
+// +---+----+----+----+
// -*- 1 -*-
Matrix
@@ -473,6 +557,82 @@
return a.solve (typ, b, info, rcond, solve_singularity_warning);
}
+namespace {
+template <typename RT, typename DM, typename SM>
+RT do_leftdiv_dm_sm (const DM& d, const SM& a)
+{
+ const octave_idx_type a_nr = a.rows ();
+ const octave_idx_type a_nc = a.cols ();
+
+ const octave_idx_type d_nc = d.cols ();
+
+ using std::min;
+ const octave_idx_type nr = min (d_nc, a_nr);
+
+ if ( ! mx_leftdiv_conform (d, a))
+ return RT ();
+
+ const octave_idx_type nz = a.nnz ();
+ RT r (nr, a_nc, nz);
+
+ const typename DM::element_type zero = typename DM::element_type ();
+
+ octave_idx_type k_result = 0;
+ for (octave_idx_type j = 0; j < a_nc; ++j)
+ {
+ OCTAVE_QUIT;
+ const octave_idx_type colend = a.cidx (j+1);
+ r.xcidx (j) = k_result;
+ for (octave_idx_type k = a.cidx (j); k < colend; ++k)
+ {
+ const octave_idx_type i = a.ridx (k);
+ if (i < nr)
+ {
+ const typename DM::element_type s = d.dgelem (i);
+ if (s != zero)
+ {
+ r.xdata (k_result) = a.data (k) / s;
+ r.xridx (k_result) = i;
+ ++k_result;
+ }
+ }
+ }
+ }
+ r.xcidx (a_nc) = k_result;
+
+ r.maybe_compress (true);
+ return r;
+}
+} // anonymous namespace
+
+// -*- 9 -*-
+SparseMatrix
+xleftdiv (const DiagMatrix& d, const SparseMatrix& a, MatrixType&)
+{
+ return do_leftdiv_dm_sm<SparseMatrix> (d, a);
+}
+
+// -*- 10 -*-
+SparseComplexMatrix
+xleftdiv (const DiagMatrix& d, const SparseComplexMatrix& a, MatrixType&)
+{
+ return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
+// -*- 11 -*-
+SparseComplexMatrix
+xleftdiv (const ComplexDiagMatrix& d, const SparseMatrix& a, MatrixType&)
+{
+ return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
+// -*- 12 -*-
+SparseComplexMatrix
+xleftdiv (const ComplexDiagMatrix& d, const SparseComplexMatrix& a,
MatrixType&)
+{
+ return do_leftdiv_dm_sm<SparseComplexMatrix> (d, a);
+}
+
/*
;;; Local Variables: ***
;;; mode: C++ ***
diff --git a/src/sparse-xdiv.h b/src/sparse-xdiv.h
--- a/src/sparse-xdiv.h
+++ b/src/sparse-xdiv.h
@@ -27,6 +27,8 @@
#include "oct-cmplx.h"
#include "MatrixType.h"
+class DiagMatrix;
+class ComplexDiagMatrix;
class SparseMatrix;
class SparseComplexMatrix;
@@ -47,6 +49,15 @@
extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a,
const SparseComplexMatrix& b, MatrixType &typ);
+extern SparseMatrix xdiv (const SparseMatrix& a,
+ const DiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseMatrix& a,
+ const ComplexDiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a,
+ const DiagMatrix& b, MatrixType &typ);
+extern SparseComplexMatrix xdiv (const SparseComplexMatrix& a,
+ const ComplexDiagMatrix& b, MatrixType &typ);
+
extern Matrix x_el_div (double a, const SparseMatrix& b);
extern ComplexMatrix x_el_div (double a, const SparseComplexMatrix& b);
extern ComplexMatrix x_el_div (const Complex a, const SparseMatrix& b);
@@ -71,6 +82,14 @@
extern SparseComplexMatrix xleftdiv (const SparseComplexMatrix& a,
const SparseComplexMatrix& b, MatrixType
&typ);
+extern SparseMatrix xleftdiv (const DiagMatrix&, const SparseMatrix&,
MatrixType&);
+extern SparseComplexMatrix xleftdiv (const ComplexDiagMatrix&, const
SparseMatrix&,
+ MatrixType&);
+extern SparseComplexMatrix xleftdiv (const DiagMatrix&, const
SparseComplexMatrix&,
+ MatrixType&);
+extern SparseComplexMatrix xleftdiv (const ComplexDiagMatrix&, const
SparseComplexMatrix&,
+ MatrixType&);
+
#endif
/*
diff --git a/test/ChangeLog b/test/ChangeLog
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-08 Jason Riedy <address@hidden>
+
+ * test_diag_perm.m: Add tests for inverse scaling and sparse structure.
+
2009-03-08 Jason Riedy <address@hidden>
* test_diag_perm.m: Add tests for preserving sparse structure when
scaling.
diff --git a/test/test_diag_perm.m b/test/test_diag_perm.m
--- a/test/test_diag_perm.m
+++ b/test/test_diag_perm.m
@@ -147,3 +147,38 @@
%! A(4, 1) = Inf;
%! assert (Dr * A * Dc, A .* kron (dr, dc), eps);
+## sparse inverse row scaling with a zero factor
+%!test
+%! n = 8;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (n, 1);
+%! Dr = diag (scalefact);
+%! scalefact(n-1) = Inf;
+%! Dr(n-1, n-1) = 0;
+%! assert (full (Dr \ A), full (A) ./ repmat (scalefact, 1, n));
+
+## narrow sparse inverse row scaling
+%!test
+%! n = 8;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (n-2, 1);
+%! Dr = diag (scalefact, n, n-2);
+%! assert (full (Dr \ A), Dr \ full(A))
+
+## sparse inverse column scaling with a zero factor
+%!test
+%! n = 11;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (1, n);
+%! Dc = diag (scalefact);
+%! scalefact(n-1) = Inf;
+%! Dc(n-1, n-1) = 0;
+%! assert (full (A / Dc), full(A) / Dc)
+
+## short sparse inverse column scaling
+%!test
+%! n = 7;
+%! A = sprand (n, n, .5);
+%! scalefact = rand (1, n-2) + I () * rand(1, n-2);
+%! Dc = diag (scalefact, n-2, n);
+%! assert (full (A / Dc), full(A) / Dc)
- [PATCH 0 of 4] Implement basic sparse op diag and diag op sparse support., Jason Riedy, 2009/03/09
- [PATCH 1 of 4] Add identity_val and conj_val functor objects to functor.h, Jason Riedy, 2009/03/09
- [PATCH 2 of 4] Implement sparse * diagonal and diagonal * sparse operations, double-prec only, Jason Riedy, 2009/03/09
- [PATCH 3 of 4] Implement diag \ sparse and sparse / diag,
Jason Riedy <=
- [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, Jason Riedy, 2009/03/09
- [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, John W. Eaton, 2009/03/09
- Re: [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, Jason Riedy, 2009/03/10
- Re: [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, John W. Eaton, 2009/03/10
- Re: [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, Jason Riedy, 2009/03/10
- Re: [PATCH 4 of 4] Implement diag + sparse, diag - sparse, sparse + diag, sparse - diag, Jaroslav Hajek, 2009/03/11
[PATCH 0 of 4] Implement basic sparse op diag and diag op sparse support., John W. Eaton, 2009/03/09