Skip to content

Commit

Permalink
Implement equality and non-equality comparisons for matrices
Browse files Browse the repository at this point in the history
Closes #14
  • Loading branch information
demianmnave committed Apr 17, 2018
1 parent 623335e commit c7c5ebd
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 15 deletions.
37 changes: 37 additions & 0 deletions cml/matrix/comparison.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* -*- C++ -*- ------------------------------------------------------------
@@COPYRIGHT@@
*-----------------------------------------------------------------------*/
/** @file
*/

#pragma once

#ifndef cml_matrix_comparison_h
#define cml_matrix_comparison_h

#include <cml/matrix/readable_matrix.h>

namespace cml {

/** Returns true if the elements of @c left are all equal to the elements
* of @c right.
*/
template<class Sub1, class Sub2> bool operator==(
const readable_matrix<Sub1>& left, const readable_matrix<Sub2>& right);

/** Returns true if some element of @c left is not equal to the same element
* of @c right.
*/
template<class Sub1, class Sub2> bool operator!=(
const readable_matrix<Sub1>& left, const readable_matrix<Sub2>& right);

} // namespace cml

#define __CML_MATRIX_COMPARISON_TPP
#include <cml/matrix/comparison.tpp>
#undef __CML_MATRIX_COMPARISON_TPP

#endif

// -------------------------------------------------------------------------
// vim:ft=cpp:sw=2
41 changes: 41 additions & 0 deletions cml/matrix/comparison.tpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* -*- C++ -*- ------------------------------------------------------------
@@COPYRIGHT@@
*-----------------------------------------------------------------------*/
/** @file
*/

#ifndef __CML_MATRIX_COMPARISON_TPP
#error "matrix/comparison.tpp not included correctly"
#endif

#include <cml/matrix/size_checking.h>

namespace cml {

template<class Sub1, class Sub2> inline bool operator==(
const readable_matrix<Sub1>& left, const readable_matrix<Sub2>& right
)
{
/* Possibly equal only if the same dimensions: */
if(left.size() != right.size()) return false;
for(int i = 0; i < left.rows(); i ++) {
for(int j = 0; j < left.cols(); j ++) {
/**/ if(left(i, j) < right(i, j)) return false; // Strictly less.
else if(right(i, j) < left(i, j)) return false; // Strictly greater.
else continue; // Possibly equal.
}
}
return true;
}

template<class Sub1, class Sub2> inline bool operator!=(
const readable_matrix<Sub1>& left, const readable_matrix<Sub2>& right
)
{
return !(left == right);
}

} // namespace cml

// -------------------------------------------------------------------------
// vim:ft=cpp:sw=2
33 changes: 18 additions & 15 deletions cml/vector/comparison.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,42 @@ template<class Sub1, class Sub2> inline bool operator<(
const readable_vector<Sub1>& left, const readable_vector<Sub2>& right
)
{
cml::check_same_size(left, right);
for(int i = 0; i < left.size(); i ++) {
int n = std::min(left.size(), right.size());
for(int i = 0; i < n; i ++) {
/**/ if(left[i] < right[i]) return true; // Strictly less.
else if(left[i] > right[i]) return false; // Strictly greater.
else continue; // Equal.
else if(right[i] < left[i]) return false; // Strictly greater.
else continue; // Possibly equal.
}

/* Equal. */
return false;
/* Equal only if the same length: */
return left.size() < right.size();
}

template<class Sub1, class Sub2> inline bool operator>(
const readable_vector<Sub1>& left, const readable_vector<Sub2>& right
)
{
cml::check_same_size(left, right);
for(int i = 0; i < left.size(); i ++) {
/**/ if(left[i] > right[i]) return true; // Strictly greater.
else if(left[i] < right[i]) return false; // Strictly less.
else continue; // Equal.
int n = std::min(left.size(), right.size());
for(int i = 0; i < n; i ++) {
/**/ if(left[i] < right[i]) return false; // Strictly less.
else if(right[i] < left[i]) return true; // Strictly greater.
else continue; // Possibly equal.
}

/* Equal. */
return false;
/* Equal only if the same length: */
return left.size() > right.size();
}

template<class Sub1, class Sub2> inline bool operator==(
const readable_vector<Sub1>& left, const readable_vector<Sub2>& right
)
{
cml::check_same_size(left, right);
/* Possibly equal only if the same length: */
if(left.size() != right.size()) return false;
for(int i = 0; i < left.size(); i ++) {
if(!(left[i] == right[i])) return false; // Not equal.
/**/ if(left[i] < right[i]) return false; // Strictly less.
else if(right[i] < left[i]) return false; // Strictly greater.
else continue; // Possibly equal.
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions tests/matrix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ CML_ADD_TEST(rowcol1)
CML_ADD_TEST(lu1)
CML_ADD_TEST(determinant1)
CML_ADD_TEST(matrix_hadamard_product1)
CML_ADD_TEST(matrix_comparison1)

# --------------------------------------------------------------------------
# vim:ft=cmake
56 changes: 56 additions & 0 deletions tests/matrix/matrix_comparison1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* -*- C++ -*- ------------------------------------------------------------
@@COPYRIGHT@@
*-----------------------------------------------------------------------*/
/** @file
*/

// Make sure the main header compiles cleanly:
#include <cml/matrix/comparison.h>

#include <cml/matrix/fixed.h>
#include <cml/matrix/types.h>

// For Catch:
#include <cml/util/matrix_print.h>

/* Testing headers: */
#include "catch_runner.h"

CATCH_TEST_CASE("equal1")
{
auto M = cml::matrix33d(
1., 2., 3.,
1., 4., 9.,
1., 16., 25.
);

M.transpose();
auto expected = cml::matrix33d(
1., 1., 1.,
2., 4., 16.,
3., 9., 25.
);

CATCH_CHECK(M == expected);
}

CATCH_TEST_CASE("not_equal1")
{
auto M = cml::matrix33d(
1., 2., 3.,
1., 4., 9.,
1., 16., 25.
);

M.transpose();
auto expected = cml::matrix33d(
1., 1., 1.,
2., 4., 16.,
3., 9., 24.
);

CATCH_CHECK(M != expected);
}

// -------------------------------------------------------------------------
// vim:ft=cpp:sw=2

0 comments on commit c7c5ebd

Please sign in to comment.