Skip to content

Commit

Permalink
✨ Add function to generate a random coordinate. (#233)
Browse files Browse the repository at this point in the history
* ✨ function to generate a random cell between two given cells.

* 🎨 remove type information in std::uniform_int_distribution.

* 🎨 reformat code.

* 🎨 implement suggestions.

* 🎨 remove ``const`` and pass parameters by copy.

* 🎨 implement suggestions.

* 🎨 implement suggestions.

* 🎨 add siqad exception.

* 🎨 use more elegant way.

* 🎨 change order of if branches.
  • Loading branch information
Drewniok committed Jun 13, 2023
1 parent 1d3de0b commit 12fdfc3
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docs/utils/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Layout Utils
.. doxygenfunction:: fiction::normalize_layout_coordinates
.. doxygenfunction:: fiction::convert_to_siqad_coordinates
.. doxygenfunction:: fiction::convert_to_fiction_coordinates

.. doxygenfunction:: fiction::random_coordinate


Placement Utils
Expand Down
47 changes: 47 additions & 0 deletions include/fiction/utils/layout_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
#include "fiction/traits.hpp"
#include "fiction/types.hpp"

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <limits>
#include <random>
#include <type_traits>
#include <utility>

namespace fiction
{
Expand Down Expand Up @@ -350,6 +354,49 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept

return lyt_new;
}
/**
* Generates a random coordinate within the region spanned by two given coordinates. The two given coordinates form the
* top left corner and the bottom right corner of the spanned region.
*
* @OffsetCoordinateType The coordinate implementation to be used.
* @param coordinate1 Top left Coordinate.
* @param coordinate2 Bottom right Coordinate (coordinate order is not important, automatically swapped if
* necessary).
* @return Randomly generated coordinate.
*/
template <typename CoordinateType>
CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coordinate2) noexcept
{
static_assert(std::is_same_v<CoordinateType, offset::ucoord_t> || std::is_same_v<CoordinateType, cube::coord_t> ||
std::is_same_v<CoordinateType, siqad::coord_t>,
"CoordinateType is unknown");

static std::mt19937_64 generator(std::random_device{}());

if (coordinate1 > coordinate2)
{
std::swap(coordinate1, coordinate2);
}

if constexpr (std::is_same_v<CoordinateType, siqad::coord_t>)
{
std::uniform_int_distribution<> dist_x(coordinate1.x, coordinate2.x);
std::uniform_int_distribution<> dist_y(coordinate1.y, coordinate2.y);
std::uniform_int_distribution<> dist_z(0, 1);

return std::clamp(siqad::coord_t{dist_x(generator), dist_y(generator), dist_z(generator)}, coordinate1,
coordinate2);
}

else
{
std::uniform_int_distribution<> dist_x(coordinate1.x, coordinate2.x);
std::uniform_int_distribution<> dist_y(coordinate1.y, coordinate2.y);
std::uniform_int_distribution<> dist_z(coordinate1.z, coordinate2.z);

return {dist_x(generator), dist_y(generator), dist_z(generator)};
}
}

} // namespace fiction

Expand Down
106 changes: 106 additions & 0 deletions test/utils/layout_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,109 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to cube::coord_t coordinate layout", "[
CHECK(lyt_transformed.get_cell_name({5, 6}) == "output cell");
}
}

