Femboy_GP/tests/src/tests.cpp

267 lines
8.8 KiB
C++
Raw Normal View History

2024-02-19 15:55:54 -05:00
/*
* <Short Description>
* Copyright (C) 2024 Brett Terpstra
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <lilfbtf/tests.h>
#include <lilfbtf/symbol_regression.h>
#include <blt/std/logging.h>
2024-02-20 15:18:19 -05:00
#include <blt/std/vector.h>
2024-02-19 15:55:54 -05:00
#include <iostream>
#include "blt/std/utility.h"
2024-02-29 11:25:39 -05:00
#include "blt/std/hashmap.h"
2024-02-20 15:18:19 -05:00
#include <blt/std/ranges.h>
2024-02-29 11:25:39 -05:00
#include <utility>
2024-02-20 15:18:19 -05:00
#include <variant>
#include <array>
2024-02-19 15:55:54 -05:00
2024-02-29 11:25:39 -05:00
template<typename T>
auto run_once()
{
static auto called = false;
return !std::exchange(called, true);
};
2024-02-19 15:55:54 -05:00
namespace fb
{
2024-02-20 15:18:19 -05:00
using arg_t = double;
2024-02-19 15:55:54 -05:00
/*
* Classes
*/
test_add_function_t add_base;
test_sub_function_t sub_base;
test_mul_function_t mul_base;
test_div_function_t div_base;
test_exp_function_t exp_base;
test_log_function_t log_base;
test_sin_function_t sin_base;
test_cos_function_t cos_base;
2024-02-20 15:18:19 -05:00
#define STATIC_FUNCTION_LIST \
STATIC_FUNCTION_APPLY(test_add_function_t, args[0], args[1]) \
STATIC_FUNCTION_APPLY(test_sub_function_t, args[0], args[1]) \
STATIC_FUNCTION_APPLY(test_mul_function_t, args[0], args[1]) \
STATIC_FUNCTION_APPLY(test_div_function_t, args[0], args[1]) \
STATIC_FUNCTION_APPLY(test_exp_function_t, args[0]) \
STATIC_FUNCTION_APPLY(test_log_function_t, args[0]) \
STATIC_FUNCTION_APPLY(test_sin_function_t, args[0]) \
STATIC_FUNCTION_APPLY(test_cos_function_t, args[0])
#define FUNCTION_LIST \
FUNCTION_APPLY(add_base, add_t, args[0], args[1]) \
FUNCTION_APPLY(sub_base, sub_t, args[0], args[1]) \
FUNCTION_APPLY(mul_base, mul_t, args[0], args[1]) \
FUNCTION_APPLY(div_base, div_t, args[0], args[1]) \
FUNCTION_APPLY(exp_base, exp_t, args[0]) \
FUNCTION_APPLY(log_base, log_t, args[0]) \
FUNCTION_APPLY(sin_base, sin_t, args[0]) \
FUNCTION_APPLY(cos_base, cos_t, args[0])
class function_virtual_t
{
private:
arg_count_t args_count_;
public:
explicit function_virtual_t(arg_count_t args_count): args_count_(args_count)
{}
virtual arg_t operator()(blt::span<arg_t> args) = 0;
[[nodiscard]] arg_count_t argCount() const noexcept
{
return args_count_;
}
virtual ~function_virtual_t() = default;
};
// create virtual function variants
#define FUNCTION_APPLY(type, name, ...) \
class function_virtual_##name : public function_virtual_t{ \
public: \
function_virtual_##name(): function_virtual_t(type.argCount())\
{} \
\
arg_t operator()(blt::span<arg_t> args) final \
{ \
return type(__VA_ARGS__);\
}\
};
FUNCTION_LIST
#undef FUNCTION_APPLY
#define FUNCTION_APPLY(type, name, ...) std::make_unique<function_virtual_##name>(),
std::array<std::unique_ptr<function_virtual_t>, static_cast<int>(symbolic_regress_function_t::SIZE)> virtual_functions = {
FUNCTION_LIST
};
#undef FUNCTION_APPLY
using function_variant = std::variant<test_add_function_t, test_sub_function_t, test_mul_function_t, test_div_function_t, test_exp_function_t, test_log_function_t, test_sin_function_t, test_cos_function_t>;
#define STATIC_FUNCTION_APPLY(type, ...) \
constexpr auto operator()(const type& func){ \
return func(__VA_ARGS__); \
}
struct function_variant_visitor_apply
{
private:
blt::span<arg_t> args;
public:
constexpr explicit function_variant_visitor_apply(blt::span<arg_t> args): args(args)
{}
STATIC_FUNCTION_LIST
};
#undef STATIC_FUNCTION_APPLY
#define STATIC_FUNCTION_APPLY(type, ...) \
constexpr auto operator()(const type& func){ \
return func.argCount(); \
}
struct function_variant_visitor_argc
{
STATIC_FUNCTION_LIST
};
2024-02-19 15:55:54 -05:00
2024-02-20 15:18:19 -05:00
class flat_tree
{
};
2024-02-21 23:54:11 -05:00
template<typename ENUM_TYPE>
class arg_constraint_container
{
private:
2024-02-29 11:25:39 -05:00
blt::vector<blt::vector<ENUM_TYPE>> map;
2024-02-21 23:54:11 -05:00
public:
2024-02-29 11:25:39 -05:00
constexpr explicit arg_constraint_container(const blt::vector<blt::vector<ENUM_TYPE>>& map): map(map)
2024-02-21 23:54:11 -05:00
{}
2024-02-29 11:25:39 -05:00
constexpr explicit arg_constraint_container(blt::size_t argc, const blt::vector<ENUM_TYPE>& map)
2024-02-21 23:54:11 -05:00
{
for (blt::size_t i = 0; i < argc; i++)
this->map.push_back(map);
}
constexpr arg_constraint_container(std::initializer_list<blt::vector<ENUM_TYPE>> maps)
{
for (const auto& v : maps)
this->map.push_back(v);
}
2024-02-29 11:25:39 -05:00
[[nodiscard]] constexpr const blt::vector<ENUM_TYPE>& getAllowedArguments(blt::size_t arg) const
{
return map[arg];
}
2024-02-21 23:54:11 -05:00
};
template<typename ARG_TYPE, typename ENUM_TYPE>
class operator_t
2024-02-20 15:18:19 -05:00
{
2024-02-21 16:32:44 -05:00
private:
2024-02-29 11:25:39 -05:00
ENUM_TYPE our_type;
2024-02-21 16:32:44 -05:00
arg_count_t argc;
std::function<ARG_TYPE(blt::span<ARG_TYPE>)> func;
2024-02-21 23:54:11 -05:00
arg_constraint_container<ENUM_TYPE> allowed_inputs;
2024-02-29 11:25:39 -05:00
constexpr operator_t(ENUM_TYPE type, arg_count_t argc, std::function<ARG_TYPE(blt::span<ARG_TYPE>)> func,
arg_constraint_container<ENUM_TYPE> allowed_inputs):
our_type(type), argc(argc), func(std::move(func)), allowed_inputs(std::move(allowed_inputs))
2024-02-21 16:32:44 -05:00
{}
2024-02-29 11:25:39 -05:00
public:
static constexpr operator_t make_operator(ENUM_TYPE type, arg_count_t argc,
std::function<ARG_TYPE(blt::span<ARG_TYPE>)> func,
arg_constraint_container<ENUM_TYPE> allowed_inputs)
{
return operator_t{type, argc, func, allowed_inputs};
}
2024-02-21 16:32:44 -05:00
[[nodiscard]] constexpr arg_count_t argCount() const
{ return argc; }
2024-02-29 11:25:39 -05:00
[[nodiscard]] constexpr std::function<ARG_TYPE(blt::span<ARG_TYPE>)>& function() const
2024-02-21 16:32:44 -05:00
{ return func; }
2024-02-29 11:25:39 -05:00
[[nodiscard]] constexpr const blt::vector<ENUM_TYPE>& getAllowedArguments(blt::size_t arg) const
{ return allowed_inputs.getAllowedArguments(arg); }
[[nodiscard]] constexpr ENUM_TYPE type() const
{ return our_type; }
};
template<typename ARG_TYPE, typename ENUM_TYPE>
struct operator_container_constructor_t;
template<typename ARG_TYPE, typename ENUM_TYPE, blt::i32 ENUM_MAX>
struct operator_container_t
{
friend operator_container_constructor_t<ARG_TYPE, ENUM_TYPE>;
private:
constexpr operator_container_t(std::initializer_list<std::pair<ENUM_TYPE, operator_t<ARG_TYPE, ENUM_TYPE>>> list)
{
for (const auto& v : list)
{
operators[static_cast<blt::i32>(v.first)] = v.second;
max_argc = std::max(v.second.argCount(), max_argc);
}
}
2024-02-21 23:54:11 -05:00
2024-02-29 11:25:39 -05:00
public:
arg_count_t max_argc;
std::array<operator_t<ARG_TYPE, ENUM_TYPE>, ENUM_MAX> operators;
[[nodiscard]] constexpr arg_count_t getMaxArgc() const
{
return max_argc;
}
2024-02-20 15:18:19 -05:00
};
2024-02-29 11:25:39 -05:00
template<typename NODE_CONTAINER, arg_count_t MAX_ARGS, template<typename> typename ALLOC>
2024-02-20 15:18:19 -05:00
class node_tree
{
private:
2024-02-29 11:25:39 -05:00
static ALLOC<NODE_CONTAINER> allocator;
2024-02-20 15:18:19 -05:00
struct node
{
2024-02-29 11:25:39 -05:00
std::array<node*, MAX_ARGS> children;
2024-02-20 15:18:19 -05:00
NODE_CONTAINER caller;
};
public:
};
2024-02-19 15:55:54 -05:00
/*
* Functions
*/
void run_tree_type_tests(blt::size_t population_size, blt::size_t tree_min_size, blt::size_t tree_max_size)
{
(void) population_size;
(void) tree_min_size;
(void) tree_max_size;
2024-02-20 15:18:19 -05:00
std::cout << log_base(population_size) << std::endl;
2024-02-19 15:55:54 -05:00
}
}