|
Ublas : |
Subject: Re: [ublas] question regarding elementwise matrix product
From: Jesse Manning (manning.jesse_at_[hidden])
Date: 2009-05-28 17:40:13
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_at_[hidden]> 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_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/ublas
>