Forgive me, as I've tried searching and maybe I'm just using the wrong keywords. I'm almost positive there is a way where I can bound an integer template argument to a positive value. I just know from bitter experience that it's probably not intuitive at all.
Just so you know, STL widgets for doing this (if there are such animals) are pretty much off the table because as much as I love the STL I can't use the STL for the code I'm targeting outside minor stuff like definitions because a lot of the platforms I'm targeting with this code don't have it available. (32kb machines and such)
basically what I want is this
template<const size_t TCapacity /* bounded to a minimum of one */ > class Buffer {
...
};
Where a compile error is thrown if TCapacity is zero such that
Buffer<0> buffer; // won't compile
I mean, not only do i think i have encountered this sort of sorcery before, I've seen things like the Spirit framework do much more complicated things so I'm pretty sure there's an answer. I just doubt it's obvious.
Thanks in advance!
In C++11, you could just use a static_assert inside the class:
template<std::size_t TCapacity> class Buffer
{
static_assert(TCapacity > 0, "The size must be greater than zero");
// ...
};
If the expression is true, this declaration has no effect. Otherwise a compile-time error is issued, and the text is included in the diagnostic message.
template<std::size_t cap> requires(cap >= 1) class Buffer;
I doubt it can be very reliably doable in C++11. Of course, you can use some pre-concepts SFINAE, like
template<std::size_t cap, class = std::enable_if_t<(cap > 0)>> class Buffer;
or even something more contrived, like
template<std::size_t cap> class Buffer
: private std::enable_if_t<(cap > 0)
, std::integral_constant<std::size_t, cap>>> {};
but they can be overcome quite easily with things like
template<> class Buffer<0> {};
Anyone know how to use Boost to solve simple definite integrals?
E.g. -x^2 + 1 from -1 to 1?
I have tried reading the boost documentation, but I can't seem to figure out how to properly pass the function.
Thanks
Edit: My attempt so far
using namespace boost::math;
typename function_type; // this is probably wrong
function_type f // and this
{
return -x*x+1;
};
int main(int, char**)
{
const double val =
integral(0.0,
1,
0.001,
f); // my question is, what do I put in here? How do I format f.
}
The first thing to observe is that the Boost library you've shown doesn't actually have a function to calculate integrals. That might have set you on the wrong track.
The library is used for multi-precision floating point operations, and one of the examples happens to be a simple approximation of integrals, per Riemann. The point of the example is that Riemann integrals are so simple that you can use them to demonstrate a fancy library.
In your case, you wouldn't even need to bother with passing a function. You can just write out the Riemann method substituting -x^2 + 1 directly.
That said, the typical C++ way to pass it as an argument would be [](double x) { return -x*x+1.0;}. That's an unnamed function or lambda. It doesn't need a name of its own, since the parameter already has a name.
This question already has answers here:
how to convert a matrix in dlib to a std::vector
(2 answers)
Closed 5 years ago.
I am using Dlib thanks to its great matrix sub module. I find it very complete and useful to do fast scientific algorithm. I managed to add some custom operations and get the overall idea how it works.
However, there is a question that bother me since quite some time. Is there specific reason why it seems impossible to assign any kind of matrix expression to an std::vector ?
EDIT:
Here is a typical dlib function:
template <typename EXP>
const matrix_op<op_trans<EXP> > trans(const matrix_exp<EXP>& m) {
typedef op_trans<EXP> op;
return matrix_op<op>(op(m.ref());
}
And if I want to implement the corresponding function that takes and returns std::vector instead, I think I would do:
template <typename EXP>
const std::vector<matrix_op<op_trans<EXP> > > trans(const std::vector<matrix_exp<EXP> >& ms) {
std::vector<matrix_op<op_trans<EXP> > > out(ms.size());
typedef op_resize_bilinear<EXP> op;
for (int i = 0; i < ms.size(); ++i)
out[i] = matrix_op<op>(op(ms.ref()));
return out;
}
But as it works, any expression is seen as matrix_exp being matrix, matrix_op, matrix_add_exp... But this is not true with std::vector<matrix_exp>:
‘const std::vector<smu::matrix<float> >’ is not derived from ‘const std::vector<smu::matrix_exp<EXP> >’
I just want to know if this is intentional from dlib, if there are any reason for it as it could be useful in several algorithms that need to process several matrices at once... and if some work around this could work
(Disclaimer: First time I am looking at dlib, I'm taking a shot in the dark here and have no idea how dlib / its matrix class actually work.)
A dlib::matrix has member functions including begin() and end(), which will...
...iterate over the elements of the matrix in row major order if layout is row_major_layout or in column major order if layout is column_major_layout.
Assigning to a std::vector can thus be done pretty straightforward:
dlib::matrix< ... > mat;
// fill the matrix, do operations on it etc.
std::vector< mat::type > vec( mat.begin(), mat.end() );
Whether that is what you are looking for, I don't know, because you did not really tell us. ;-)
so I have a function like
int f(int i, int j, int c, double d) {
/*...any operations with i, j, c, d affect on some return int we have*/
}
Is there any thing in boost or STD that would take my function and find the input arguments that minimize my function output?
I assume you're trying to do a "simple" mathematical multi-dimensional minimization.
GSL has some functions to help you with this. I wouldn't look any further ;)
I understand you to be looking for code to perform mathematical optimization.
Boost does not have anything to do this as far as I know, and neither does the standard library; however, NLopt may be what you're looking for.
You can use Brent's algorithm to minimise simple functions.
http://www.boost.org/doc/libs/1_65_0/libs/math/doc/html/math_toolkit/roots/brent_minima.html
In numerical oriented languages (Matlab, Fortran) range operator and semantics is very handy when working with multidimensional data.
For example:
A(i:j,k,:n) // represents two-dimensional slice B(i:j,0:n) of A at index k
unfortunately C++ does not have range operator (:). of course it can be emulated using range/slice functor, but semantics is less clean than Matlab. I am prototyping matrix/tensor domain language in C++ and am wondering if there any options to reproduce range operator.
I still would like to rely on C++/prprocessor framework exclusively.
So far I have looked through boost wave which might be an suitable option.
is there any other means to introduce new non-native operators to C++ DSL?
I know you cannot add new operators.am specifically looking for workaround.
One thing I came up (very ugly hack and I do not intend to use):
#define A(r) A[range(((1)?r), ((0)?r))] // assume A overloads []
A(i:j); // abuse ternary operator
A solution that I've used before is to write an external preprocessor that parses the source and replaces any uses of your custom operator with vanilla C++. For your purposes, a : b uses would be replaced with something like a.operator_range_(b), and operator:() declarations with declarations of range_ operator_range_(). In your makefile you then add a rule that preprocesses source files before compiling them. This can be done with relative ease in Perl.
However, having worked with a similar solution in the past, I do not recommend it. It has the potential to create maintainability and portability issues if you do not remain vigilant of how source is processed and generated.
No -- you can't define your own operators in C++. Bjarne Stroustrup details why..
As Billy said, you cannot overload operators. However, you can come very close yo what you want with "regular" operator overloading (and maybe some template metaprogramming). It would be quite easy to allow for something like this:
#include <iostream>
class FakeNumber {
int n;
public:
FakeNumber(int nn) : n(nn) {}
operator int() const { return n; }
};
class Range {
int f, t;
public:
Range(const int& ff, const int& tt) : f(ff), t(tt) {};
int from() const { return f; }
int to() const { return t; }
};
Range operator-(const FakeNumber& a, const int b) {
return Range(a,b);
}
class Matrix {
public:
void operator()(const Range& a, const Range& b) {
std::cout << "(" << a.from() << ":" << a.to() << "," << b.from() << ":" << b.to() << ")" << std::endl;
}
};
int main() {
FakeNumber a=1,b=2,c=3,d=4;
Matrix m;
m(a-b,c-d);
return 0;
}
The downside is that This solution doesn't support all-literal expressions. Either from or to have to be user-defined classes, since we can't overload operator- for two primitive types.
You can also overload operator* to allow specifying stepping, like so:
m(a-b*3,c-d); // equivalent to m[a:b:3,c:d]
And overload both versions of operator-- to allow ignoring one of the bounds:
m(a--,--d); // equivalent to m[a:,:d]
Another option is to define two objects, named something like Matrix::start and Matrix::end, or whatever you like, and then instead of using operator--, you could use them, and then the other bound wouldn't have to be a variable and could be a literal:
m(start-15,38-end); // This clutters the syntax however
And you could of course use both ways.
I think it's pretty much the best you can get without resorting to bizarre solutions, such as custom prebuild tools or macro abuse (of the sort Matthieu presented and suggested against using them:)).
An alternative is to build a C++ variant dialect using a program transformation tool.
The DMS Software Reengineering Toolkit is a program transformation engine, with an industrial strength C++ Front End. DMS, using this front end, can parse full C++ (it even has a preprocessor and can retain most preprocessor directives unexpanded), automatically build ASTs and complete symbol tables.
The C++ front end comes in source, using a grammar derived directly from the standard. It is technically straightforward to add new grammar rules including those that would allow ":" syntax as array subscripts as you have described, and as Fortran90+ has implemented. One can then use the program transformation capability of DMS to transform the "new" syntax into "vanilla" C++ for use in conventional C++ compilers. (This scheme is a generalization of the Intentional Programming model of "add DSL concepts to your language").
We in fact did a concept demonstration of "Vector C++" using this approach.
We added a multidimensional Vector datatype, whose storage semantics are only that array elements are distinct. This is different than C++'s model of sequential locations, but you need this different semantic if you want the compiler/transformer to have freedom to lay out memory arbitrarily, and this is fundamental if you want to use SIMD machine instructions and/or efficient cache accesses along different axes.
We added Fortran-90 style scalar and subarray range accesses, added virtually all of F90's array-processing operations, added a good fraction of APL's matrix operations, all by adjusting the DMS C++ grammar.
Finally, we built two translators using DMS transformational capability: one mapping a significant part of this (remember, this was a concept demo) to vanilla C++ so you could compile and run Vector C++ applications on a typical workstation, and the other mapping C++ to a PowerPC C++ dialect with SIMD instruction extensions, and we generated SIMD code that was pretty reasonable we thought. Took us about 6 man-months to do all this.
The customer for this ultimately bailed out (his business model didn't include supporting a custom compiler in spite of his severe need for parallel/SIMD based operations), and it has been languishing on the shelf. We've chosen not to pursue this in the broader market because it isn't clear what the market really is. I'm pretty sure there are organizations for which this would be valuable.
Point is, you really can do this. It is almost impossible using ad hoc methods. It is technically quite straightforward with a strong enough program transformation system. It isn't a walk in the park.
The easiest solution is to use a method on matrix instead of an operator.
A.range(i, j, k, n);
Note that typically you do not use , in a subscript operator [], eg A[i][j] instead of A[i,j]. The second form could be possible by overloading the comma operator but then you force i and j to be objects not numbers.
You could define a range class that could be used as a subscript for your matrix class.
class RealMatrix
{
public:
MatrixRowRangeProxy operator[] (int i) {
return operator[](range(i, 1));
}
MatrixRowRangeProxy operator[] (range r);
// ...
RealMatrix(const MatrixRangeProxy proxy);
};
// A generic view on a matrix
class MatrixProxy
{
protected:
RealMatrix * matrix;
};
// A view on a matrix of a range of rows
class MatrixRowRangeProxy : public MatrixProxy
{
public:
MatrixColRangeProxy operator[] (int i) {
return operator[](range(i, 1));
}
MatrixColRangeProxy operator[] (const range & r);
// ...
};
// A view on a matrix of a range of columns
class MatrixColRangeProxy : public MatrixProxy
{
public:
MatrixRangeProxy operator[] (int i) {
return operator[](range(i, 1));
}
MatrixRangeProxy operator[] (const range & r);
// ...
};
Then you can copy a range from one matrix into another.
RealMatrix A = ...
RealMatrix B = A[range(i,j)][range(k,n)];
Finally by creating a Matrix class that can hold either a RealMatrix or a MatrixProxy you can make a RealMatrix and a MatrixProxy appear the same from the outside.
Note the operator[] on the proxies are not and cannot be virtual.
If you want to have fun, you may check out IdOp.
If you are really working on a project, I don't suggest using this trick though. Maintenance will suffer from clever tricks.
Your best bet is thus to bite the bullet and use explicit notation. A short function called range which yields a custom defined object for which the operators are overloaded seems especially suitable.
Matrix<10,30,50> matrix = /**/;
MatrixView<5,6,7> view = matrix[range(0,5)][range(0,6)][range(0,7)];
Matrix<5,6,7> n = view;
Note that the operator[] only has 4 overloads (const/non-const + basic int / range) and yields a proxy object (until the last dimension). Once applied to the last dimension, it gives a view of the matrix. A normal matrix may be built from a view that has the same dimensions (non-explicit constructor).