Another way of doing this would be the following:

namespace ublas = boost::numeric::ublas;

// multiplies a vector element-wise and stores the answer in the first vector
template <typename E>
void ElementWiseMult(ublas::vector_expression<E>& data1, ublas::vector_expression<E>& data2)
{
    // element-wise multiplication and assign answer to the first data vector
    data1() = ublas::element_prod(data1(), data2());
}

// Element-wise multiplication of same dimension matrices (Hadamard matrix product)
// The answer is stored in the first matrix on exit
template <typename E>
void HadamardProduct(ublas::matrix_expression<E>& data1, ublas::matrix_expression<E>& data2)
{
    typedef typename E::size_type size_t;

    // make sure dimensions are the same
    assert(data1().size1() == data2().size1());
    assert(data1().size2() == data2().size2());

    // loop over all rows, multiplying each element-wise
    for (size_t index = 0, end = data1().size1(); index != end; ++index)
    {
        ElementWiseMult(ublas::row(data1(), index), ublas::row(data2(), index));
    }
}

int main()
{
    ublas::matrix<int> mat1(3,3);
    ublas::matrix<int> mat2(3,3);

    mat1(0,0) = 1;
    mat1(0,1) = 3;
    mat1(0,2) = 2;
    mat1(1,0) = 1;
    mat1(1,1) = 0;
    mat1(1,2) = 0;
    mat1(2,0) = 1;
    mat1(2,1) = 2;
    mat1(2,2) = 2;

    mat2(0,0) = 0;
    mat2(0,1) = 0;
    mat2(0,2) = 2;
    mat2(1,0) = 7;
    mat2(1,1) = 5;
    mat2(1,2) = 0;
    mat2(2,0) = 2;
    mat2(2,1) = 1;
    mat2(2,2) = 1;

    HadamardProduct(mat1, mat2);
    std::cout << mat1 << std::endl;

    return 0;
}

I don't know about the efficiency of the operation, but it seems to get the job done. Note that the first vector passed in is overridden with the multiplication result on exit.


On Thu, May 28, 2009 at 4:19 PM, Kim Kuen Tang <kuentang@vodafone.de> wrote:
Hi Kaveh,

Kaveh Kohan schrieb:

Hi Kim,

Thank you for your reply.
I am sorry if my questions sounds naive. I ran into a problem compiling this program. Do I need to have a specific version of phoenix or spirit to compile this program. Since in my system, phoenix.hpp is located in  "boost/spirit/phoenix.hpp", I changed your program to the following:
This is not a good idea, because including only phoenix.hpp is not enough in your boost version.
( I use 1.39.)


 symmetric_matrix<double,lower> m(3, 3), n(3,3), u(3,3);
 generate(arg1, lambda[val(1.0)] )(m.data());
the plain data of your matrix is stored in the unbounded_array. Using the member data() you have access to this vector. Since you have another version of boost, i suggest you to change the above code to     std::fill(m.data().begin(), m.data().end,1.0 ); This will have the same effect.

 generate(arg1, lambda[val(2.0)] )(n.data());
 transform(arg1,n.data().begin(),u.data().begin(),lambda[arg1/arg2])(m.data());
Using transform you can perform an element wise division. In blas there is already an element_wise division called element_div.
Here is the complete code:


# include <boost/numeric/ublas/symmetric.hpp>
# include <boost/numeric/ublas/matrix_expression.hpp>

# include <boost/numeric/ublas/io.hpp>

# include <vector>
# include <algorithm>

using namespace boost::numeric::ublas;

int main () {

  symmetric_matrix<double,lower> m(3, 3), n(3,3), u(3,3);
  std::fill(m.data().begin(), m.data().end(),1.0 );
  std::fill(n.data().begin(), n.data().end(),2.0 );
  u=element_div(m,n);

  std::cout << u << std::endl;
}

Plus can you explain a little what it does because notation-wise, it is very confusing for me. Definitely ignorance frommy side but I would appreciate if you describe it a little bit.

Thanks,
Kaveh

------------------------------------------------------------------------
**
_______________________________________________
ublas mailing list
ublas@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/ublas