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
Related
I am trying to convert some MATLAB code to C++ using armadillo and one of the MATLAB functions used is interp1. "Easy enough", I though, Armadillo has interp1. "linear should be good enough", well I was wrong. So I searched for interp1.m source code and found the Octave source, it uses pchip.m which I found the octave source code but pchip.m uses pchip_deriv.cc which then seems to use a fortran fcn.
So before I start really diving in to the conversion of pchip are there any other libraries or sources that include pchip out there that I could possibly use?
In case anyone else ever needs this I looked here to find the equations. For large data sets it does not seem to work properly so using the matrix formula, I create a sliding window PCHIP interp. Still did not match MATLABs so I average with a linear interp and it's pretty close. Is it the right way to do this? probably not... does it work? Yup!
void pchip_slide(const arma::vec& x, const arma::vec& y, const arma::vec& x_new, arma::vec& y_custom,const int M=4){
vec y_interp=zeros<vec>(size(x_new));
interp1(x,y,x_new,y_interp);
int I=0;
int start_interp=0;
int end_interp=0;
for(int ii=0;ii<x_new.n_elem;ii++){
I=index_min(abs(x-x_new(ii)));
start_interp=std::max((I-2),0);
end_interp=std::min((start_interp+M-1),int(numel(x)-1));
vec x_mini=x(span(start_interp,end_interp));
vec y_mini=y(span(start_interp,end_interp));
mat x_mat=ones<mat>(x_mini.n_elem,x_mini.n_elem);
for(int ll=0;ll<x_mini.n_elem-1;ll++){
x_mat.row(ll)=pow((x_mini.t()),(x_mini.n_elem-ll));
}
vec c_mini=solve( x_mat, y_mini,solve_opts::fast + solve_opts::no_approx);
rowvec x_pchip_mini=ones<rowvec>(x_mini.n_elem);
for (int ll=0;ll<x_mini.n_elem-1;ll++){
x_pchip_mini(ll)=pow((x_new(ii)),(x_mini.n_elem-ll));
}
y_custom(ii)=conv_to<double>::from(x_pchip_mini*c_mini);
if ((x_new(ii)>=x(0))&& (x_new(ii)<=x(x.n_elem-1))){
y_custom(ii)=(y_custom(ii)*1/M+y_interp(ii)*3/M);
}
}
return;
}
I'm trying to eliminate nested for loops by making use of coefficient-wise operations on eigen3 objects. In order to achieve this I have to generalize an already existing function such that I can make us of custom coefficient-wise operations.
I found that eigen provides two functions, unaryExpr() and binaryExpr() (documentation), that allow to implement a custom coefficient-wise operation on eigen Arrays. However, as far as I understand, you can only give one or two arguments to these functions which represent the coefficients from the array itself. I would like to pass other arguments as well to this function since I need these other arguments to complete the calculation.
I would like to generalize the following function
inline Complex expValue(int twoMS, int twoMSPrime, const Matrix2cd& mat)
{
const Vector2cd& bra = getSpinBasisState(twoMSPrime);
const Vector2cd& ket = getSpinBasisState(twoMS);
return bra.adjoint()*mat*ket;
}
All the possible combinations of values for twoMS and twoMSPrime I have stored in an array like this
Eigen::ArrayXXd spinCGPart(16, 2);
So, 16 different combinations and two columns, one for twoMS and one for twoMSPrime.
Instead of looping over all the different combinations, I would like to implement a coefficient-wise operation like so
Eigen::ArrayXXcd result(16, 1);
result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1), generalExpVal);
Where generalExpVal should be something like
complex generalExpVal(int a, int b, const Matrix2cd& mat) const
{
const Vector2cd& bra = getSpinBasisState(b);
const Vector2cd& ket = getSpinBasisState(a);
return bra.adjoint()*mat*ket;
}
I'm stuck with implementing this last function. The documentation for the binaryExpr() looks like it doesn't allow extra parameters to be given to the function. Is this the case? I need to pass mat as an argument since it changes constantly throughout the calculation. Any suggestion regarding eigen or another way of thinking about the problem would be very helpful and appreciated!
Still not sure what you are actually trying to achieve here, but the easiest way (with C++11 or later) to refer to additional objects in your binary functor is to use a lambda expression:
result = spinCGPart.col(0).binaryExpr(spinCGPart.col(1),
[&](int a, int b){return generalExpVal(a,b,mat);});
Fully compiling example: https://godbolt.org/z/PBJJRW
With C++03 you can manually do that using a helper struct, or using e.g., boost::bind.
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.
I had pleasure of working with function pointers lately. I got to know how they work. Classical example of function pointers is :
int add() {
return (100+10);
}
int sub() {
return (100-10);
}
void print(int x, int y, int (*func)()) {
printf("value is : %d", (x+y+(*func)()));
}
int main() {
int x=100, y=200;
print(x,y,add);
print(x,y,sub);
}
Somebody asked me the other day that how is it better than calling(inside main):
print(add(x,y));
print(sub(x,y));
and I struggled to explain that. Is it only about the stack or there is something else lying underneath?
I don't really understand why the code you show would be a classical example of function pointers. Functions pointers' utility is much more obvious from code like this:
void transform(int *dst, const int *src, size_t len, int (*f)(int))
{
for (size_t i = 0; i < len; ++i)
dst[i] = f(src[i]);
}
Basically, if you accept a pointer to function as a parameter, it allows you to apply a client-provided operation on data of your choice.
The classic use case (which generalizes) is qsort (https://linux.die.net/man/3/qsort). The sort algorithm is general purpose but the implementation does not know how to compare items because they can be of any type. So you pass in a function that it can call in order to compare two elements.
Function pointers are pretty much useless overhead if you hard coded call the one or the other, like your example. Their power comes from being able to dynamically pick and use them, or pass them to other functions:
You can put function pointers in an array, and loop over them; or you can call a selected one based on a user-input or input file content, or other circumstances. In both cases, they will allow to write code that has a single dynamic call, instead of potential long switch or if statement chains.
The second - and even more useful - concept is to pass them to some other function (also sometimes called 'callbacks'); a classic example is to call qsort with your data table and a custom comparison function in form of a function pointer. qsort will then use your comparison function inside the standardized sort algorithm; there is no other way to implement this.
"pointer to function" is an object. So it can be copied,stored,assigned like any other object.
Where as references to functions (normal functions) are not objects.
I think the classic example is.... User interfaces events handling by using callback functions, which has become an obvious pattern for any UI software.
The question might sound a bit weird: I want to do numeric matrix calculations using Boost's ublas and ATLAS/Lapack. I am using the Boost numeric bindings to interface between those two libraries. However, either I just cannot find it or there is no proper documentation on how to use these bindings. Also, I am new to Boost (and actually C++ in general) so I have a hard time finding out how I can use functions provided by Lapack in my code.
The problem I want to solve in the end, is finding the Eigenvalues and -vectors of a symmetric banded matrix. As far as I understood it, I would be using lapack::steqr for this. The thing is, I don't know, how to properly call the function. In the code of the numeric bindings, I can see something like this:
template <typename D, typename E, typename Z, typename W>
inline
int steqr( char compz, D& d, E& e, Z& z, W& work ) {
int const n = traits::vector_size (d);
assert( traits::vector_size (e) == n-1 );
assert( traits::matrix_size1 (z) == n );
assert( traits::matrix_size2 (z) == n );
assert( compz=='N' || compz=='V' || compz=='I' );
...
Now, how do I handle that? I tried steqr<double, double, double, double>(...) and double arrays, which didn't work. Then, to find out the proper arguments to use, I picked one of the asserts and tried to find anything that works with traits::matrix_size1(...) - Even that I couldn't get to compile, neither with a double array nor with a ublas::matrix.
So my question is, in general: When I find such a library without complete documentation, how do I find out how to call functions? I am coming from C mainly and am extremely confused with all these templates. Is the only way really to track down everything in the code? Or are there little tricks? Or can I probably draw information from the error messages?
One example of such an error message is, for the following code:
ublas::matrix<double> empty(N,N);
std::cout << traits::matrix_size1<ublas::matrix>(empty) << std::endl;
Then I get during compilation:
eigenvalues.cpp:40:85: error: no matching function for call to ‘matrix_size1(boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<>, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >&)’
eigenvalues.cpp:40:85: note: candidate is:
/usr/include/boost/numeric/bindings/traits/matrix_traits.hpp:148:18: note: template<class M> std::ptrdiff_t boost::numeric::bindings::traits::matrix_size1(M&)
It is probably useful, that the candidate is listed there, but I just don't know, how to read this line and adjust my code accordingly.
Again: This question is a bit more general, on how to deal with stuff like this. I know the basic concept of classes and templates, but this is just a bit too abstract for my knowledge.
Since I am not too proficient in templated c++, I personally find it much easier to use the cblas interface which is only a thin wrapper over the original Fortran code.
In this approach, you'll have to make your own class for matrices, which would be compatible to the Fortran understanding of what a matrix is. The easiest way is probably to inherit from std::vector or std::valarray and provide your own indexing operation.
Yes, it's a bit of work. But it's not as bad as it sounds :-).
And by the way, beware of using the single-precision routines (ssteqr) with double precision arguments. LAPACK will not report any error, but the result is going to be plain wrong.