Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 The critical temperature value will only be overwritten by the new value if the new value is lower. #343

Merged
merged 3 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions include/fiction/algorithms/simulation/sidb/critical_temperature.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,14 @@ class critical_temperature_impl
*
* @tparam TT The type of the truth table specifying the gate behavior.
* @param spec Expected Boolean function of the layout given as a multi-output truth table.
* @return `true` if the simulation succeeds and *Gate-based Critical Temperature* is determined, `false` otherwise.
*/
template <typename TT>
[[nodiscard]] bool gate_based_simulation(const std::vector<TT>& spec) noexcept
void gate_based_simulation(const std::vector<TT>& spec) noexcept
{
if (layout.is_empty())
{
stats.critical_temperature = 0.0;
return true;
return;
}
else if (layout.num_cells() > 1)
{
Expand All @@ -200,15 +199,15 @@ class critical_temperature_impl
if (can_positive_charges_occur(*bii, params.simulation_params.phys_params))
{
stats.critical_temperature = 0.0;
return true;
return;
}

// performs physical simulation of a given SiDB layout at a given input combination
const auto sim_result = physical_simulation_of_layout(bii);
if (sim_result.charge_distributions.empty())
{
stats.critical_temperature = 0.0;
return true;
return;
}
stats.num_valid_lyt = sim_result.charge_distributions.size();
// The energy distribution of the physically valid charge configurations for the given layout is
Expand Down Expand Up @@ -237,16 +236,12 @@ class critical_temperature_impl
}
}
}

return true;
}

/**
* *Gate-based Critical Temperature* Simulation of a SiDB layout for a given Boolean function.
*
* @return `true` if the simulation succeeds and the *Critical Temperature* is determined, `false` otherwise.
*/
bool non_gate_based_simulation() noexcept
void non_gate_based_simulation() noexcept
{
sidb_simulation_result<Lyt> simulation_results{};
if (params.engine == critical_temperature_params::simulation_engine::EXACT)
Expand Down Expand Up @@ -299,22 +294,29 @@ class critical_temperature_impl
{
// If the occupation probability of excited states exceeds the given threshold.
if (occupation_probability_non_gate_based(distribution, temp) > (1 - params.confidence_level) &&
temp < stats.critical_temperature)
(temp < stats.critical_temperature))
{
// The current temperature is stored as the critical temperature.
stats.critical_temperature = temp;

break;
}

if (std::abs(temp - params.max_temperature) < 0.001)
if (std::abs(temp - params.max_temperature) < 0.001 && (temp < stats.critical_temperature))
{
// Maximal temperature is stored as the Critical Temperature.
stats.critical_temperature = params.max_temperature;
}
}

return true;
}
/**
* Returns the critical temperature.
*
* @return The critical temperature (unit: K).
*/
[[nodiscard]] double get_critical_temperature() const noexcept
{
return stats.critical_temperature;
}

