Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #2744 from SunilMahendrakar/scale
Browse files Browse the repository at this point in the history
move scale to linalg
  • Loading branch information
lambday committed Mar 9, 2015
2 parents 2753367 + 64311a0 commit 136b497
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 7 deletions.
35 changes: 35 additions & 0 deletions src/shogun/mathematics/linalg/internal/implementation/Scale.h
Expand Up @@ -66,6 +66,41 @@ struct scale
static void compute(Matrix A, Matrix B, Matrix C, T alpha, T beta);
};

/** Specialization of scale for the Native backend */
template<class Matrix>
struct scale<Backend::NATIVE, Matrix>
{
typedef typename Matrix::Scalar T;

/** Performs the operation B = alpha*A */
static void compute(SGMatrix<T> A, SGMatrix<T> B, T alpha)
{
REQUIRE((A.num_rows==B.num_rows)&&(A.num_cols==B.num_cols),
"Dimensions of A(%dx%d) and B(%dx%d) don't match.",
A.num_rows, A.num_cols, B.num_rows, B.num_cols);

compute(A.matrix, B.matrix, A.num_rows*A.num_cols, alpha);
}

/** Performs the operation B = alpha*A */
static void compute(SGVector<T> A, SGVector<T> B, T alpha)
{
REQUIRE(A.vlen==B.vlen,"Number of elements in A(%d) should be "
"equal to number of elements in (%d)!", A.vlen, B.vlen);

compute(A.vector, B.vector, A.vlen, alpha);
}

/** Performs the operation B = alpha*A for len elements*/
static void compute(T* A, T* B, index_t len, T alpha)
{
REQUIRE(A!=NULL&&B!=NULL, "Invalid pointers to matrices.");

for (index_t i=0; i<len; i++)
B[i]=A[i]*alpha;
}
};

#ifdef HAVE_EIGEN3

/** Specialization of scale for the Eigen3 backend */
Expand Down
21 changes: 14 additions & 7 deletions src/shogun/mathematics/linalg/internal/modules/Core.h
Expand Up @@ -61,6 +61,20 @@ void add(Matrix A, Matrix B, Matrix C, typename Matrix::Scalar alpha=1.0,
implementation::add<backend, Matrix>::compute(A, B, C, alpha, beta);
}

/** Performs the operation B = alpha*A. Works for both matrices and vectors */
template <Backend backend=linalg_traits<Core>::backend,class Matrix>
void scale(Matrix A, Matrix B, typename Matrix::Scalar alpha)
{
implementation::scale<backend, Matrix>::compute(A, B, alpha);
}

/** Performs the operation A = alpha*A. Works for both matrices and vectors */
template <Backend backend=linalg_traits<Core>::backend,class Matrix>
void scale(Matrix A, typename Matrix::Scalar alpha)
{
implementation::scale<backend, Matrix>::compute(A, A, alpha);
}

#ifdef HAVE_LINALG_LIB
/** Performs matrix multiplication
*
Expand All @@ -87,13 +101,6 @@ void subtract(Matrix A, Matrix B, Matrix C,
implementation::add<backend, Matrix>::compute(A, B, C, alpha, -1*beta);
}

/** Performs the operation B = alpha*A. Works for both matrices and vectors */
template <Backend backend=linalg_traits<Core>::backend,class Matrix>
void scale(Matrix A, Matrix B, typename Matrix::Scalar alpha)
{
implementation::scale<backend, Matrix>::compute(A, B, alpha);
}

/** Performs the operation C = A .* B where ".*" denotes elementwise multiplication */
template <Backend backend=linalg_traits<Core>::backend,class Matrix>
void elementwise_product(Matrix A, Matrix B, Matrix C)
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/mathematics/linalg/Scale_unittest.cc
Expand Up @@ -47,6 +47,38 @@

using namespace shogun;

TEST(ScaleMatrix, native_backend)
{
const float64_t alpha = 0.3;

SGMatrix<float64_t> A(9,9);
SGMatrix<float64_t> B(9,9);

for (int32_t i=0; i<9*9; i++)
A[i] = i;

linalg::scale<linalg::Backend::NATIVE>(A, B, alpha);

for (int32_t i=0; i<9*9; i++)
EXPECT_NEAR(alpha*A[i], B[i], 1e-15);
}

TEST(ScaleVector, native_backend)
{
const float64_t alpha = 0.3;

SGVector<float64_t> A(9);
SGVector<float64_t> B(9);

for (int32_t i=0; i<9; i++)
A[i] = i;

linalg::scale<linalg::Backend::NATIVE>(A, B, alpha);

for (int32_t i=0; i<9; i++)
EXPECT_NEAR(alpha*A[i], B[i], 1e-15);
}

#ifdef HAVE_EIGEN3
TEST(ScaleMatrix, eigen3_backend)
{
Expand Down

0 comments on commit 136b497

Please sign in to comment.