add basic_operations + first corresponding test

This commit is contained in:
Christian Zimmermann 2023-02-26 20:15:05 +01:00
parent 039effb344
commit a2b936c4da
8 changed files with 214 additions and 32 deletions

View file

@ -0,0 +1,99 @@
#ifndef __cxz_basic_operations_cc_h__
#define __cxz_basic_operations_cc_h__
#include "basic_operations.h"
namespace CNORXZ
{
/************************************
* standard operatrions (unary) *
************************************/
template <class Op>
constexpr decltype(auto) minus(const COpInterface<Op>& op)
{
return operation( [](const auto& a) { return -a; }, op.THIS() );
}
/*************************************
* standard operatrions (binary) *
*************************************/
template <class Op1, class Op2>
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a + b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a - b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a * b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a / b; },
op1.THIS(), op2.THIS() );
}
template <class Op1, class Op2>
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return operation( [](const auto& a, const auto& b) { return a % b; },
op1.THIS(), op2.THIS() );
}
/*****************************************
* operators for standard operations *
*****************************************/
template <class Op>
constexpr decltype(auto) operator-(const COpInterface<Op>& op)
{
return minus(op);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return plus(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return minus(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return multiplies(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return divides(op1, op2);
}
template <class Op1, class Op2>
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2)
{
return modulo(op1, op2);
}
}
#endif

View file

@ -0,0 +1,55 @@
#ifndef __cxz_basic_operations_h__
#define __cxz_basic_operations_h__
#include "base/base.h"
#include "operation.h"
namespace CNORXZ
{
// standard operations:
// unary:
template <class Op>
constexpr decltype(auto) minus(const COpInterface<Op>& op);
// binary:
template <class Op1, class Op2>
constexpr decltype(auto) plus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) minus(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) multiplies(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) divides(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) modulo(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
// operators for standard operations:
template <class Op>
constexpr decltype(auto) operator-(const COpInterface<Op>& op);
template <class Op1, class Op2>
constexpr decltype(auto) operator+(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator-(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator*(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator/(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
template <class Op1, class Op2>
constexpr decltype(auto) operator%(const COpInterface<Op1>& op1, const COpInterface<Op2>& op2);
}
#endif

View file

@ -421,6 +421,8 @@ namespace CNORXZ
{
return i->xpr(i);
}
}
#endif

View file

@ -243,6 +243,7 @@ namespace CNORXZ
template <class IndexT>
constexpr decltype(auto) indexOp(const Sptr<IndexT>& i);
}
#endif

View file

@ -1,3 +1,4 @@
#include "op_types.cc.h"
#include "op_utility.cc.h"
#include "basic_operations.cc.h"

View file

@ -1,5 +1,6 @@
#include "op_types.h"
#include "op_utility.h"
#include "basic_operations.h"
#include "operation.cc.h"

View file

@ -46,6 +46,7 @@ namespace CNORXZ
virtual ~RangeBase() = default;
// virtual RangePtr sub() const; // Sptr<URange<RangePtr>> ; range of subranges (TODO!!!)
virtual RangePtr sub(SizeT num) const;
virtual SizeT size() const = 0;
virtual SizeT dim() const = 0;

View file

@ -53,35 +53,45 @@ namespace
{
mSize1 = 7;
mSize2 = 11;
const SizeT off = 20;
SizeT off = 20;
mData1 = Numbers::get(off, mSize1);
mData2 = Numbers::get(off+mSize1, mSize2);
mData12 = Numbers::get(off+mSize1+mSize2, mSize1*mSize2);
auto cra = CRangeFactory(mSize1).create();
auto crb = CRangeFactory(mSize2).create();
mCIa1 = std::make_shared<CIndex>(cra);
mCIa2 = std::make_shared<CIndex>(cra);
mCIb1 = std::make_shared<CIndex>(crb);
mCIb2 = std::make_shared<CIndex>(crb);
mCCa1a2 = mindexPtr(mCIa1*mCIa2);
mCCa2a1 = mindexPtr(mCIa2*mCIa1);
mOCa1a2.init(mCCa1a2);
mORa2a1.init(mData12.data(), mCCa2a1);
mData2 = Numbers::get(off += mSize1 , mSize2);
mData11 = Numbers::get(off += mSize2, mSize1*mSize1);
mData12 = Numbers::get(off += mSize1*mSize1, mSize1*mSize2);
auto cr1 = CRangeFactory(mSize1).create();
auto cr2 = CRangeFactory(mSize2).create();
mCI1i = std::make_shared<CIndex>(cr1);
mCI1j = std::make_shared<CIndex>(cr1);
mCI2i = std::make_shared<CIndex>(cr2);
mCI2j = std::make_shared<CIndex>(cr2);
mCC1i1j = mindexPtr(mCI1i*mCI1j);
mCC1j1i = mindexPtr(mCI1j*mCI1i);
//mCC1i2i = mindexPtr(mCI1i*mCI2i);
//mCC1j2i = mindexPtr(mCI1j*mCI2i);
mOC1i1j.init(mCC1i1j);
mOR1j1i.init(mData11.data(), mCC1j1i);
mOR1i1j.init(mData11.data(), mCC1i1j);
}
SizeT mSize1;
SizeT mSize2;
Vector<Double> mData1;
Vector<Double> mData2;
Vector<Double> mData11;
Vector<Double> mData12;
Sptr<CIndex> mCIa1;
Sptr<CIndex> mCIa2;
Sptr<CIndex> mCIb1;
Sptr<CIndex> mCIb2;
Sptr<MCCI> mCCa1a2;
Sptr<MCCI> mCCa2a1;
OpCont<double,MCCI> mOCa1a2;
COpRoot<double,MCCI> mORa2a1;
Sptr<CIndex> mCI1i;
Sptr<CIndex> mCI1j;
Sptr<CIndex> mCI2i;
Sptr<CIndex> mCI2j;
Sptr<MCCI> mCC1i1j;
Sptr<MCCI> mCC1j1i;
//Sptr<MCCI> mCC1i2i;
//Sptr<MCCI> mCC1j2i;
OpCont<double,MCCI> mOC1i1j;
COpRoot<double,MCCI> mOR1j1i;
COpRoot<double,MCCI> mOR1i1j;
//COpRoot<double,MCCI> mOR1j2i;
//COpRoot<double,MCCI> mOR1i2i;
};
TEST_F(OpCont_CR_Test, Basics)
@ -145,20 +155,32 @@ namespace
TEST_F(OpCont_CR_CR_Test, Basics)
{
EXPECT_EQ(mOCa1a2.rootSteps(mCIa1->id()).val(), mCIa2->pmax().val());
EXPECT_EQ(mOCa1a2.rootSteps(mCIa2->id()).val(), 1u);
EXPECT_EQ(mORa2a1.rootSteps(mCIa1->id()).val(), 1u);
EXPECT_EQ(mORa2a1.rootSteps(mCIa2->id()).val(), mCIa1->pmax().val());
EXPECT_EQ(mOC1i1j.rootSteps(mCI1i->id()).val(), mCI1j->pmax().val());
EXPECT_EQ(mOC1i1j.rootSteps(mCI1j->id()).val(), 1u);
EXPECT_EQ(mOR1j1i.rootSteps(mCI1i->id()).val(), 1u);
EXPECT_EQ(mOR1j1i.rootSteps(mCI1j->id()).val(), mCI1i->pmax().val());
}
TEST_F(OpCont_CR_CR_Test, Assignment)
{
mOCa1a2 = mORa2a1;
for(SizeT i = 0; i != mCIa1->pmax().val(); ++i){
for(SizeT j = 0; j != mCIa2->pmax().val(); ++j){
const SizeT jS = mCIa2->pmax().val();
const SizeT iS = mCIa1->pmax().val();
EXPECT_EQ(mOCa1a2.data()[i*jS+j], mORa2a1.data()[j*iS+i]);
mOC1i1j = mOR1j1i;
for(SizeT i = 0; i != mCI1i->pmax().val(); ++i){
for(SizeT j = 0; j != mCI1j->pmax().val(); ++j){
const SizeT jS = mCI1j->pmax().val();
const SizeT iS = mCI1i->pmax().val();
EXPECT_EQ(mOC1i1j.data()[i*jS+j], mOR1j1i.data()[j*iS+i]);
}
}
}
TEST_F(OpCont_CR_CR_Test, Multiply)
{
mOC1i1j = mOR1j1i * mOR1i1j;
for(SizeT i = 0; i != mCI1i->pmax().val(); ++i){
for(SizeT j = 0; j != mCI1j->pmax().val(); ++j){
const SizeT jS = mCI1j->pmax().val();
const SizeT iS = mCI1i->pmax().val();
EXPECT_EQ(mOC1i1j.data()[i*jS+j], mOR1j1i.data()[j*iS+i] * mOR1i1j.data()[i*jS+j]);
}
}
}