I'm having trouble compiling this program with #include. I see that if I comment out this line it compiles.
MatrixXd A = (1.0 / (double) d) * (p * U * p.transpose() - (p * u) * (p * u).transpose()).inverse();
I am unable to change the header since I need to run this code in ROS and I have to use the Eigen library built within. I am using the code as described in this link
How to fit a bounding ellipse around a set of 2D points.
Any help is greatly appricated.
pound include iostream
pound include Eigen/Dense
using namespace std;
using Eigen::MatrixXd;
int main ( )
{
//The tolerance for error in fitting the ellipse
double tolerance = 0.2;
int n = 12; // number of points
int d = 2; // dimension
MatrixXd p(d,n); //Fill matrix with random points
p(0,0) = -2.644722;
p(0,1) = -2.644961;
p(0,2) = -2.647504;
p(0,3) = -2.652942;
p(0,4) = -2.652745;
p(0,5) = -2.649508;
p(0,6) = -2.651345;
p(0,7) = -2.654530;
p(0,8) = -2.651370;
p(0,9) = -2.653966;
p(0,10) = -2.661322;
p(0,11) = -2.648208;
p(1,0) = 4.764553;
p(1,1) = 4.718605;
p(1,2) = 4.676985;
p(1,3) = 4.640509;
p(1,4) = 4.595640;
p(1,5) = 4.546657;
p(1,6) = 4.506177;
p(1,7) = 4.468277;
p(1,8) = 4.421263;
p(1,9) = 4.383508;
p(1,10) = 4.353276;
p(1,11) = 4.293307;
cout << p << endl;
MatrixXd q = p;
q.conservativeResize(p.rows() + 1, p.cols());
for(size_t i = 0; i < q.cols(); i++)
{
q(q.rows() - 1, i) = 1;
}
int count = 1;
double err = 1;
const double init_u = 1.0 / (double) n;
MatrixXd u = MatrixXd::Constant(n, 1, init_u);
while(err > tolerance)
{
MatrixXd Q_tr = q.transpose();
cout << "1 " << endl;
MatrixXd X = q * u.asDiagonal() * Q_tr;
cout << "1a " << endl;
MatrixXd M = (Q_tr * X.inverse() * q).diagonal();
cout << "1b " << endl;
int j_x, j_y;
double maximum = M.maxCoeff(&j_x, &j_y);
double step_size = (maximum - d - 1) / ((d + 1) * (maximum + 1));
MatrixXd new_u = (1 - step_size) * u;
new_u(j_x, 0) += step_size;
cout << "2 " << endl;
//Find err
MatrixXd u_diff = new_u - u;
for(size_t i = 0; i < u_diff.rows(); i++)
{
for(size_t j = 0; j < u_diff.cols(); j++)
u_diff(i, j) *= u_diff(i, j); // Square each element of the matrix
}
err = sqrt(u_diff.sum());
count++;
u = new_u;
}
cout << "3 " << endl;
MatrixXd U = u.asDiagonal();
MatrixXd A = (1.0 / (double) d) * (p * U * p.transpose() - (p * u) * (p * u).transpose()).inverse();
MatrixXd c = p * u;
cout << A << endl;
cout << c << endl;
return 0;
}
If I replace the obvious pound include bogus by
#include <iostream>
#include <Eigen/Dense>
it compiles just fine. It also runs, prints some numbers and returns 0.
Related
I'm trying to implement the shooting method which is used to solve 2nd-order ordinary differential equations with boundary conditions in C++. The equation is d^2y/dx^2 = 2ydy/dx. The boundary conditions provided are at x = 0, u1 =0.5 and at x = 1, u1 =1. The step size for x is 0.25. The values of U1 and U2 are being solved simultaneously at each x/iteration. However, on printing the values of U1 and U2 I get 0 as the output.
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
int i{0}, j{0};
double K1_one, K2_one, K3_one, K4_one, K_one;
double K1_two, K2_two, K3_two, K4_two, K_two;
double x[5] = {0, 0.25, 0.5, 0.75, 1};
double U1[5] = {0.5};
double U2[5] = {};
double G1{0}, G2{0}, G3{0};
double a{0}, b{0};
double f1(double u2)
{
return u2;
}
double f2(double u1, double u2)
{
return 2 * u1 * u2;
}
double RK4_f1(double U2[5])
{
K1_one = 0.25 * (f1(U2[i - 1]));
K2_one = 0.25 * (f1(U2[i - 1] + K1_one / 2));
K3_one = 0.25 * (f1(U2[i - 1] + K2_one / 2));
K4_one = 0.25 * (f1(U2[i - 1] + K3_one));
K_one = (K1_one + 2 * K2_one + 2 * K3_one + K4_one) / 6;
U1[i] = U1[i - 1] + K_one;
a = U1[i];
return a;
}
double RK4_f2(double U1[5], double U2[5])
{
K1_two = 0.25 * (f2(U1[i - 1], U2[i - 1]));
K2_two = 0.25 * (f2(U1[i - 1] + 0.25 / 2, U2[i - 1] + K1_two / 2));
K3_two = 0.25 * (f2(U1[i - 1] + 0.25 / 2, U2[i - 1] + K2_two / 2));
K4_two = 0.25 * (f2(U1[i - 1] + 0.25, U2[i - 1] + K3_two));
K_two = (K1_two + 2 * K2_two + 2 * K3_two + K4_two) / 6;
U2[i] = U2[i - 1] + K_two;
b = U2[i];
return b;
}
int main()
{
cout << "Enter your first random guess for u2" << endl;
cin >> G1;
U2[0] = G1;
cout << "\nu1[i]\tu2[i]\n"
<< endl;
for (int i = 1; i < 5; i++)
{
for (int j = 1; j <= 2; j++)
{
if (j == 1)
{
a = RK4_f1(U2);
}
else
{
b = RK4_f2(U1, U2);
}
}
cout << a << "\t" << b << endl;
}
cout << "Enter your second random guess for u2" << endl;
cin >> G2;
U2[0] = G2;
cout << "\nu1[i]\tu2[i]\n"
<< endl;
for (int i = 1; i < 5; i++)
{
for (int j = 1; j <= 2; j++)
{
if (j == 1)
{
a = RK4_f1(U2);
}
else
{
b = RK4_f2(U1, U2);
}
}
cout << a << "\t" << b << endl;
}
}
something does not work as expected, please give me a piece of advice.
I try to find the PI number with many decimals, I user with success the atan series
but I try to use a faster method and it seems that Chudnovsky is one of the solution.
But after some tests it seems that something went wrongly, more exactly there are
just a few exact decimals.
#include "bigInt.h"
#define DECIMALS 200
Bint ONE_() {
string one("1");
for (int i = 1; i <= DECIMALS; i++)
one = one + "0";
return Bint(one.c_str());
}
Bint FOUR_() {
string four("4");
for (int i = 1; i <= DECIMALS; i++)
four = four + "0";
return Bint(four.c_str());
}
Bint EIGHT_() {
string eight("8");
for (int i = 1; i <= DECIMALS; i++)
eight = eight + "0";
return Bint(eight.c_str());
}
static Bint ONE, FOUR, EIGHT;
class Init {
public:
Init() {
ONE = ONE_();
FOUR = FOUR_();
EIGHT = EIGHT_();
}
};
..............
Bint Chudnovsky() {
Bint SQR("10002499687578100594479218787636");
Bint C("426880");
Bint L("13591409");
Bint LS("545140134");
Bint X("1");
Bint M("1");
Bint B("-262537412640768000");
Bint PI(L);
Bint K("6");
int i = 1;
while(i < 100) {
M = M * (K * K * K - K * 16) / (i + 1) / (i + 1) / (i++ + 1);
L = L + LS;
X = X * B;
PI = PI + M * L / X;
K = K + 12;
}
PI = ONE / PI;
PI = C *SQR * PI;
return PI;
}
.....................
main()
{
cout << "START ------------------------------" << endl;
auto start = std::chrono::high_resolution_clock::now();
Bint PI = Chudnovsky();
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
cout << "Elapsed time: " << elapsed.count() << " s" << endl;
cout << " Chudnovsky formula" << endl;
cout << endl << PI << endl << endl;
.................
}
START ------------------------------
Elapsed time: 21.3608 s
Chudnovsky formula
31415926535897342076684535915783681294558937929099183167837859930489914621802640182485862944746935361889264019646528185561923712250878477720742566131296615384026777503347886889431404794013630226633347235010074370488851025463587840
I am used to write C++ project in CodeBlocks, but for some stupid reasons I have to show it to my teacher in VisualStudio. I tried to make a console app or an empty project, and copied my main file there, but with the first one I get bunch of erorrs and the second one I get 'The system cannot find the way specified'. What is different in VisualStudio? I don't understand at all what is wrong.
here is my code
#include <iostream>
#include <fstream>
#include <math.h>
using namespace std;
const int kroku = 1000;
const double aa = 0; //pocatecni bod intervalu
const double bb = 1; //konečný bod intervalu
double a; //parametr
const double h = (bb - aa) / kroku; //krok
double p(double t) { //(py')' - qy = f
return exp(a*pow(t, 2));
}
double q(double t) {
return -exp(a*pow(t, 2))*pow(a, 2)*pow(t, 2);
}
double dp(double t) {
return 2 * t*a*exp(a*pow(t, 2));
}
double y[kroku + 1]; //řešení původní rce
double dydx[kroku + 1];
double z[kroku + 1]; //řešení dílčí rce
double dzdx[kroku + 1];
double x[kroku + 1]; //rozdělení intervalu (aa, bb) po krocích h
void generateX() { //generuje hodnoty x
for (int k = 0; k <= kroku; k++) {
x[k] = aa + k*h;
}
}
double partial(double pp1, double pp2, double w[kroku + 1], double dwdx[kroku + 1], double v)//řešení rce (pw')' - qw = g s pp
{
w[v] = pp1; //inicializace - počáteční podmínka
dwdx[v] = pp2; //inicialzace - počáteční podmínka
for (int i = 0; i <= kroku; i++) { //substituce dwdx proměnná -> dwdx = (w_(n+1) - w_n)/h) && dwdx =
w[i + 1] = h*dwdx[i] + w[i];
dwdx[i + 1] = (h / p(aa + h*i))*(q(aa + h*i)*w[i] - dp(aa + h*i)*dwdx[i]) + dwdx[i];
}
return 0;
}
double omega1, omega2; //nové počáteční podmínky omega1 = y(x0), omega2 = y'(x0)
void print(double N[kroku + 1])
{
fstream file;
file.open("data.dat", ios::out | ios::in | ios::trunc);//otevření/vytvoření(trunc) souboru
if (file.is_open()) //zápis do souboru
{
cout << "Writing";
file << "#" << "X" << " " << "Y" << endl;
for (int j = 0; j <= kroku; j++) {
file << x[j] << " " << N[j] << endl;
}
file << "#end";
}
else
{
cout << "Somethinq went wrong!";
}
file.close();
}
int main()
{
double alpha; //pocatecni podminka y(aa) = alpha
double beta; //y(bb) = beta
cout << "Assign the value of beta " << endl;
cin >> beta;
cout << "Assign the value of alpha " << endl;
cin >> alpha;
cout << "Assign the value of parameter a" << endl;
cin >> a;
double alpha1 = 0; //alpha1*p(aa)*y'(aa) - beta1*y(aa) = gamma1
//double alpha2 = 0; //alpha2*p(bb)*y'(bb) + beta2*y(bb) = gamma2
double beta1 = -1;
double beta2 = 1;
double gamma1 = alpha;
double gamma2 = beta;
generateX();
partial(alpha1, beta1 / p(aa), z, dzdx, aa); //(pz')'-qz = 0
omega1 = gamma2 / beta2;
omega2 = 1 / (z[kroku] * p(bb))*(gamma1 + dzdx[kroku] * p(bb));
partial(omega1, omega2, y, dydx, aa);//(py')' - qy = f = 0
print(y);
return 0;
strong text}
when I add
#include "stdafx.h"
I get four errors
2x 'Expression must have integral or unscoped enum type'
2x 'subscript is not of integral type'
for these lines
w[v] = pp1;
dwdx[v] = pp2;
Could anyone please help me? Thank you a lot
array subscript v in your line
w[v]
can not be double. It must be of interger type.
Given a set of 2d points (in Cartesian form), I need to find the minimum-area ellipse such that every point in the set lies either on or inside the ellipse.
I have found the solution in the form of pseudo-code on this site, but my attempt to implement the solution in C++ has been unsuccessful.
The following image illustrates graphically what the solution to my problem looks like:
In my attempt, I used the Eigen library for the various operations on matrices.
//The tolerance for error in fitting the ellipse
double tolerance = 0.2;
int n = 10; // number of points
int d = 2; // dimension
MatrixXd p = MatrixXd::Random(d,n); //Fill matrix with random points
MatrixXd q = p;
q.conservativeResize(p.rows() + 1, p.cols());
for(size_t i = 0; i < q.cols(); i++)
{
q(q.rows() - 1, i) = 1;
}
int count = 1;
double err = 1;
const double init_u = 1.0 / (double) n;
MatrixXd u = MatrixXd::Constant(n, 1, init_u);
while(err > tolerance)
{
MatrixXd Q_tr = q.transpose();
cout << "1 " << endl;
MatrixXd X = q * u.asDiagonal() * Q_tr;
cout << "1a " << endl;
MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();
cout << "1b " << endl;
int j_x, j_y;
double maximum = M.maxCoeff(&j_x, &j_y);
double step_size = (maximum - d - 1) / ((d + 1) * (maximum + 1));
MatrixXd new_u = (1 - step_size) * u;
new_u(j_x, 0) += step_size;
cout << "2 " << endl;
//Find err
MatrixXd u_diff = new_u - u;
for(size_t i = 0; i < u_diff.rows(); i++)
{
for(size_t j = 0; j < u_diff.cols(); j++)
u_diff(i, j) *= u_diff(i, j); // Square each element of the matrix
}
err = sqrt(u_diff.sum());
count++;
u = new_u;
}
cout << "3 " << endl;
MatrixXd U = u.asDiagonal();
MatrixXd A = (1.0 / (double) d) * (p * U * p.transpose() - (p * u) * (p * u).transpose()).inverse();
MatrixXd c = p * u;
The error occurs on the following line:
MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();
and it reads as follows:
run: /usr/include/eigen3/Eigen/src/Core/DenseBase.h:261: void Eigen::DenseBase<Derived>::resize(Eigen::Index, Eigen::Index) [with Derived = Eigen::Diagonal<Eigen::Matrix<double, -1, -1>, 0>; Eigen::Index = long int]: Assertion `rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize."' failed.
Aborted (core dumped)
Can someone please point out why this error is occurring or even better, give me some advice on how to fit an ellipse to a set of points using C++?
With Eigen, you can get the diagonal vector from a matrix with .diagonal(); you can treat a vector as a diagonal matrix with .asDiagonal(); but you cannot treat a dense matrix as a diagonal matrix. So that line should be
MatrixXd M = (Q_tr * X.inverse() * q).diagonal();
I have to implement a DCT algorithm in C++, here is my present code :
// dct: computes the discrete cosinus tranform of a 8x8 block
template<typename Tin=uchar,typename Tout=float>
inline cv::Mat_<Tout> dct(const cv::Mat_<Tin>& oBlock) {
int indexNumber;
float pi = 3.14159265359;
float fcoscos, fxy, cos1, cos2, forCos1, forCos2;
cv::Mat_<Tout> resultBloc(8, 8);
for (int u = 0; u < oBlock.rows; u++){
for (int v = 0; v < oBlock.cols; v++){
float cu=0, cv=0, Result=0;
// calcul c(u)
if (u == 0){
cu = (float)sqrt((float)1 / (float)oBlock.rows);
}
else {
cu = (float)sqrt((float)2 / (float)oBlock.rows);
}
// calcul c(v)
if (v == 0){
cv = (float)sqrt((float)1 / (float)oBlock.cols);
}
else {
cv = (float)sqrt((float)2 / (float)oBlock.cols);
}
float sums = 0;
for (int x = 0; x < oBlock.rows; x++){
for (int y = 0; y < oBlock.cols; y++){
indexNumber = x * oBlock.rows + y;
fxy = (int)oBlock.data[indexNumber];
forCos1 = (pi*((2 * x) + 1)*u) / (2 * oBlock.rows);
forCos2 = (pi*((2 * y) + 1)*v) / (2 * oBlock.cols);
cos1 = cos(forCos1);
cos2 = cos(forCos2);
fcoscos = fxy * cos1 * cos2;
sums += fcoscos;
}
}
// calcul total
Result = sums*cu*cv;
indexNumber = u * oBlock.rows + v;
resultBloc.data[indexNumber] = Result;
}
}
return resultBloc;
}
I compared the result with the cv DCT algorithm as follow :
cv::Mat_<float> tempImage(8,8);
for (int i = 0; i < vecImageCut[0].cols*vecImageCut[0].rows; i++){
tempImage.data[i] = (int)vecImageCut[0].data[i];
}
cv::Mat_<float> dctCV;
cv::dct(tempImage, dctCV);
for (int i = 0; i < blocksAfterDCT[0].cols*blocksAfterDCT[0].rows; i++){
std::cerr << "Difference DCT for pixel " << i << " : " << dctCV.data[i] - blocksAfterDCT[0].data[i] << std::endl;
}
The results between my DCT and the cv DCT are very different so i assume my DCT algorithm is wrong but i searched for hours and i can't find my mistake, can anyone tell me where i did something wrong ?
Your index calculations are wrong. In indexNumber = x * oBlock.rows + y;, since x is counting rows it needs to be multiplied by the number of columns:
indexNumber = x * oBlock.cols + y;
The same for indexNumber = u * oBlock.rows + v;
indexNumber = u * oBlock.cols + v;