Loading ...
Sorry, an error occurred while loading the content.
 

Fwd: Re: [ublas-dev] Re: Deleting rows from sparse matrices

Expand Messages
  • Gunter Winkler
    ... [code removed] Ok. I changed the code to use internal data structures. Especialy swap() is very important. The code now creates a temporary column. Then
    Message 1 of 2 , Feb 27, 2004
      Quoting vital_vasilev <vital_vasilev@...>:

      > Thank's for answering on my letter. I wrote the following test code
      > for deleting
      > rows from matrices, but it only makes elements in specified rows
      > equal to zero and doesn't delete them.

      [code removed]

      Ok. I changed the code to use "internal" data structures. Especialy swap() is
      very important.

      The code now creates a temporary column. Then it copies all unselected values
      to
      this temporary column and the swaps both. This means the temp.col. becomes a
      column of the matrix M and the old column becomes the new temp.col.
      This code works _only_ for column oriented vector_of_vector matrices!

      regards
      Gunter

      ------ code ------
      #include <iostream>
      #include <iomanip>

      #include <boost/numeric/ublas/matrix.hpp>
      #include <boost/numeric/ublas/matrix_sparse.hpp>
      #include <boost/numeric/ublas/vector.hpp>
      #include <boost/numeric/ublas/vector_sparse.hpp>
      #include <boost/numeric/ublas/vector_of_vector.hpp>
      #include <boost/numeric/ublas/operation_blocked.hpp>
      #include <boost/numeric/ublas/io.hpp>
      #include <boost/timer.hpp>

      using namespace boost::numeric::ublas;

      typedef matrix<float, column_major, unbounded_array<float> > TCDenseMatrix;
      typedef vector<float, unbounded_array<float> > TCDenseVector;
      typedef generalized_vector_of_vector< float, column_major,
      vector<coordinate_vector<float> > > TCSparseMatrix;
      typedef coordinate_vector<float> TCSparseVector;

      typedef TCSparseMatrix::iterator1 i1_t;
      typedef TCSparseMatrix::iterator2 i2_t;

      using std::cout;
      using std::endl;

      int main(int argc, char* argv[])
      {

      // Initialize matrix
      TCSparseMatrix M(6,5);
      M(0,0) = 11; M(0,2) = 13; M(0,3) = 13;
      M(1,0) = 21; M(1,1) = 22;
      M(2,2) = 33; M(2,4) = 35;
      M(3,0) = 666; M(3,1) = 666; M(3,4) = 666;
      M(4,0) = 52; M(4,4) = 55;
      M(5,0) = 12; M(5,2);

      cout << "Input: " << endl;
      // Show result
      for (i2_t i2 = M.begin2(); i2 != M.end2(); ++i2)
      {
      for (i1_t i1 = i2.begin(); i1 != i2.end(); ++i1)
      {
      cout << "(" << i1.index1() << "," << i1.index2()
      << ":" << *i1 << ") ";
      }
      cout << endl;
      }

      // Initialize vector of selected rows
      std::vector<bool> SelectedRows(6);
      SelectedRows[0] = true;
      SelectedRows[1] = true;
      SelectedRows[4] = true;

      // Delete not selected rows in a column major matrix
      // of type vector-of-coordinate vector
      TCSparseMatrix::vector_data_value_type tmp_vec(M.size1());
      for(size_t icol = 0; icol < M.size2(); icol++)
      {
      TCSparseMatrix::vector_data_value_type & cur_col(M.data()(icol));
      TCSparseMatrix::vector_data_value_type::const_iterator irow;

      tmp_vec.clear(); tmp_vec.resize(M.size1());
      for(irow = cur_col.begin(); irow != cur_col.end(); ++irow)
      if(SelectedRows[irow.index()])
      tmp_vec.insert(irow.index(), *irow);

      swap( cur_col, tmp_vec );
      }

      cout << "Result: " << endl;
      // Show result
      for (i2_t i2 = M.begin2(); i2 != M.end2(); ++i2)
      {
      for (i1_t i1 = i2.begin(); i1 != i2.end(); ++i1)
      {
      cout << "(" << i1.index1() << "," << i1.index2()
      << ":" << *i1 << ") ";
      }
      cout << endl;
      }

      return 0;
      }
    • vital_vasilev
      Hi All! Hi Gunter! Thank s for answering on my question. ... Your example works well but using internal data structures makes code hard portable. I changed
      Message 2 of 2 , Feb 29, 2004
        Hi All!
        Hi Gunter! Thank's for answering on my question.

        You wrote:
        > Ok. I changed the code to use "internal" data structures.
        > Especialy swap() is very important.

        Your example works well but using "internal" data structures makes
        code hard portable.
        I changed your code so that "internal" data structures are hided by
        using template specialization of class matrix_column for
        generalized_vector_of_vector as shown below.

        ------ code for matrix_column specialization ------

        template<class T, class A>
        class matrix_column<generalized_vector_of_vector<T, column_major, A>
        >: public
        vector_expression<matrix_column<generalized_vector_of_vector<T,
        column_major, A> > >
        {
        public:
        typedef generalized_vector_of_vector<T, column_major, A> M;

        // ...

        #ifndef BOOST_UBLAS_CT_PROXY_CLOSURE_TYPEDEFS
        // Old code
        //typedef typename M::closure_type matrix_closure_type;
        //typedef matrix_closure_type matrix_closure_reference;

        typedef matrix_type matrix_closure_type;
        typedef matrix_closure_type& matrix_closure_reference;

        #else
        // Old Code
        //typedef typename
        // boost::mpl::if_c<boost::is_const<M>::value,
        // typename M::const_closure_type, typename
        // M::closure_type>::type matrix_closure_type;
        //typedef matrix_closure_type matrix_closure_reference;

        typedef typename boost::mpl::if_c<boost::is_const<M>::value,
        const matrix_type,
        matrix_type>::type
        matrix_closure_type;
        typedef matrix_closure_type& matrix_closure_reference;
        #endif

        // ...

        template<class AE>
        BOOST_UBLAS_INLINE
        matrix_column &assign (const vector_expression<AE> &ae)
        {

        // Old code
        // vector_assign(scalar_assign<value_type,
        // BOOST_UBLAS_TYPENAME AE::value_type> (),
        // *this, ae);


        vector_assign (scalar_assign<value_type,
        BOOST_UBLAS_TYPENAME AE::value_type> (),
        data_.data()[j_], ae);
        return *this;
        }

        // Other assign functions are defined analogically

        // ...

        private:

        // Old code
        // matrix_closure data_;

        matrix_closure_reference data_;
        size_type j_;
        static matrix_type nil_;

        };

        ------ test code ------
        #include <iostream>
        #include <iomanip>

        #include <boost/numeric/ublas/matrix.hpp>
        #include <boost/numeric/ublas/matrix_sparse.hpp>
        #include <boost/numeric/ublas/vector.hpp>
        #include <boost/numeric/ublas/vector_sparse.hpp>
        #include <boost/numeric/ublas/vector_of_vector.hpp>
        #include <boost/numeric/ublas/operation_blocked.hpp>
        #include <boost/numeric/ublas/io.hpp>
        #include <boost/timer.hpp>

        using namespace boost::numeric::ublas;

        typedef matrix<float, column_major, unbounded_array<float> >
        TCDenseMatrix;
        typedef vector<float, unbounded_array<float> > TCDenseVector;
        typedef generalized_vector_of_vector< float, column_major,
        vector<coordinate_vector<float> > > TCSparseMatrix;
        typedef coordinate_vector<float> TCSparseVector;

        typedef TCSparseMatrix::iterator1 i1_t;
        typedef TCSparseMatrix::iterator2 i2_t;

        using std::cout;
        using std::endl;

        int main(int argc, char* argv[])
        {

        // Initialize matrix
        TCSparseMatrix M(6,5);
        M(0,0) = 11; M(0,2) = 13; M(0,3) = 13;
        M(1,0) = 21; M(1,1) = 22;
        M(2,2) = 33; M(2,4) = 35;
        M(3,0) = 666; M(3,1) = 666; M(3,4) =
        666;
        M(4,0) = 52; M(4,4) = 55;
        M(5,0) = 12; M(5,2);

        cout << "Input: " << endl;
        // Show result
        for (i2_t i2 = M.begin2(); i2 != M.end2(); ++i2)
        {
        for (i1_t i1 = i2.begin(); i1 != i2.end(); ++i1)
        {
        cout << "(" << i1.index1() << "," << i1.index2()
        << ":" << *i1 << ") ";
        }
        cout << endl;
        }

        // Initialize vector of selected rows
        std::vector<bool> SelectedRows(6);
        SelectedRows[0] = true;
        SelectedRows[1] = true;
        SelectedRows[4] = true;

        // Delete not selected rows in a column major matrix
        // of type vector-of-coordinate vector
        TCSparseVector tmp_vec(M.size1());
        for (i2_t i2 = M.begin2(); i2 != M.end2(); ++i2)
        {
        tmp_vec.clear(); tmp_vec.resize(M.size1());
        for (i1_t i1 = i2.begin(); i1 != i2.end(); ++i1)
        if(SelectedRows[i1.index1()])
        tmp_vec.insert(i1.index1(), *i1);

        column(M, i2.index2()) = tmp_vec;
        }

        cout << "Result: " << endl;
        // Show result
        for (i2_t i2 = M.begin2(); i2 != M.end2(); ++i2)
        {
        for (i1_t i1 = i2.begin(); i1 != i2.end(); ++i1)
        {
        cout << "(" << i1.index1() << "," << i1.index2()
        << ":" << *i1 << ") ";
        }
        cout << endl;
        }

        return 0;
        }
        --- End forwarded message ---

        What do you think about this variant?
      Your message has been successfully submitted and would be delivered to recipients shortly.