private:
Expand Down Expand Up @@ -373,13 +375,14 @@ class critical_temperature_impl
for (const auto& temp : temp_values)
{
// If the occupation probability of erroneous states exceeds the given threshold...
if (occupation_probability_gate_based(energy_state_type, temp) > (1 - params.confidence_level))
if (occupation_probability_gate_based(energy_state_type, temp) > (1 - params.confidence_level) &&
(temp < stats.critical_temperature))
{
// The current temperature is stored as Critical Temperature.
stats.critical_temperature = temp;
break;
}
if (std::abs(temp - params.max_temperature) < 0.001)
if (std::abs(temp - params.max_temperature) < 0.001 && (temp < stats.critical_temperature))
{
// Maximal temperature is stored as Critical Temperature.
stats.critical_temperature = params.max_temperature;
Expand Down Expand Up @@ -452,15 +455,15 @@ class critical_temperature_impl
* @param spec Expected Boolean function of the layout given as a multi-output truth table.
* @param params Simulation and physical parameters.
* @param pst Statistics.
* @return The critical temperature (unit: K).
*/
template <typename Lyt, typename TT>
bool critical_temperature_gate_based(const Lyt& lyt, const std::vector<TT>& spec,
const critical_temperature_params& params = {},
critical_temperature_stats<Lyt>* pst = nullptr)
double critical_temperature_gate_based(const Lyt& lyt, const std::vector<TT>& spec,
const critical_temperature_params& params = {},
critical_temperature_stats<Lyt>* pst = nullptr)
{
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");
static_assert(has_sidb_technology_v<Lyt>, "Lyt is not an SiDB layout");
static_assert(has_siqad_coord_v<Lyt>, "Lyt is not based on SiQAD coordinates");

assert(!spec.empty());
// all elements in tts must have the same number of variables
Expand All @@ -471,14 +474,14 @@ bool critical_temperature_gate_based(const Lyt& lyt, const std::vector<TT>& spec

detail::critical_temperature_impl<Lyt> p{lyt, params, st};

const auto result = p.gate_based_simulation(spec);
p.gate_based_simulation(spec);

if (pst)
{
*pst = st;
}

return result;
return p.get_critical_temperature();
}

/**
Expand All @@ -490,10 +493,11 @@ bool critical_temperature_gate_based(const Lyt& lyt, const std::vector<TT>& spec
* @param lyt The layout to simulate.
* @param params Simulation and physical parameters.
* @param pst Statistics.
* @return The critical temperature (unit: K)
*/
template <typename Lyt>
bool critical_temperature_non_gate_based(const Lyt& lyt, const critical_temperature_params& params = {},
critical_temperature_stats<Lyt>* pst = nullptr)
double critical_temperature_non_gate_based(const Lyt& lyt, const critical_temperature_params& params = {},
critical_temperature_stats<Lyt>* pst = nullptr)
{
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");
static_assert(has_sidb_technology_v<Lyt>, "Lyt is not an SiDB layout");
Expand All @@ -503,14 +507,14 @@ bool critical_temperature_non_gate_based(const Lyt& lyt, const critical_temperat

detail::critical_temperature_impl<Lyt> p{lyt, params, st};

const auto result = p.non_gate_based_simulation();
p.non_gate_based_simulation();

if (pst)
{
*pst = st;
}

return result;
return p.get_critical_temperature();
}

} // namespace fiction
Expand Down
34 changes: 34 additions & 0 deletions test/algorithms/simulation/sidb/critical_temperature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,40 @@ TEMPLATE_TEST_CASE(
CHECK_THAT(std::abs(criticalstats.critical_temperature - 0.85), Catch::Matchers::WithinAbs(0.00, 0.01));
}

SECTION("OR gate")
{
TestType lyt{};

lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT);
lyt.assign_cell_type({26, 0, 0}, sidb_technology::cell_type::INPUT);

lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT);
lyt.assign_cell_type({24, 1, 0}, sidb_technology::cell_type::INPUT);

lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL);
lyt.assign_cell_type({20, 2, 0}, sidb_technology::cell_type::NORMAL);

lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL);
lyt.assign_cell_type({18, 3, 0}, sidb_technology::cell_type::NORMAL);

// three canvas SiDBs
lyt.assign_cell_type({12, 6, 0}, sidb_technology::cell_type::NORMAL);
lyt.assign_cell_type({12, 7, 1}, sidb_technology::cell_type::NORMAL);
lyt.assign_cell_type({15, 11, 0}, sidb_technology::cell_type::NORMAL);

lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::OUTPUT);
lyt.assign_cell_type({20, 14, 0}, sidb_technology::cell_type::OUTPUT);

lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL);

critical_temperature_stats<TestType> criticalstats{};
const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.25}},
critical_temperature_params::simulation_engine::EXACT, 0.99, 350};
critical_temperature_gate_based(lyt, std::vector<tt>{create_or_tt()}, params, &criticalstats);

CHECK(criticalstats.critical_temperature < 350);
}

SECTION("Not working diagonal Wire")
{
TestType lyt{};
Expand Down
Loading