TEST_CASE("Generate random offset::ucoord_t coordinate", "[layout-utils]")
{
SECTION("two identical cells as input")
{
const auto randomly_generated_coordinate = random_coordinate<offset::ucoord_t>({0, 0, 0}, {0, 0, 0});
CHECK(randomly_generated_coordinate.x == 0);
CHECK(randomly_generated_coordinate.y == 0);
CHECK(randomly_generated_coordinate.z == 0);

const auto randomly_generated_coordinate_second = random_coordinate<offset::ucoord_t>({1, 0, 0}, {1, 0, 0});
CHECK(randomly_generated_coordinate_second.x == 1);
CHECK(randomly_generated_coordinate_second.y == 0);
CHECK(randomly_generated_coordinate_second.z == 0);
}

SECTION("two unidentical cells as input, correct order")
{
const auto randomly_generated_coordinate_second = random_coordinate<offset::ucoord_t>({1, 1, 1}, {5, 2, 3});
CHECK(randomly_generated_coordinate_second.x >= 1);
CHECK(randomly_generated_coordinate_second.x <= 5);
CHECK(randomly_generated_coordinate_second.y <= 2);
CHECK(randomly_generated_coordinate_second.y >= 0);
CHECK(randomly_generated_coordinate_second.z <= 3);
CHECK(randomly_generated_coordinate_second.z >= 1);
}

SECTION("two unidentical cells as input, switched correct order")
{
const auto randomly_generated_coordinate = random_coordinate<offset::ucoord_t>({5, 2, 3}, {1, 1, 1});
CHECK(randomly_generated_coordinate.x >= 1);
CHECK(randomly_generated_coordinate.x <= 5);
CHECK(randomly_generated_coordinate.y <= 2);
CHECK(randomly_generated_coordinate.y >= 0);
CHECK(randomly_generated_coordinate.z <= 3);
CHECK(randomly_generated_coordinate.z >= 1);
}
}

TEST_CASE("Generate random cube::coord_t coordinate", "[layout-utils]")
{
SECTION("two identical cells as input")
{
const auto randomly_generated_coordinate = random_coordinate<cube::coord_t>({-10, -5, 0}, {-10, -5, 0});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -5);
CHECK(randomly_generated_coordinate.z == 0);

const auto randomly_generated_coordinate_second = random_coordinate<cube::coord_t>({1, 0, 0}, {1, 0, 0});
CHECK(randomly_generated_coordinate_second.x == 1);
CHECK(randomly_generated_coordinate_second.y == 0);
CHECK(randomly_generated_coordinate_second.z == 0);
}

SECTION("two unidentical cells as input, correct order")
{
const auto randomly_generated_coordinate = random_coordinate<cube::coord_t>({-10, -1, 3}, {-10, -1, 6});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -1);
CHECK(randomly_generated_coordinate.z >= 3);
CHECK(randomly_generated_coordinate.z <= 6);
}

SECTION("two unidentical cells as input, switched correct order")
{
const auto randomly_generated_coordinate = random_coordinate<cube::coord_t>({-10, -1, 6}, {-10, -1, 3});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -1);
CHECK(randomly_generated_coordinate.z >= 3);
CHECK(randomly_generated_coordinate.z <= 6);
}
}

TEST_CASE("Generate random siqad::coord_t coordinate", "[layout-utils]")
{
SECTION("two identical cells as input")
{
const auto randomly_generated_coordinate = random_coordinate<siqad::coord_t>({-10, -5, 0}, {-10, -5, 0});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -5);
CHECK(randomly_generated_coordinate.z == 0);

const auto randomly_generated_coordinate_second = random_coordinate<siqad::coord_t>({1, 0, 0}, {1, 0, 0});
CHECK(randomly_generated_coordinate_second.x == 1);
CHECK(randomly_generated_coordinate_second.y == 0);
CHECK(randomly_generated_coordinate_second.z == 0);
}

SECTION("two unidentical cells as input, correct order")
{
const auto randomly_generated_coordinate = random_coordinate<siqad::coord_t>({-10, -1, 0}, {-10, -1, 1});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -1);
CHECK(randomly_generated_coordinate.z >= 0);
CHECK(randomly_generated_coordinate.z <= 1);
}

SECTION("two unidentical cells as input, switched correct order")
{
const auto randomly_generated_coordinate = random_coordinate<siqad::coord_t>({-10, -1, 1}, {-10, -1, 0});
CHECK(randomly_generated_coordinate.x == -10);
CHECK(randomly_generated_coordinate.y == -1);
CHECK(randomly_generated_coordinate.z >= 0);
CHECK(randomly_generated_coordinate.z <= 1);
}
}

0 comments on commit 12fdfc3

Please sign in to comment.