I have a doubt regarding the parameter search_radius in nanoflann's radiusSearch function. My code is this:
#include <iostream>
#include <vector>
#include <map>
#include "nanoflann.hpp"
#include "Eigen/Dense"
int main()
{
Eigen::MatrixXf mat(7, 2);
mat(0,0) = 0.0; mat(0,1) = 0.0;
mat(1,0) = 0.1; mat(1,1) = 0.0;
mat(2,0) = -0.1; mat(2,1) = 0.0;
mat(3,0) = 0.2; mat(3,1) = 0.0;
mat(4,0) = -0.2; mat(4,1) = 0.0;
mat(5,0) = 0.5; mat(5,1) = 0.0;
mat(6,0) = -0.5; mat(6,1) = 0.0;
std::vector<float> query_pt(2);
query_pt[0] = 0.0;
query_pt[1] = 0.0;
typedef nanoflann::KDTreeEigenMatrixAdaptor<Eigen::MatrixXf> KDTree;
KDTree index(2, mat, 10);
index.index->buildIndex();
{ // Find nearest neighbors in radius
const float search_radius = 0.1f;
std::vector<std::pair<size_t, float> > matches;
nanoflann::SearchParams params;
const size_t nMatches = index.index->radiusSearch(&query_pt[0], search_radius, matches, params);
std::cout << "RadiusSearch(): radius = " << search_radius << " -> "
<< nMatches << " matches" << std::endl;
for(size_t i = 0; i < nMatches; i++)
std::cout << "Idx[" << i << "] = " << matches[i].first
<< " dist[" << i << "] = " << matches[i].second << std::endl;
std::cout << std::endl;
}
}
What I want is to have the points within a radius of 0.1, so, what I expected was the first three elements in the matrix but to my surprise it returned the first 5 elements. Checking the distances return it seems to me that it is not the actual distance but the distance-squared (right?) so I squared the radius to get what I expected but unfortunately it returns only the first point.
So I increased a little bit the radius from 0.1^2 = 0.01 to 0.02 and finally got the points I wanted.
Now, the question is, shouldn't the points laying on the perimeter of the neighborhood be included? Where can I change this condition in nanoflann?
The full definition of KDTreeEigenMatrixAdaptor starts like this:
template <class MatrixType, int DIM = -1,
class Distance = nanoflann::metric_L2,
typename IndexType = size_t>
struct KDTreeEigenMatrixAdaptor
{
//...
So, yes: the default metric is the squared Euclidean distance, the L2_Adaptor struct, and documented as follows:
Squared Euclidean distance functor (generic version, optimized for high-dimensionality data sets).
As for the second issue, there are two aspects. First one is that you should not rely on equality when it comes to floating point numbers (obligatory reference: David Goldberg, What every computer scientist should know about floating-point arithmetic, ACM Computing Surveys, 1991).
Second is that in principle, you are right. nanoflann is based on FLANN, in which's source code you may find the implementation of CountRadiusResultSet class, used by the radiusSearch search method. Its key method has the following implementation:
void addPoint(DistanceType dist, size_t index)
{
if (dist<radius) {
count++;
}
}
Whereas it seems that a common definition of this problem involves "less than or equal", as for example in the following reference (Matthew T. Dickerson, David Eppstein, Algorithms for Proximity Problems in Higher Dimensions, Computational Geometry, 1996):
Problem 1. (Fixed-Radius Near-Neighbors Search) Given a finite set S of n distinct points in Rd and a distance 𝛿. For each point p ∈ S report all pairs of points (p,q), q ∈ S such that the distance from p to q is less than or equal to 𝛿.
(the last emphasis by me)
Still, that's mathematics and in Computer Science the floating-point arithmetic problems effectively inhibit thinking about equality in such a strict manner.
It seems that your only choice here is to slightly increase the radius, because the usage of the CountRadiusResultSet class is hard-coded in radiusSearch method implementation inside FLANN.
Related
I have a range of base-10 logarithmically spaced points and I need to calculate the #points-per-decade for the points.
Based on this section from wikipedia we have #decades = log10(start / stop). From this we should be able to calculate #points-per-decade as #points / #decades. However this does not give the right answer. Here is a short program I've been using to test this method:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <float.h>
class GenLog {
public:
GenLog(double start, double step) : curVal(start), step(step) {
m = 1.0 / step;
b = std::log10(start);
stepi = 0;
};
double operator()() {
++stepi;
double arg = m*stepi+b;
if (arg < DBL_MAX_10_EXP) {
curVal += pow(10.0, arg) - curVal;
} else {
curVal = DBL_MAX;
}
return curVal;
}
private:
double step, stepi, curVal, m, b;
};
int main(int argc, char *argv[])
{
if (argc < 5) {
std::cout << "Wrong number of args: format is [start] [stop] [points-per-decade] [size]\n";
return -1;
}
double start = atof(argv[1]);
double stop = atof(argv[2]);
double ppd = atof(argv[3]);
int size = atoi(argv[4]);
std::vector<double> vals;
vals.push_back(start);
// generate total number of points - 2 (excluding endpoints, GenLog takes in
// starting freq, and #point/dec
std::generate_n(std::back_inserter(vals), size - 2, GenLog(start, ppd));
vals.push_back(stop);
for (auto i : vals) {
std::cout << i << " ";
}
std::cout << "\n---TEST BACKWARDS PPD---\n";
std::cout << "ppd: " << ppd << "\t " << (vals.size()) / std::log10(*std::prev(vals.end()) / vals.front()) << "\n";
return 0;
}
Example output:
This generates a logarithmically spaced series of points from 1 to 10.1681 with 13 points per decade for a total of 15 points--although in principal you only need the starting point, and the points per decade to generate the next logarithmic point in the series.
As you can see the resulting numbers (13 and 14.8922) are not the same when they should be.
./so 1.0 10.1681 13 15
1 1.19378 1.4251 1.70125 2.03092 2.42446 2.89427 3.45511 4.12463 4.92388 5.87802 7.01704 8.37678 10 10.1681
---TEST BACKWARDS PPD---
ppd: 13 14.8922
based on my testing so far I do not think it is anything like an off-by-one error. Perhaps the calculations for #points-per-decade is conceptually incorrect? If so what is the correct way of calculating it?
My way of calculating #points-per-decade was incorrect
So based on the last equation in the calculations section of the wikipedia article we have:
step-size = 10^(1 / #points-per-decade)
since we know the step-size we can re-arrange to
1/#points-per-decade * ln(10)=ln(step-size)
and finally solve for #points-per-decade
#points-per-decade = ln(10) / ln(step-size)
How can I compute the square root of 3 in C++ using the following relation?
Here is what I tried:
#include <iostream>
#include <cmath>
int main(void)
{
double prevRes(1);
double res(1 + 1./2);
short i(2);
while (abs(prevRes - res) > 1.e-14)
{
prevRes = res;
res = i + 1 / res;
i = 3 - i;
}
std::cout << res << std::endl;
return 0;
}
The program runs forever.
It's a shame that this question wasn't asked with more effort and detail so that it was taken seriously. I've always been confused by the appearance and concept of continued fractions, but it's been nice taking the time to think about them and implement one.
This particular one can be done iteratively. As #wally states, the continued fraction shown in the question does not converge to sqrt(3), but to ~1.36603. The two top-most coefficients should be 1. Notice that sqrt(3) ~= 1 + (1/1.36603), and that all the coefficients in the continued fraction alternate.
So, if a loop works from the bottom up until the alternating continued fraction converges then one more calculation after the loop will give us the correct answer. At each iteration the reciprocal of the current value is added to either 1 or 2. The initial value can be anything.
#include <iostream>
#include <cmath>
#include <limits>
// Calculate square root of 3 with a continued fraction
int main(void) {
int iterations = 0;
double epsilon = 1.0e-12; //error bounds
double prev = 0.0;
double curr = 1.0; //initial estimate
double error = curr - prev;
// Don't show more precision than we have
std::cout.precision(std::numeric_limits<double>::digits10);
// Iterate the continued fraction [1;1,2,1,2...]
// from the bottom up until it converges with errors
// less than epsilon.
while (std::abs(error) > epsilon) {
prev = curr;
// Unroll the loop with the repeating pattern here
curr = 2 + (1/curr);
curr = 1 + (1/curr);
iterations++;
error = curr - prev;
std::cout << "error at iteration " << iterations
<< " was " << error << std::endl;
}
// The actual continued fraction we want to evaluate
// is [1;1,1,2,1,2,...].
// The two top-level coefficients are 1, so do
// another half iteration here.
curr = 1 + (1/curr);
std::cout << "sqrt(3) = " << curr << " after "
<< iterations << " iterations" << std::endl;
return 0;
}
This strategy should work for any continued fraction with that ends in a repeating pattern of coefficients.
As for why the original code does not complete, I'll leave that to the author to figure out. Print statements or a pocket calculator will help.
The formula seems a bit wrong if I compare it to wikipedia. Note the 1 + is repeated at the start.
Next we can use a recursive function to perform the calculation and provide a number of iterations. Note that we can use a large return value to terminate the recursion (or even zero, but that would require more iterations as it is technically making the wrong assumption).
Finally we keep trying more iterations until the error is small enough.
#include <iostream>
#include <limits>
#include <cmath>
double f(int depth, bool odd = true)
{
if(depth == 0)
return std::numeric_limits<double>::max();
return (odd ? 1 : 2) + 1. / f(--depth, !odd);
}
double sqrt3(int depth = 10)
{
return 1 + 1. / f(depth);
}
int main(void)
{
int depth{2};
double prevRes{sqrt3(depth)};
double res{sqrt3(++depth)};
while(abs(prevRes - res) > 1.e-14)
{
prevRes = res;
res = sqrt3(++depth);
}
std::cout << "Answer is " << res << " at depth " << depth << ".\n";
}
Output:
Answer is 1.73205 at depth 26.
Use the built in sqrt function.
#include <cstdio>
#include <cmath>
int main ()
{
double param, result;
param = 1024.0;
result = sqrt (param);
printf ("sqrt(%f) = %f\n", param, result );
return 0;
}
double sqrt_of_three(bool adds_two, int rec_depth, int max_rec_depth)
{
int x;
if (rec_depth < 2)
x = 1;
else
x = adds_two ? 2 : 1;
if (rec_depth < max_rec_depth)
return x + 1/sqrt_of_three(!adds_two, ++rec_depth, max_rec_depth);
return x;
}
And this method can be called with an estimate for a threshold.
int main()
{
std::cout << sqrt_of_three(true, 0, 10);
}
This is an example how to recursively call a function that calculates the square root of 3. Now you can either manually set the maximum recursion depth by trial and error or you do something that you did with your first approach and check after each complete recursion if the value between two different maximum recursion depths is smaller than some threshold.
It's for sure not the most efficient way to find the square root of three because you have to do n*(n-1)/2 (where n is the recursion depth that satisfied the boundary that you set) recursions in total and depending on how close you want to converge to the real result this can be a lot.
I am being asked to find the roots of f(x) = 5x(e^-mod(x))cos(x) + 1 . I have previously used the Durand-Kerner method to find the roots of the function x^4 -3x^3 + x^2 + x + 1 with the code shown below. I thought I could simply reuse the code to find the roots of f(x) but whenever I replace x^4 -3x^3 + x^2 + x + 1 with f(x) the program outputs nan for all the roots. What is wrong with my Durand-Kerner implementation and how do I go about modifying it to work for f(x)? I would be very grateful for any help.
#include <iostream>
#include <complex>
#include <math.h>
using namespace std;
typedef complex<double> dcmplx;
dcmplx f(dcmplx x)
{
// the function we are interested in
double a4 = 1;
double a3 = -3;
double a2 = 1;
double a1 = 1;
double a0 = 1;
return (a4 * pow(x,4) + a3 * pow(x,3) + a2 * pow(x,2) + a1 * x + a0);
}
int main()
{
dcmplx p(.9,2);
dcmplx q(.1, .5);
dcmplx r(.7,1);
dcmplx s(.3, .5);
dcmplx p0, q0, r0, s0;
int max_iterations = 100;
bool done = false;
int i=0;
while (i<max_iterations && done == false)
{
p0 = p;
q0 = q;
r0 = r;
s0 = s;
p = p0 - f(p0)/((p0-q)*(p0-r)*(p0-s));
q = q0 - f(q0)/((q0-p)*(q0-r)*(q0-s));
r = r0 - f(r0)/((r0-p)*(r0-q)*(r0-s0));
s = s0 - f(s0)/((s0-p)*(s0-q)*(s0-r));
// if convergence within small epsilon, declare done
if (abs(p-p0)<1e-5 && abs(q-q0)<1e-5 && abs(r-r0)<1e-5 && abs(s-s0)<1e-5)
done = true;
i++;
}
cout<<"roots are :\n";
cout << p << "\n";
cout << q << "\n";
cout << r << "\n";
cout << s << "\n";
cout << "number steps taken: "<< i << endl;
return 0;
}
The only thing I have been changing so far is the dcmplx f function. I have been changing it to
dcmplx f(dcmplx x)
{
// the function we are interested in
double a4 = 5;
double a0 = 1;
return (a4 * x * exp(-x) * cos(x) )+ a0;
}
The Durand-Kerner method that you're using requires the function to be continuous on the interval you are working.
Here we ahve a discrepancy between the mathematical view and the limits of the numeric applications. I'd propose you to plot your function (typing the formula in google will give you a quick overview of course for the real part). You'll notice that:
there are an infinity of roots due to the periodicity of the cosinus.
due to the x*exp(-x) the absolute value quickly rises up beyond the maximum precision that a floating point number can hold.
To understand the consequences on your code, I invite you to trace the different iteration. You'll notice that p, r and s are converging very quicky while q is diverging (apparently on the track of one of the huge peak):
At the 2nd iteration q is already at 1e74
At 3rd iteration already beyond what a double can store.
As q is used in the calculation of p,r and s, the error is propagated to the other terms
At 5th iteration, all terms are at NAN
It then continues bravely through the 100 iterations
Perhap's you could make it work by choosing different starting points. If not, you'll have to use some other method and carefully select the interwall on which you're working.
You should have noted in your documentation of the Durand-Kerner method (invented by Karl Weierstrass around 1850) that it only applies to polynomials. Your second function is far from being a polynomial.
Indeed, because of the mod function it has to be declared as a nasty function for numerical methods. Most of them rely on the continuity of the given function, i.e., if the value is close to zero, there is a good chance that there is a root nearby and if the sign changes on an interval then there is a root in the interval. Even the most basic derivate-free methods as the bisection method or Brents method on the sophisticated end of that class pre-suppose these properties.
I have 2 rotations represented as yaw, pitch, roll (Tait-Brian intrinsic right-handed). What is the recommended way to construct a single rotation that is equivalent to both of them?
EDIT: if I understand correctly from the answers, I must first convert yaw, pitch, roll to either matrix or quaternion, compose them and then transform the result back to yaw, pitch, roll representation.
Also, my first priority is simplicity, then numerical stability and efficiency.
Thanks :)
As a general answer, if you make a rotation matrix for each of the two rotations, you can then make a single matrix which is the product of the two (order is important!) to represent the effect of applying both rotations.
It is possible to conceive of instances where "gimbal lock" could make this numerically unstable for certain angles (typically involving angles very close to 90 degrees).
It is faster and more stable to use quaternions. You can see a nice treatment at http://www.genesis3d.com/~kdtop/Quaternions-UsingToRepresentRotation.htm - in summary, every rotation can be represented by a quaternion and multiple rotations are just represented by the product of the quaternions. They tend to have better stability properties.
Formulas for doing this can be found at http://en.m.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
UPDATE using the formulas provided at http://planning.cs.uiuc.edu/node102.html , you can adapt the following code to do a sequence of rotations. While the code is written in (and compiles as ) C++, I am not taking advantage of certain built in C++ types and methods that might make this code more elegant - showing my C roots here. The point is really to show how the rotation equations work, and how you can concatenate multiple rotations.
The two key functions are calcRot which computes the rotation matrix for given yaw, pitch and roll; and mMult which multiplies two matrices together. When you have two successive rotations, the product of their rotation matrices is the "composite" rotation - you do have to watch out for the order in which you do things. The example that I used shows this. First I rotate a vector by two separate rotations; then I compute a single matrix that combines both rotations and get the same result; finally I reverse the order of the rotations, and get a different result. All of which should help you solve your problem.
Make sure that the conventions I used make sense for you.
#include <iostream>
#include <cmath>
#define PI (2.0*acos(0.0))
//#define DEBUG
void calcRot(double ypr[3], double M[3][3]) {
// extrinsic rotations: using the world frame of reference
// ypr: yaw, pitch, roll in radians
double cy, sy, cp, sp, cr, sr;
// compute sin and cos of each just once:
cy = cos(ypr[0]);
sy = sin(ypr[0]);
cp = cos(ypr[1]);
sp = sin(ypr[1]);
cr = cos(ypr[2]);
sr = sin(ypr[2]);
// compute this rotation matrix:
// source: http://planning.cs.uiuc.edu/node102.html
M[0][0] = cy*cp;
M[0][1] = cy*sp*sr - sy*cr;
M[0][2] = cy*sp*cr + sy*sr;
M[1][0] = sy*cp;
M[1][1] = sy*sp*sr + cy*cr;
M[1][2] = sy*sp*sr - cy*sr;
M[2][0] = -sp;
M[2][1] = cp*sr;
M[2][2] = cp*cr;
}
void mMult(double M[3][3], double R[3][3]) {
// multiply M * R, returning result in M
double T[3][3] = {0};
for(int ii = 0; ii < 3; ii++) {
for(int jj = 0; jj < 3; jj++) {
for(int kk = 0; kk < 3; kk++ ) {
T[ii][jj] += M[ii][kk] * R[kk][jj];
}
}
}
// copy the result:
for(int ii = 0; ii < 3; ii++) {
for(int jj = 0; jj < 3; jj++ ) {
M[ii][jj] = T[ii][jj];
}
}
}
void printRotMat(double M[3][3]) {
// print 3x3 matrix - for debug purposes
#ifdef DEBUG
std::cout << "rotation matrix is: " << std::endl;
for(int ii = 0; ii < 3; ii++) {
for(int jj = 0; jj < 3; jj++ ) {
std::cout << M[ii][jj] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
#endif
}
void applyRot(double before[3], double after[3], double M[3][3]) {
// apply rotation matrix M to vector 'before'
// returning result in vector 'after'
double sumBefore = 0, sumAfter = 0;
std::cout << "Result of rotation:" << std::endl;
for(int ii = 0; ii < 3; ii++) {
std::cout << before[ii] << " -> ";
sumBefore += before[ii] * before[ii];
after[ii] = 0;
for( int jj = 0; jj < 3; jj++) {
after[ii] += M[ii][jj]*before[jj];
}
sumAfter += after[ii] * after[ii];
std::cout << after[ii] << std::endl;
}
std::cout << std::endl;
#ifdef DEBUG
std::cout << "length before: " << sqrt(sumBefore) << "; after: " << sqrt(sumAfter) << std::endl;
#endif
}
int main(void) {
double r1[3] = {0, 0, PI/2}; // order: yaw, pitch, roll
double r2[3] = {0, PI/2, 0};
double initPoint[3] = {3,4,5}; // initial point before rotation
double rotPoint[3], rotPoint2[3];
// initialize rotation matrix to I
double R[3][3];
double R2[3][3];
// compute first rotation matrix in-place:
calcRot(r1, R);
printRotMat(R);
applyRot(initPoint, rotPoint, R);
// apply second rotation on top of first:
calcRot(r2, R2);
std::cout << std::endl << "second rotation matrix: " << std::endl;
printRotMat(R2);
// applying second matrix to result of first rotation:
std::cout << std::endl << "applying just the second matrix to result of first: " << std::endl;
applyRot(rotPoint, rotPoint2, R2);
mMult(R2, R);
std::cout << "after multiplication: " << std::endl;
printRotMat(R2);
std::cout << "Applying the combined matrix to the intial vector: " << std::endl;
applyRot(initPoint, rotPoint2, R2);
// now in the opposite order:
double S[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
calcRot(r2, S);
printRotMat(S);
calcRot(r1, R2);
mMult(R2, S);
std::cout << "applying rotation in the opposite order: " << std::endl;
printRotMat(R2);
applyRot(initPoint, rotPoint, R2);
}
Output (with #DEBUG not defined - commented out):
Result of rotation:
3 -> 3
4 -> -5
5 -> 4
second rotation matrix:
applying just the second matrix to result of first:
Result of rotation:
3 -> 4
-5 -> -5
4 -> -3
after multiplication:
Applying the combined matrix to the intial vector:
Result of rotation:
3 -> 4
4 -> -5
5 -> -3
Note that these last two give the same result, showing that you can combine rotation matrices.
applying rotation in the opposite order:
Result of rotation:
3 -> 5
4 -> 3
5 -> 4
Now the result is different - the order is important.
If you are familiar with matrix operations, you may try Rodrigues' rotation formula. If you are familiar with quaternions, you may try the P' = q*P*q' approach.
Quaterion math is a bit more complicated to grasp, but code is simpler and faster.
Implementing this simple root-finding algorithm.
http://en.wikipedia.org/wiki/Durand%E2%80%93Kerner_method
I cannot for the life of me figure out what's wrong with my implementation. The roots keep blowing up and no sign of convergence. Any suggestions?
Thanks.
#include <iostream>
#include <complex>
using namespace std;
typedef complex<double> dcmplx;
dcmplx f(dcmplx x)
{
// the function we are interested in
double a4 = 3;
double a3 = -3;
double a2 = 1;
double a1 = 0;
double a0 = 100;
return a4 * pow(x,4) + a3 * pow(x,3) + a2 * pow(x,2) + a1 * x + a0;
}
int main()
{
dcmplx p(.9,2);
dcmplx q(.1, .5);
dcmplx r(.7,1);
dcmplx s(.3, .5);
dcmplx p0, q0, r0, s0;
int max_iterations = 20;
bool done = false;
int i=0;
while (i<max_iterations && done == false)
{
p0 = p;
q0 = q;
r0 = r;
s0 = s;
p = p0 - f(p0)/((p0-q0)*(p0-r0)*(p0-s0));
q = q0 - f(q0)/((q0-p)*(q0-r0)*(q0-s0));
r = r0 - f(r0)/((r0-p)*(r0-q)*(r0-s0));
s = s0 - f(s0)/((s0-p)*(s0-q)*(s0-r));
// if convergence within small epsilon, declare done
if (abs(p-p0)<1e-5 && abs(q-q0)<1e-5 && abs(r-r0)<1e-5 && abs(s-s0)<1e-5)
done = true;
i++;
}
cout<<"roots are :\n";
cout << p << "\n";
cout << q << "\n";
cout << r << "\n";
cout << s << "\n";
cout << "number steps taken: "<< i << endl;
return 0;
}
A half year late: The solution to the enigma is that the denominator should be an approximation of the derivative of the polynomial, and thus needs to contain the leading coefficient a4 as factor.
Alternatively, one can divide the polynomial value by a4 in the return statement, so that the polynomial is effectively normed, i.e., has leading coefficient 1.
Note that the example code in wikipedia by Bo Jacoby is the Seidel-type variant of the method, the classical formulation is the Jordan-like method where all new approximations are simultaneously computed from the old approximation. Seidel can have faster convergence than the order 2 that the formulation as a multidimensional Newton method provides for Jacobi.
However, for large degrees Jacobi can be accelerated using fast polynomial multiplication algorithms for the required multi-point evaluations of polynomial values and the products in the denominators.
Ah, the problem was that the coefficients of an N-degree polynomial have to be specified as
1*x^N + a*x^(N-1) + b*x^(N-2) ... etc + z;
where 1 is the coefficient of the largest degree term. Otherwise the first root will never converge.
You haven't implemented for formulae correctly. For instance
s = s0 - f(s0)/((s0-p0)*(s0-q0)*(s0-r0));
should be
s = s0 - f(s0)/((s0-p)*(s0-q)*(s0-r));
Look again at the wiki article