Operator overloading for Boost interval (vectors)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
2
down vote

favorite












I am a complete newbie to c++ and programming in general. I need to write something for scientific purposes and as such, performance is crucial.
I introduced two types, matrices and vectors with intervals as entries, and now want to make them "able to work with", i.e. define basic operations. The type definitions:



#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>

namespace bn = boost::numeric;
namespace bi = bn::interval_lib;

// Interval typedefs
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;

using Matrix = Eigen::Matrix<Interval, 3, 3>;
using Vector = Eigen::Matrix<Interval, 3, 1>;


Luckily, matrix products work without extra definitions (although I need to call a.lazyProduct(b), otherwise I receive an "operator unambiguous" error, which I don't understand), but inner products and multiplications with constants do not. It seems that I have to manually overload the multiplications, which I did as follows:



Vector operator* (const double& x, const Vector& y)

Vector res;
for(int i = 0; i<3;i++)
res[i] = x*y[i];

return res;


Matrix operator* (const double& x, const Matrix& y)

Matrix res;
for(int i = 0; i<3; i++)
for(int j = 0; j<3; j++)
res(i,j) = x* y(i,j);


return res;


Interval inner_prod(const Vector& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i]*y[i];

return res;


Interval inner_prod(const std::vector<double>& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i] * y[i];

return res;



sizes are hard-coded as I will not be working with any others. I would love to have some feedback and improvement suggestions that focus on performance. Also for the inner product, I was hoping there was a way to make use of std::inner_product for possible better performance, but I can't figure out how.



Edit: The boost/numeric/interval.hpp header gives a definition for multiplication of intervals with scalars, I must have made some mistake before that this didn't work. That just leaves my custom types.







share|improve this question





















  • Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
    – user14717
    Jan 28 at 3:50










  • I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
    – bernhard_e
    Jan 29 at 11:31






  • 1




    It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
    – user14717
    Jan 29 at 16:20










  • #include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
    – Marc Glisse
    Feb 4 at 21:52










  • The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
    – Marc Glisse
    Feb 4 at 22:04
















up vote
2
down vote

favorite












I am a complete newbie to c++ and programming in general. I need to write something for scientific purposes and as such, performance is crucial.
I introduced two types, matrices and vectors with intervals as entries, and now want to make them "able to work with", i.e. define basic operations. The type definitions:



#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>

namespace bn = boost::numeric;
namespace bi = bn::interval_lib;

// Interval typedefs
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;

using Matrix = Eigen::Matrix<Interval, 3, 3>;
using Vector = Eigen::Matrix<Interval, 3, 1>;


Luckily, matrix products work without extra definitions (although I need to call a.lazyProduct(b), otherwise I receive an "operator unambiguous" error, which I don't understand), but inner products and multiplications with constants do not. It seems that I have to manually overload the multiplications, which I did as follows:



Vector operator* (const double& x, const Vector& y)

Vector res;
for(int i = 0; i<3;i++)
res[i] = x*y[i];

return res;


Matrix operator* (const double& x, const Matrix& y)

Matrix res;
for(int i = 0; i<3; i++)
for(int j = 0; j<3; j++)
res(i,j) = x* y(i,j);


return res;


Interval inner_prod(const Vector& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i]*y[i];

return res;


Interval inner_prod(const std::vector<double>& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i] * y[i];

return res;



sizes are hard-coded as I will not be working with any others. I would love to have some feedback and improvement suggestions that focus on performance. Also for the inner product, I was hoping there was a way to make use of std::inner_product for possible better performance, but I can't figure out how.



Edit: The boost/numeric/interval.hpp header gives a definition for multiplication of intervals with scalars, I must have made some mistake before that this didn't work. That just leaves my custom types.







share|improve this question





















  • Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
    – user14717
    Jan 28 at 3:50










  • I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
    – bernhard_e
    Jan 29 at 11:31






  • 1




    It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
    – user14717
    Jan 29 at 16:20










  • #include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
    – Marc Glisse
    Feb 4 at 21:52










  • The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
    – Marc Glisse
    Feb 4 at 22:04












up vote
2
down vote

favorite









up vote
2
down vote

favorite











I am a complete newbie to c++ and programming in general. I need to write something for scientific purposes and as such, performance is crucial.
I introduced two types, matrices and vectors with intervals as entries, and now want to make them "able to work with", i.e. define basic operations. The type definitions:



#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>

namespace bn = boost::numeric;
namespace bi = bn::interval_lib;

// Interval typedefs
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;

using Matrix = Eigen::Matrix<Interval, 3, 3>;
using Vector = Eigen::Matrix<Interval, 3, 1>;


Luckily, matrix products work without extra definitions (although I need to call a.lazyProduct(b), otherwise I receive an "operator unambiguous" error, which I don't understand), but inner products and multiplications with constants do not. It seems that I have to manually overload the multiplications, which I did as follows:



Vector operator* (const double& x, const Vector& y)

Vector res;
for(int i = 0; i<3;i++)
res[i] = x*y[i];

return res;


Matrix operator* (const double& x, const Matrix& y)

Matrix res;
for(int i = 0; i<3; i++)
for(int j = 0; j<3; j++)
res(i,j) = x* y(i,j);


return res;


Interval inner_prod(const Vector& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i]*y[i];

return res;


Interval inner_prod(const std::vector<double>& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i] * y[i];

return res;



sizes are hard-coded as I will not be working with any others. I would love to have some feedback and improvement suggestions that focus on performance. Also for the inner product, I was hoping there was a way to make use of std::inner_product for possible better performance, but I can't figure out how.



Edit: The boost/numeric/interval.hpp header gives a definition for multiplication of intervals with scalars, I must have made some mistake before that this didn't work. That just leaves my custom types.







share|improve this question













I am a complete newbie to c++ and programming in general. I need to write something for scientific purposes and as such, performance is crucial.
I introduced two types, matrices and vectors with intervals as entries, and now want to make them "able to work with", i.e. define basic operations. The type definitions:



#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>

namespace bn = boost::numeric;
namespace bi = bn::interval_lib;

// Interval typedefs
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;

using Matrix = Eigen::Matrix<Interval, 3, 3>;
using Vector = Eigen::Matrix<Interval, 3, 1>;


Luckily, matrix products work without extra definitions (although I need to call a.lazyProduct(b), otherwise I receive an "operator unambiguous" error, which I don't understand), but inner products and multiplications with constants do not. It seems that I have to manually overload the multiplications, which I did as follows:



Vector operator* (const double& x, const Vector& y)

Vector res;
for(int i = 0; i<3;i++)
res[i] = x*y[i];

return res;


Matrix operator* (const double& x, const Matrix& y)

Matrix res;
for(int i = 0; i<3; i++)
for(int j = 0; j<3; j++)
res(i,j) = x* y(i,j);


return res;


Interval inner_prod(const Vector& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i]*y[i];

return res;


Interval inner_prod(const std::vector<double>& x, const Vector& y)
Interval res(0.0);
for(int i = 0; i<3; i++)
res += x[i] * y[i];

return res;



sizes are hard-coded as I will not be working with any others. I would love to have some feedback and improvement suggestions that focus on performance. Also for the inner product, I was hoping there was a way to make use of std::inner_product for possible better performance, but I can't figure out how.



Edit: The boost/numeric/interval.hpp header gives a definition for multiplication of intervals with scalars, I must have made some mistake before that this didn't work. That just leaves my custom types.









share|improve this question












share|improve this question




share|improve this question








edited Jan 26 at 14:41
























asked Jan 26 at 8:58









bernhard_e

162




162











  • Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
    – user14717
    Jan 28 at 3:50










  • I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
    – bernhard_e
    Jan 29 at 11:31






  • 1




    It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
    – user14717
    Jan 29 at 16:20










  • #include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
    – Marc Glisse
    Feb 4 at 21:52










  • The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
    – Marc Glisse
    Feb 4 at 22:04
















  • Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
    – user14717
    Jan 28 at 3:50










  • I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
    – bernhard_e
    Jan 29 at 11:31






  • 1




    It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
    – user14717
    Jan 29 at 16:20










  • #include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
    – Marc Glisse
    Feb 4 at 21:52










  • The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
    – Marc Glisse
    Feb 4 at 22:04















Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
– user14717
Jan 28 at 3:50




Since you are using a vector of length 3, just use std::array<double, 3> rather than std::vector. That'll save some bytes which store the size in std::vector.
– user14717
Jan 28 at 3:50












I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
– bernhard_e
Jan 29 at 11:31




I switched to Eigen::Vector3d for the normal double entry vectors (this gives me also the preimplemented methods such as the norm). Still not sure if the straightforward for-loop overloading is really efficient
– bernhard_e
Jan 29 at 11:31




1




1




It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
– user14717
Jan 29 at 16:20




It should be fine. I've looked at the asm generated by clang in this situation and it always gets vectorized as long as you use '-march=native -O3' compile flag.
– user14717
Jan 29 at 16:20












#include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
– Marc Glisse
Feb 4 at 21:52




#include <eigen3/Eigen/Dense> I think you are supposed to write #include <Eigen/Dense> and compile with a suitable -I flag.
– Marc Glisse
Feb 4 at 21:52












The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
– Marc Glisse
Feb 4 at 22:04




The fact that you have to call a.lazyProduct(b) instead of a*b is a sign of a problem, either in Eigen or in Boost (it works fine with the interval type from CGAL), you may want to report that to one of those projects (probably Eigen, since AFAIK Boost.Interval is unmaintained). I wouldn't try to use the combination until that is fixed...
– Marc Glisse
Feb 4 at 22:04















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186038%2foperator-overloading-for-boost-interval-vectors%23new-answer', 'question_page');

);

Post as a guest



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186038%2foperator-overloading-for-boost-interval-vectors%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?