Skip to content

Commit

Permalink
Implement Ns brute force improved (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
aartiukh authored Jan 26, 2025
1 parent 1347b51 commit d0f566c
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 8 deletions.
2 changes: 2 additions & 0 deletions algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ file(GLOB ALGORITHMS_SRC_LIST_INCLUDE "src/neighbours/NeighboursSearch.h"
"src/neighbours/NeighboursSearch.hpp"
"src/neighbours/NSBruteForce.h"
"src/neighbours/NSBruteForce.hpp"
"src/neighbours/NSBruteForceImproved.h"
"src/neighbours/NSBruteForceImproved.hpp"
"src/Point.h"
"src/Point.hpp"
"src/Defines.h"
Expand Down
4 changes: 3 additions & 1 deletion algorithms/src/neighbours/NSBruteForce.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ template <class T> void NSBruteForce<T>::search(T& points)
continue;
}

if ((points[i].position - points[j].position).calcNormSqr() < pow(m_radius, 2) + DBL_EPSILON)
const auto distanceSqr = (points[i].position - points[j].position).calcNormSqr();

if (distanceSqr < pow(m_radius, 2) + DBL_EPSILON)
{
points[i].neighbours.push_back(j);
}
Expand Down
45 changes: 45 additions & 0 deletions algorithms/src/neighbours/NSBruteForceImproved.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @file NSBruteForceImproved.h
* @author Anton Artiukh
* @date Created Jan 25, 2025
**/

#ifndef NS_BRUTE_FORCE_IMPROVED_H_48DCCF3737274ADE9B6EEF8BF6947A6E
#define NS_BRUTE_FORCE_IMPROVED_H_48DCCF3737274ADE9B6EEF8BF6947A6E

#include "Area.h"
#include "Defines.h"
#include "NeighboursSearchInterface.h"
#include "Point.h"

namespace SPHSDK
{

namespace TestEnvironment
{
class NeighboursSearchTestSuite;
} // namespace TestEnvironment

template <class T> class NSBruteForceImproved : public NeighboursSearchI<T>
{
friend class TestEnvironment::NeighboursSearchTestSuite;

public:
explicit NSBruteForceImproved(const Volume& volume, FLOAT radius, FLOAT eps);

~NSBruteForceImproved();

void search(T& points);

private:
Volume m_volume;

FLOAT m_radius;

FLOAT m_eps;
};
} // namespace SPHSDK

#include "NSBruteForceImproved.hpp"

#endif // NS_BRUTE_FORCE_IMPROVED_H_48DCCF3737274ADE9B6EEF8BF6947A6E
41 changes: 41 additions & 0 deletions algorithms/src/neighbours/NSBruteForceImproved.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @file NSBruteForce.hpp
* @author Anton Artiukh
* @date Created Jan 25, 2025
**/

#include "NSBruteForceImproved.h"

#include <iostream>

namespace SPHSDK
{

template <class T>
NSBruteForceImproved<T>::NSBruteForceImproved(const Volume& volume, FLOAT radius, FLOAT eps)
: m_volume(volume),
m_radius(radius),
m_eps(eps)
{
}

template <class T> NSBruteForceImproved<T>::~NSBruteForceImproved() = default;

template <class T> void NSBruteForceImproved<T>::search(T& points)
{
for (size_t i = 0u; i < points.size(); ++i)
{
for (size_t j = i + 1u; j < points.size(); ++j)
{
const auto distanceSqr = (points[i].position - points[j].position).calcNormSqr();

if (distanceSqr < pow(m_radius, 2) + DBL_EPSILON)
{
points[i].neighbours.push_back(j);
points[j].neighbours.push_back(i);
}
}
}
}

} // namespace SPHSDK
45 changes: 45 additions & 0 deletions algorithms/src/neighbours/NeighbourSerachAlgo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Neighbour Search Algorithms

Generated by Copilot.

1. **Brute Force Search**:
- **Description**: This is the simplest method where the distance between each pair of points is calculated to find the nearest neighbors.
- **Complexity**: O(n^2)
- **Use Case**: Suitable for small datasets due to its simplicity and ease of implementation.

2. **Grid-Based Search**:
- **Description**: The space is divided into a grid of cells. Each particle is assigned to a cell, and only neighboring cells are searched for neighbors.
- **Complexity**: O(n) for uniform distributions
- **Use Case**: Effective for large datasets with uniform distributions.

3. **k-d Tree Search**:
- **Description**: A k-d tree is a binary tree that recursively partitions the space into two half-spaces. It allows efficient range searches and nearest neighbor searches.
- **Complexity**: O(log n) for balanced trees
- **Use Case**: Suitable for moderate to large datasets with non-uniform distributions.

4. **Octree Search**:
- **Description**: An octree is a tree data structure where each internal node has exactly eight children. It is used to partition a three-dimensional space by recursively subdividing it into eight octants.
- **Complexity**: O(log n) for balanced trees
- **Use Case**: Effective for 3D spatial searches, especially in simulations involving large datasets.

5. **Ball Tree Search**:
- **Description**: A ball tree is a binary tree where each node represents a ball (a region in space defined by a center and radius). It is used for efficient nearest neighbor searches.
- **Complexity**: O(log n) for balanced trees
- **Use Case**: Suitable for high-dimensional data.

6. **Cover Tree Search**:
- **Description**: A cover tree is a data structure for nearest neighbor search that maintains a hierarchy of nested coverings of the data points. It allows efficient nearest neighbor searches in high-dimensional spaces.
- **Complexity**: O(log n) for balanced trees
- **Use Case**: Effective for high-dimensional datasets.

7. **Voronoi Diagram Search**:
- **Description**: A Voronoi diagram partitions the space into regions based on the distance to a specific set of points. Each region contains all points closer to one particular point than to any other.
- **Complexity**: O(n log n) for construction, O(log n) for search
- **Use Case**: Suitable for static datasets where the search structure does not need to be updated frequently.

8. **Approximate Nearest Neighbor (ANN) Search**:
- **Description**: Algorithms like Locality-Sensitive Hashing (LSH) or randomized k-d trees provide approximate nearest neighbor searches with a trade-off between accuracy and speed.
- **Complexity**: O(log n) for search, with a trade-off in accuracy
- **Use Case**: Effective for very large datasets where exact searches are computationally expensive.

Each of these algorithms has its strengths and weaknesses, and the choice of algorithm depends on the specific requirements of the SPH simulation, such as the size of the dataset, the dimensionality of the space, and the desired balance between accuracy and computational efficiency.
28 changes: 23 additions & 5 deletions algorithms/test/src/NeighboursSearchTestSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "Area.h"
#include "NSBruteForce.h"
#include "NSBruteForceImproved.h"
#include "NeighboursSearch.h"

#include <stdexcept>
Expand All @@ -19,7 +20,7 @@ namespace SPHSDK
namespace TestEnvironment
{

void NeighboursSearchTestSuite::testSearch3D(
void NeighboursSearchTestSuite::testSearch(
const Cuboid& cuboid,
FLOAT radius,
FLOAT accuracy,
Expand Down Expand Up @@ -80,9 +81,26 @@ void NeighboursSearchTestSuite::testSearch3D(
EXPECT_EQ(expectedPointNeighbours[i], points[i].neighbours);
}
}

for (size_t i = 0u; i < points.size(); ++i)
{
points[i].neighbours.clear();
}

{
NSBruteForceImproved<TestPoints3D> ns(volume, radius, accuracy);

ns.search(points);

for (size_t i = 0u; i < points.size(); ++i)
{
std::sort(points[i].neighbours.begin(), points[i].neighbours.end());
EXPECT_EQ(expectedPointNeighbours[i], points[i].neighbours);
}
}
}

void NeighboursSearchTestSuite::testInsert3D(
void NeighboursSearchTestSuite::testInsert(
const Cuboid& cuboid,
FLOAT radius,
FLOAT accuracy,
Expand Down Expand Up @@ -132,7 +150,7 @@ void NeighboursSearchTestSuite::searchInOneBox3D()

VectorOfSizetVectors expectedNeighbours = {{1, 2}, {0, 2}, {0, 1}};

testSearch3D(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
testSearch(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
}

void NeighboursSearchTestSuite::searchInDifferentBoxesCenterBack3D()
Expand Down Expand Up @@ -183,7 +201,7 @@ void NeighboursSearchTestSuite::searchInDifferentBoxesCenterBack3D()

VectorOfSizetVectors expectedNeighbours = {{3, 1, 4, 2, 5}, {0, 4, 2}, {0, 3, 1}, {0, 4, 2}, {0, 3, 1}, {0}};

testSearch3D(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
testSearch(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
}

void NeighboursSearchTestSuite::searchInDifferentBoxesCenterMiddle3D()
Expand Down Expand Up @@ -280,7 +298,7 @@ void NeighboursSearchTestSuite::searchInDifferentBoxesCenterMiddle3D()
{3, 2, 0},
{4, 1, 0}};

testSearch3D(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
testSearch(cuboid, radius, accuracy, points, expectedBoxSizes, expectedBoxNeighbours, expectedNeighbours);
}

} // namespace TestEnvironment
Expand Down
4 changes: 2 additions & 2 deletions algorithms/test/src/NeighboursSearchTestSuite.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class NeighboursSearchTestSuite

using TestPoints3D = std::vector<TestPoint3F>;

static void testSearch3D(
static void testSearch(
const Cuboid& cuboid,
FLOAT radius,
FLOAT accuracy,
Expand All @@ -52,7 +52,7 @@ class NeighboursSearchTestSuite
const VectorOfSizetVectors& expectedBoxNeighbours,
VectorOfSizetVectors expectedPointNeighbours);

static void testInsert3D(
static void testInsert(
const Cuboid& cuboid,
FLOAT radius,
FLOAT accuracy,
Expand Down

0 comments on commit d0f566c

Please sign in to comment.