Nanoflann findNeighbors raise segfault - c++

So I have the following class KdTree:
#include <nanoflann.hpp>
#include <ctime>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <cstdlib>
#include <iostream>
struct PointCloud
{
struct Point
{
double x,y,z;
};
std::vector<Point> pts;
inline size_t kdtree_get_point_count() const { return pts.size(); }
inline double kdtree_get_pt(const size_t idx, const size_t dim) const
{
if (dim == 0) return pts[idx].x;
else if (dim == 1) return pts[idx].y;
else if (dim == 2) return pts[idx].z;
}
template <class BBOX>
bool kdtree_get_bbox(BBOX& /* bb */) const { return false; }
};
void generatePointCloud(PointCloud &point, const std::vector<std::vector<double>>& given)
{
point.pts.resize(given.size());
for (size_t i = 0; i < given.size(); ++i) {
point.pts[i].x = given[i][0];
point.pts[i].y = given[i][1];
point.pts[i].z = given[i][2];
}
}
using namespace nanoflann;
using Points = std::vector<std::vector<double>>;
class KdTree {
public:
KdTree(const Points& points) {
PointCloud cloud;
generatePointCloud(cloud, points); // just puts points into cloud format
index = std::make_shared<my_kd_tree>(3 /*dim*/, cloud, KDTreeSingleIndexAdaptorParams(10 /* max leaf */) );
index->buildIndex();
}
size_t GetNearest(const std::vector<double>& pt) const {
double query_pt[3] = { pt[0], pt[1], pt[2] };
const size_t num_results = 1;
size_t ret_index;
double out_dist_sqr;
nanoflann::KNNResultSet<double > resultSet(num_results);
resultSet.init(&ret_index, &out_dist_sqr );
index->findNeighbors(resultSet, &query_pt[0], nanoflann::SearchParams(10));
std::cout << "knnSearch(nn="<<num_results<<"): \n";
std::cout << "ret_index=" << ret_index << " out_dist_sqr=" << out_dist_sqr << endl;
return ret_index;
}
typedef KDTreeSingleIndexAdaptor<
L2_Simple_Adaptor<double , PointCloud > ,
PointCloud,
3 /* dim */
> my_kd_tree;
std::shared_ptr<my_kd_tree> index = nullptr;
};
The problem is that the following code raises segfault:
int main()
{
srand(static_cast<unsigned int>(time(nullptr)));
Points points{{1, 5, 8}, {3, 3, 3}, {1, 1, 0}};
KdTree tree(points);
tree.GetNearest({1, 1, 1});
return 0;
}
But if I put GetNearest code in constructor (so that I construct index and find pt's neighbor in constructor itself), or just write constructor and GetNearest code in main, then everything works just fine.
I am new to nanoflann, can't figure what's wrong. Thanks for the help in advance!

I had to dig into the source nanoflann.hpp to find that the second parameter to the constructor for KDTreeSingleIndexAdaptor (cloud in your KdTree constructor) is passed by reference and stored as a reference. This means that the cloud data you pass to nanoflann needs to stay around until you delete the KDTreeSingleIndexAdaptor object.
Because you declare PointCloud cloud as a local variable within your KdTree constructor, it will be destroyed when the constructor ends leaving the kdtree pointed to by index with an dangling internal reference.
One solution is to make cloud a member of KdTree.

Related

How to create a large number of combinations lazily in C++

I want to create a combination of K elements one each from K sets. Each set can have n elements in it.
set1 = {a1, a2, a3}
set2 = {b1, b2, b3 , b4}
set3 = {c1, c2}
Required Combinations = {{a1,b1,c1}, {a1,b2,c1} ... {a3,b4,c2}}
Number of combinations = 3*4*2 =24
So if K is large and n is large we run into Out of Memory very quickly. Refer to the below code snippet how we are creating combinations today. If we create all the combinations in a case where K is relatively large, we go out of memory! So for instance, if K=20 and each set has 5 elements, the combinations are 5^20, which is extremely large in memory. So I want an alternative algorithm where I don't need to store all those combinations in memory all at a time before I start consuming the combinations.
vector<vector<string>> setsToCombine;
vector<vector<string>> allCombinations;
vector<vector<string>> *current =
new vector<vector<string>>{vector<string>()};
vector<vector<string>> *next = new vector<vector<string>>();
vector<vector<string>> *temp;
for (const auto& oneSet : setsToCombine) {
for (auto& cur : *current) {
for (auto& oneEle : oneSet) {
cur.push_back(oneEle);
next->push_back(cur);
cur.pop_back();
}
}
temp = current;
current = next;
next = temp;
next->clear();
}
for (const auto& cur : *current) {
allCombinations.push_back(cur);
}
current->clear();
next->clear();
delete current;
delete next;
You can store the indexes and lazely iterate over the combinations
#include <cstdint>
#include <iostream>
#include <vector>
using v_size_type = std::vector<int>::size_type;
using vv_size_type = std::vector<v_size_type>::size_type;
bool increment(std::vector<v_size_type> &counters, std::vector<v_size_type> &ranges) {
for (auto idx = counters.size(); idx > 0; --idx) {
++counters[idx - 1];
if (counters[idx - 1] == ranges[idx - 1]) counters[idx - 1] = 0;
else return true;
}
return false;
}
std::vector<int> get(const std::vector<std::vector<int>> &sets, const std::vector<v_size_type> &counters) {
std::vector<int> result(sets.size());
for (vv_size_type idx = 0; idx < counters.size(); ++idx) {
result[idx] = sets[idx][counters[idx]];
}
return result;
}
void print(const std::vector<int> &result) {
for (const auto el : result) {
std::cout << el << ' ';
}
}
int main() {
const std::vector<std::vector<int>> sets = {{-5, 2}, {-100, -21, 0, 15, 32}, {1, 2, 3}};
std::vector<v_size_type> ranges(sets.size());
for (vv_size_type idx = 0; idx < sets.size(); ++idx) {
ranges[idx] = sets[idx].size();
}
std::vector<v_size_type> counters(sets.size());
while (true) {
print(get(sets, counters));
std::cout << '\n';
if (!increment(counters, ranges)) break;
}
}
Godbolt
You can also use the odometer approach.
First, let us look again, what an odometer is. It looks like this:
There are several disks, with values printed on it. And if the odometer runs forward, it will show the Cartesian product of all values on the disks.
That is somehow clear, but how to use this principle? The solution is, that each set of values will be a disk, and the values of the set, will be put on the corresponding disk. With that, we will have an odometer, where the number of values on each disk is different. But this does not matter.
Also here, if a disks overflows, the next disk is incremented. Same principle like a standard odometer. Just with maybe more or less values.
And, you can put everything on a disk, not just integers. This approach will work always.
We can abstract a disk as a std::vector of your desired type. And the odometer is a std::vector of disks.
All this we can design in a class. And if we add iterator functionality to the class, we can easily handle it.
In the example below, I show only a minimum set of functions. You can add as many useful functions to this class as you like and tailor it to your needs.
The object oriented approach is often better to understand in the end.
Please check:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <initializer_list>
#include <algorithm>
#include <iterator>
using MyType = int;
using Disk = std::vector<MyType>;
using Disks = std::vector<Disk>;
// Abstraction for a very simple odometer
class Odometer {
Disks disks{};
public:
// We will do nearly everything with the iterator of the odometer class
struct iterator {
// Definitions for iterator ----------------
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
using value_type = std::vector<MyType>;
using pointer = std::vector<MyType>*;
using reference = std::vector<MyType>&;
const Disks& d; // Reference to disks from super class
int overflow{}; // Indicates an overflow of all disks
std::vector<std::size_t>positions{}; // Stores position of any disks
// Iterator constructor
iterator(const Disks& dd, const int over = 0) : d(dd), overflow(over) {
positions = std::vector<std::size_t>(dd.size(), 0);
}
// Dereference iterator
value_type operator*() const {
std::vector<MyType> result(d.size());
for (std::size_t i{}; i < d.size(); ++i) result[i] = d[i][positions[i]];
return result;
};
// Comparison
bool operator != (const iterator& other) { return positions != other.positions or overflow != other.overflow; }
// And increment the iterator
iterator operator++() {
int carry = 0; std::size_t i{};
for (i=0; i < d.size(); ++i) {
if (positions[i] >= d[i].size() - 1) {
positions[i] = 0;
carry = 1;
}
else {
++positions[i];
carry = 0;
break;
}
}
overflow = (i == d.size() and carry) ? 1 : 0;
return *this;
}
};
// Begin and End functions. End is true, if there is a flip over of all disks
iterator begin() const { return iterator(disks); }
iterator end() const { return iterator(disks, 1); }
// Constructors
Odometer() {}; // Default (useless for this example)
// Construct from 2d initializer list
Odometer(const std::initializer_list<const std::initializer_list<MyType>> iil) {
for (const std::initializer_list<MyType>& il : iil) {
disks.push_back(il);
}
}
// Variadic. Parameter pack and fold expression
template <typename ... Args>
Odometer(Args&&... args) {
(disks.push_back(std::forward<Args>(args)), ...);
}
// Simple output of everything
friend std::ostream& operator << (std::ostream& os, const Odometer& o) {
for (const auto vi : o) {
for (const MyType i : vi) os << i << ' ';
os << '\n';
}
return os;
}
};
// Some test
int main() {
// Define Odometer. Initialiaze wit normal initializer list
Odometer odo1{ {1,2},{3},{4,5,6} };
// Show complete output
std::cout << odo1 << "\n\n\n";
// Create additional 3 vectors for building a new cartesian product
std::vector<MyType> v1{ 1,2 };
std::vector<MyType> v2{ 3,4 };
std::vector<MyType> v3{ 5,6 };
// Define next Odometer and initialize with variadic constructor
Odometer odo2(v1, v2, v3);
// Use range based for loop for output
for (const std::vector<MyType>& vm : odo2) {
for (const MyType i : vm) std::cout << i << ' ';
std::cout << '\n';
}
}

How to change values of array at initialization in C++?

I want an array that have new attributed values if the value is x.
I can do that in PHP with that code:
$test = array(1=>55, 2=>66);
on above code if test[0] = 1, the new value of test[0] is going to be 55.
I want to do that in C++.
Normal C++ arrays do not have keys. There are always 0-indexed.
But we have std::map which is what PHP also use internally for key-based containers.
https://en.cppreference.com/w/cpp/container/map
You can make your own attributed values class in C++, so it has that behavior.
You can make it so the behavior is hard coded into the class. Or if you want to get fancier you can make the class having a value mapping passed in.
Here's an example with the value mapping passed into the class.
#include <cstddef>
#include <iostream>
#include <map>
#include <stdexcept>
#include <vector>
using sad_panda = std::logic_error;
using std::cout;
using std::map;
using std::size_t;
using std::vector;
namespace {
class AttributedValues {
vector<int> v;
map<int, int> attr_to_value;
public:
AttributedValues(map<int, int> mapping);
void set(size_t index, int value);
int operator[](size_t index) const;
};
AttributedValues::AttributedValues(map<int, int> mapping)
: attr_to_value{mapping}
{ }
void AttributedValues::set(size_t index, int value) {
if (index >= v.size()) {
v.resize(index+1);
}
auto iter = attr_to_value.find(value);
if (iter != attr_to_value.end()) {
value = iter->second;
}
v[index] = value;
}
int AttributedValues::operator[](size_t index) const {
if (index >= v.size()) {
throw sad_panda("AttributedValues::operator[] index out of range");
}
return v[index];
}
} // anon
int main() {
auto test = AttributedValues{{{1, 55}, {2, 66}}};
test.set(0, 1);
test.set(10, 2);
cout << test[0] << "\n";
cout << test[10] << "\n";
}

How to take the mean of a vector no matter what is inside?

I'm working on a homework problem that requires me to find the basic statistics on data-classes. I'm currently working on finding the mean but not sure how to set it up because of the way the given files are structured.
Here is what I was given:
/* Copyright 2018 test_stat_tracker.cc */
#include <cstddef>
// using size_t
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
#include "../hw7/stat_tracker.h"
using csce240::StatTracker;
const int kInt_elems[] = {1, 2, 1, 5, 7, 2, 9};
const size_t kInt_elem_count = 7;
const int kInt_elem_mean = 3; // actually 27/7
const int kInt_elem_median = 2;
const int kInt_elem_mode[] = {1, 2};
/* Calculates the actual mean, prints the expected and actual values, and
* returns whether they are the same.
*/
template <class T>
bool TestMean(const StatTracker<T>& tracker, const T& expected) {
T actual = tracker.Mean();
cout << "Expected mean: " << expected
<< ", Actual mean: " << actual;
return actual == expected;
}
void TestIntStats() {
vector<int> elems;
elems.assign(kInt_elems, kInt_elems + kInt_elem_count);
StatTracker<int> tracker;
for (auto it = elems.begin(); it != elems.end(); ++it)
tracker.Add(*it);
if (!TestMean(tracker, kInt_elem_mean))
cout << ": FAILED\n";
else
cout << ": PASSED\n";
}
int main(int argc, char* argv[]) {
TestIntStats();
return 0;
}
Now this is what I have managed in my .h and .cc files:
/* Copyright 2018
*
* stat_tracker.h
*/
#ifndef _HW7_STAT_TRACKER_H_ // NOLINT
#define _HW7_STAT_TRACKER_H_ // NOLINT
#include <ostream>
using std::cout;
using std::endl;
#include <vector>
#include <numeric>
using std::accumulate;
namespace csce240 {
template <class T>
class StatTracker {
public:
const T Mean() const; // T = T + T and T = T / int must be defined
// T a, b; a += b; DON'T DO THIS
};
} // namespace csce240
#include "../hw7/stat_tracker.cc" // comment out
#endif /* _HW7_STAT_TRACKER_H_ */ // NOLINT
And my .cc file
/* Copyright 2018
*
* stat_tracker.cc
*/
// #include "stat_tracker.h" // NOLINT
namespace csce240 {
template<class T>
const T StatTracker<T>::Mean() const {
auto v(elems);
vector<T> v = accumulate(v.begin(), v.end(), 0)/v.size();
return T();
}
} // namespace csce240
#include "stat_tracker.h"
At the moment I am working on getting the mean to work, but I keep receiving an error that elems was not declared. I can't initialize kInt_elems in my .cc because my professor will be using his own test class with different numbers.
I am very lost and need a little direction on how to set up this function.
Here is some code that calculates the mean of a vector.
Restrictions:
Data type must support addition.
Data type must support division.
Data type must support assignment of zero.
The Code:
template <typename Data>
Data Mean(const std::vector<Data>& v)
{
Data sum = 0;
const size_t length = v.length();
for (size_t i = 0; i < length; ++i)
{
sum += v[i];
}
return sum / length;
}
This uses the primitive for loop to sum up the elements in the vector.
The result depends on how division is defined for the data type. For example, floating point will return a different result than an integral type.

Why is trying to store a pointer to function ambiguous

Here is my code:
#include <functional>
#include <iostream>
#include<vector>
using namespace std;
// vector iterator
template <class T> class vit
{
private:
//vector<T>::iterator it;
vector<T> m_v;
function<bool (T, T)> m_fptr;
int len, pos;
public:
vit(vector<T> &v) { this->m_v = v; len = v.size(); pos = 0;};
// it= v.begin(); };
bool next(T &i) {
//if(it == m_v.end()) return false;
if(pos==len) return false;
//i = *it;
i = m_v[pos];
//if(idle) { idle = false ; return true; }
//it++;
pos++;
return true;};
//bool idle = true;
void set_same(function<bool (T,T)> fptr) { m_fptr = fptr ;};
//void set_same(function<bool(int, int)> fun) { return ; }
bool grp_begin() {
return pos == 0 || ! m_fptr(m_v[pos], m_v[pos-1]); };
bool grp_end() {
return pos == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
};
bool is_same(int a, int b) { return a == b; }
main()
{
vector<int> v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
int total;
for(auto it = v.begin(); it != v.end(); it++) {
if(it == v.begin() || *it != *(it-1)) {
total = 0;
}
total += *it;
if(it+1 == v.end() || *it != *(it+1)) {
cout << total << endl;
}
}
cout << "let's gry a group" <<endl;
vit<int> g(v);
int i;
while(g.next(i)) { cout << i << endl; }
cout << "now let's get really fancy" << endl;
vit<int> a_vit(v);
//auto is_same = [](int a, int b) { return a == b; };
a_vit.set_same(is_same);
//int total;
while(a_vit.next(i)) {
if(a_vit.grp_begin()) total = 0;
total += i;
if(a_vit.grp_end()) cout << total << endl ;
}
}
When I compile it with g++ -std=c++11 iter.cc -o iter, I get the result:
iter.cc: In function 'int main()':
iter.cc:63:17: error: reference to 'is_same' is ambiguous
a_vit.set_same(is_same);
^
iter.cc:37:6: note: candidates are: bool is_same(int, int)
bool is_same(int a, int b) { return a == b; }
^
In file included from /usr/include/c++/5.3.0/bits/move.h:57:0,
from /usr/include/c++/5.3.0/bits/stl_pair.h:59,
from /usr/include/c++/5.3.0/utility:70,
from /usr/include/c++/5.3.0/tuple:38,
from /usr/include/c++/5.3.0/functional:55,
from iter.cc:1:
/usr/include/c++/5.3.0/type_traits:958:12: note: template<class, class> struct std::is_same
struct is_same;
^
By way of explanation, I have created a class called 'vit'. It does two things: iterate over a vector, and determine if a new group has been reached.
The class function 'set_same' is supposed to store a function provided by the calling class to determine if two adjacent elements of a vector are in the same group. However, I can't seem to store the function in the class for future use by grp_begin() and grp_end() on account of the ostensible ambiguity of is_same.
What gives?
There is an is_same function defined by you and there is a struct is_same defined by the C++ Standard Library. Since you are using namespace std, your compiler doesn't know which is_same you meant to use.
It's what the error says: it's not clear whether you mean your is_same (in the global namespace) or the class template is_same (in namespace std).
You may disambiguate as follows:
::is_same
… with the leading :: meaning "in the global namespace".
Though you should consider putting your code in a namespace of its own.
Thanks guys. This is my first time touching C++ after more than a decade. I have cleaned up the code, and used a lambda to bring the "is_same" function closer to where it is called.
Did you spot the bug in my code? 'pos' was off-by-one when calling grp_begin() and grp_end(). Here is the revised code:
#include <functional>
#include <iostream>
#include <vector>
// vector iterator
template <class T> class vit
{
private:
std::vector<T> m_v;
std::function<bool (T, T)> m_fptr;
int len, pos;
public:
vit(std::vector<T> &v) { m_v = v; len = v.size(); pos = -1;};
bool next(T &val) {
pos++;
if(pos==len) return false;
val = m_v[pos];
return true;};
void set_same(std::function<bool (T,T)> fptr) { m_fptr = fptr ;};
bool grp_begin() {
return pos == 0 || ! m_fptr(m_v[pos], m_v[pos-1]); };
bool grp_end() {
return pos+1 == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
};
main()
{
std::vector<int> v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
vit<int> a_vit(v);
std::function<bool (int, int)> is_same = [](int a, int b) { return a == b; };
a_vit.set_same(is_same);
int i, total;
while(a_vit.next(i)) {
if(a_vit.grp_begin()) total = 0;
total += i;
if(a_vit.grp_end()) std::cout << total << std::endl ;
}
}
My class definition isn't bullet-proof and could be better: if the user forgets to 'set-same', for example, they'll be referring a random memory address as a function.
Nevertheless, I'm pretty chuffed with my solution so far. The class caller is relieved of all the bookkeeping relating iterating over the vector, and working out if a group boundary has been crossed.
The calling code looks very compact and intuitive to me.I can see C++ being my go to language.

Eigen C++ wrapping assignment

In Matlab, it is possible to do the following:
% init
a = 1:10;
b = 18:23;
% wrapping assignment
a([8:end 1:3]) = b;
Is something like this possible with Eigen? I'm hoping to make a member function for a circular buffer class that returns some reference to an Eigen type, perhaps something like:
VectorXd b(5);
b << 1,2,3,4,5 ;
CircularBuf a( 6 /*capacity*/ );
a.push(1);a.push(2);a.push(3);
// 3 elements in buf
a.pop();a.pop();
// 1 element in buf
// next line probably wraps around internal buffer, depending on impl
a.pushRef( b.size() /*number of elements in ref*/ ) = b;
I am not sure if this is what you are looking for...Following an answer I got from Jerry Coffin, I came up with this:
#include <iostream>
#include <vector>
#include <iterator>
template <class T>
class CircularVector {
typedef std::vector<T> DVector;
public:
CircularVector(const DVector& v) : v(v){}
T at(int i){return v.at(i);}
int size(){return v.size();}
class iterator :
public std::iterator < std::random_access_iterator_tag, T > {
CircularVector *vec;
int index;
public:
iterator(CircularVector &d, int index) : vec(&d), index(index) {}
iterator &operator++() { nextIndex(); return *this; }
iterator operator++(int) {
iterator tmp(*vec, index); nextIndex(); return tmp;
}
iterator operator+(int off) {
return iterator(*vec, (index + off)%vec->size());
}
iterator operator-(int off) {
return iterator(*vec, (index - off + vec->size())%vec->size());
}
T& operator*() { return (*vec).v[index]; }
bool operator!=(iterator const &other) { return index != other.index; }
//bool operator<(iterator const &other) { return index < other.index; }
private:
void nextIndex(){
++index;
if (index==vec->size()){index=0;}
}
};
iterator begin() { return iterator(*this, 0); }
//iterator end() { return iterator(*this, size()); }
private:
DVector v;
};
Your first example then can be written as:
int main() {
std::vector<int> a;
std::vector<int> b;
for(int i=1;i<11;i++){a.push_back(i);}
for(int i=18;i<24;i++){b.push_back(i);}
CircularVector<int> ca(a);
std::copy(b.begin(),b.end(),ca.begin()+7); // copy elements starting
// at index 8
for (int i=0;i<ca.size();i++){std::cout << ca.at(i) << std::endl;}
}
Actually, I was just curious to try it and I believe there are nicer ways to implement it. It is not the most efficient way to check if the index has to be wrapped each time it is increased. Obviously < and end() are not quite meaningful for a circular buffer and I decided not to implement them (e.g. for(it=begin();it<end();it++) would be an infinite loop. However, those are not needed to use it as input/output iterator.
I have another solution as described in my answer to this question. The code posted in the answer defines a custom expression for the circular shift, so you can benefit from Eigen's optimisations.
Given the circ_shift.h from the mentioned answer, you can do the following to achieve your goal: I hope this helps...
// main.cpp
#include "stdafx.h"
#include "Eigen/Core"
#include <iostream>
#include "circ_shift.h" // posted in the answer to the other quesiton.
using namespace Eigen;
int main()
{
VectorXi a(10), b(6);
a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
b << 18, 19, 20, 21, 22, 23;
std::cout << "a = " << a.transpose() << std::endl << "b = " << b.transpose() << std::endl;
circShift(a, 3, 0).block(0, 0, b.size(), 1) = b;
std::cout << "now: a = " << a.transpose() << std::endl; // prints 21, 22, 23, 4, 5, 6, 7, 18, 19, 20
return 0;
}