I'm trying to use controlled stepper in boost odeint with thrust::host_vector container and thrust::complex<double> data type. The following code compiles when I use std::vector and std::complex<double>, however when I use thrust container and/or data type, compiler throws an error.
Secondly, the error occurs only when I use a controlled stepper and the simple stepper works with thrust (you can uncomment the appropriate parts of the code). Is there a mistake in my code or is it coming from odeint?
#include <iostream>
#include <vector>
#include <complex>
#include <thrust/host_vector.h>
#include <thrust/for_each.h>
#include <thrust/transform.h>
#include <thrust/complex.h>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/thrust/thrust.hpp>
using namespace boost::numeric::odeint;
typedef std::complex<double> c_type;
typedef std::vector<c_type> state_vec;
//typedef thrust::complex<double> c_type;
//typedef thrust::host_vector<c_type> state_vec;
template<typename data_type, typename complex_type>
struct multiply {
data_type a;
multiply (data_type a): a(a) {}
complex_type operator()(const complex_type& x){
return -a*x;
}
};
template<typename state_type, typename data_type>
struct exp_system {
const data_type gamma;
exp_system (data_type gamma): gamma(gamma) {}
void operator()(const state_type &x, state_type &dxdt, const data_type){
thrust::transform(x.begin(), x.end(), dxdt.begin(),
multiply<data_type, c_type>(gamma));
}
};
int main()
{
state_vec x(2);
x[0] = c_type(1.0, 0.0);
x[1] = c_type(0.10, 0.0);
double gamma = 0.15;
double t_final = 10.0;
runge_kutta_dopri5<state_vec> stepper;
auto c_stepper = make_controlled(1.E-5, 1.E-5, stepper);
auto n_steps = integrate_adaptive(c_stepper,
exp_system<state_vec, double>(gamma),
x , 0.0 , t_final, 0.01 );
//auto n_steps = integrate_adaptive(stepper,
// exp_system<state_vec, double>(gamma),
// x, 0.0, t_final, 0.01);
std::cout << n_steps << std::endl;
return 0;
}
Related
Visual Studio 2017, c++ code, point-coord of city; work_type = float or double
#include <cstdio>
#include <iostream>
#include <vector>
#include <set>
#include <cmath>
#include <algorithm>
#define work_type double
using namespace std;
//n <= 5 000
//-10 000 <= x, y <= 10 000
const int MAXN = 5000;
struct point {
int x;
int y;
point operator-(point& b) {
point out = { x - b.x, y - b.y };
return out;
}
};
work_type dist(point& a, point& b) {
return sqrt(work_type(pow((a - b).x, 2) + pow((a - b).y, 2)));
}
point points[MAXN];
int main(){...}
Visual Studio says that MAXN undeclared in the string. where i'm create massive of structures. I can't understand why it
I'd like to build a rule that takes in a few parameters from a parsed line then sets a few as constant. Is that possible? An (invalid) example to illustrate what I'm trying to do is below. I think I'm using _r1 incorrectly here, but I'm not sure how to get at the right thing. Assume I don't want to just modify r before sending it into the parser.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_sequence.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#include <string>
using namespace boost::spirit::qi;
struct Sample
{
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
const rule<std::string::const_iterator, Sample()> AnythingAndOne = int_ >> eps[_r1.b = 1] >> eoi;
int main()
{
std::string z("3");
Sample r;
parse(z.begin(), z.end(), AnythingAndOne, r);
return 0;
}
Again, with reference to Boost Spirit: "Semantic actions are evil"? I'd avoid the semantic action.
You can directly synthesize a particular attribute value by using qi::attr:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
struct Sample {
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
namespace qi = boost::spirit::qi;
int main()
{
std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
= qi::int_ >> qi::attr(1) >> qi::eoi;
if (parse(z.begin(), z.end(), AnythingAndOne, r))
std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
std::cout << "Parse failed\n";
}
Prints
Parsed: (3 1)
#include <cstdint>
#include <cstring>
template<typename T>
T oph_(const char *s){
constexpr std::size_t MAX = sizeof(T);
const std::size_t size = strnlen(s, MAX);
T r = 0;
for(auto it = s; it - s < size; ++it)
r = r << 8 | *it;
return r;
}
inline uint64_t oph(const char *s){
return oph_<uint64_t>(s);
}
int main(){
uint64_t const a = oph("New York City");
uint64_t const b = oph("Boston International");
return a > b;
}
I want to convert first 8 characters from const char * to uint64_t so I can easily compare if two strings are greater / lesser.
I am aware that equals will semi-work.
However I am not sure if this is most efficient implementation.
I want the implementation to work on both little and big endian machines.
This is a C implementation, that should be faster that your implementation, but I still need to use strncpy which should be the bottleneck
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <byteswap.h>
union small_str {
uint64_t v;
char buf[8];
};
static uint64_t fill_small_str(const char *str)
{
union small_str ss = { 0 };
strncpy(ss.buf, str, 8);
#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
return ss.v;
#else
return bswap_64(ss.v);
#endif
}
int main(void)
{
uint64_t const a = fill_small_str("Aew York City");
uint64_t const b = fill_small_str("Boston International");
printf("%lu ; %lu ; %d\n", a, b, (a < b));
return 0;
}
The following code doesn't compile on the latest Microsoft Visual Studio. Could someone enlighten me on what I'm doing wrong here?
#include <iostream>
#include <iomanip>
#include <array>
template <typename T, std::size_t M, std::size_t N>
using Matrix = std::array<T, M * N>;
template <typename T, std::size_t M, std::size_t N>
std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &matrix)
{
for (auto i = 0; i < M; ++i)
{
for (auto j = 0; j < N; ++j)
{
os << std::setw(5) << matrix[i * N + j];
}
os << std::endl;
}
return os;
}
int main(int argc, const char * const argv[])
{
Matrix<float, 2, 3> matrix{
1.1f, 1.2f, 1.3f,
2.1f, 2.2f, 2.3f
};
std::cout << matrix << std::endl;
return 0;
}
Here is a snapshot of the compiler error:
1>main.cpp(30): error C2679: binary '<<': no operator found which takes a right-hand operand of type 'std::array<T,6>' (or there is no acceptable conversion)
1> with
1> [
1> T=float
1> ]
Edit:
The following code works though:
#include <iostream>
#include <iomanip>
#include <array>
template <typename T, std::size_t M, std::size_t N>
using Matrix = std::array<std::array<T, N>, M>;
template <typename T, std::size_t M, std::size_t N>
std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &matrix)
{
for (auto row : matrix)
{
for (auto element : row)
{
os << std::setw(5) << element;
}
os << std::endl;
}
return os;
}
int main(int argc, const char * const argv[])
{
Matrix<float, 2, 3> matrix{
1.1f, 1.2f, 1.3f,
2.1f, 2.2f, 2.3f
};
std::cout << matrix << std::endl;
return 0;
}
Bearing in mind #dyp's comment what you have to do here is to create the new type instead of alias that will have 2 independent params.
So you just use aggregation including actual data as a field, like:
template <typename T, std::size_t M, std::size_t N>
class Matrix
{
private:
std::array<T, M * N> _data;
template <typename T1, std::size_t M1, std::size_t N1> friend std::ostream &operator<<(std::ostream &os, const Matrix<T1, M1, N1> &matrix);
public:
template <typename...Args>
Matrix(Args... args):
_data{{std::forward<Args>(args)...}}
{}
};
I am trying to cluster video frames abnormal and normal. I divided into frames as normal and abnormal with frames. I have two problem, I am not sure whether my approach is true or not and I got an unexpected error.
Please help me.
Error code: bowTrainer.add(features1);
My full code is as below:
// Bow.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <windows.h>
#include "opencv2/ml/ml.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <limits>
#include <cstdio>
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
using std::vector;
using std::iostream;
int main()
{
initModule_nonfree();
Ptr<FeatureDetector> features = FeatureDetector::create("SIFT");
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create("SIFT");
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
//defining terms for bowkmeans trainer
TermCriteria tc(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 10, 0.001);
int dictionarySize = 100;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(descriptor, matcher);
//**creating dictionary**//
Mat trainme(0, dictionarySize, CV_32FC1);
Mat labels(0, 1, CV_32FC1); //1d matrix with 32fc1 is requirement of normalbayesclassifier class
int i=0;
while(i<10)
{
char filename[255];
string n;
n=sprintf(filename, "C:\\Users\\Desktop\\New folder\\View_001\\frame_000%d.jpg",i);
Mat img = imread(filename, 0);
Mat features1;
vector<KeyPoint> keypoints;
descriptor->compute(img, keypoints, features1);
bowTrainer.add(features1);
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
Mat bowDescriptor;
bowDE.compute(img, keypoints, bowDescriptor);
trainme.push_back(bowDescriptor);
float label = 1.0;
labels.push_back(label);
i++;
}
int j=11;
while(j<21)
{
char filename2[255];
string n;
n=sprintf(filename2, "C:\\Users\\Desktop\\New folder\\View_001\\frame_000%d.jpg",j);
cout<<filename2;
Mat img2 = imread(filename2, 0);
Mat features2;
vector<KeyPoint> keypoints2;
descriptor->compute(img2, keypoints2, features2);
bowTrainer.add(features2);
Mat bowDescriptor2;
bowDE.compute(img2, keypoints2, bowDescriptor2);
trainme.push_back(bowDescriptor2);
float label = 2.0;
labels.push_back(label);
j++;
}
NormalBayesClassifier classifier;
classifier.train(trainme, labels);
//**classifier trained**//
//**now trying to predict using the same trained classifier, it should return 1.0**//
Mat tryme(0, dictionarySize, CV_32FC1);
Mat tryDescriptor;
Mat img3 = imread("C:\\Users\\Desktop\\New folder\\View_001\\frame_0121.jpg", 0);
vector<KeyPoint> keypoints3;
features->detect(img3, keypoints3);
bowDE.compute(img3, keypoints3, tryDescriptor);
tryme.push_back(tryDescriptor);
cout<<classifier.predict(tryme)<<endl;
waitKey(0);
system("PAUSE");
return 0;
}