GP_Image_Test/include/functions.h

284 lines
8.5 KiB
C++

/*
* <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/>.
*/
#ifndef GP_IMAGE_TEST_FUNCTIONS_H
#define GP_IMAGE_TEST_FUNCTIONS_H
// FUNC_DEFINE(NAME, REQUIRED_ARGS, FUNC, ALLOWED_FUNCS)
// FUNC_ALLOW_ANY
#include <initializer_list>
#include <vector>
#include "blt/std/hashmap.h"
#include "blt/std/logging.h"
#include "blt/std/types.h"
#include <variant>
#include <array>
#include <image.h>
template<typename T>
using allowed_funcs = std::vector<T>;
template<typename T>
using allowed_funcs_set = blt::hashset_t<T>;
template<typename T>
using func_list = std::vector<allowed_funcs<T>>;
template<typename T>
using func_set = std::vector<allowed_funcs_set<T>>;
template<typename T>
inline constexpr func_set<T> convert(const func_list<T>& func)
{
func_set<T> set_list;
for (const auto& v : func)
{
allowed_funcs_set<T> set;
for (const auto& f : v)
set.insert(f);
set_list.push_back(set);
}
return set_list;
}
using data_t = std::array<float, 3>;
class empty
{
};
// #define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ALLOWED...)
#define FUNC_ALLOW_ANY
#define FUNC_ALLOW_NONE
#define FUNC_ALLOW_BOOL
#define FUNC_ALLOW_COORD
#define FUNC_ALLOW_SCALAR
#define FUNC_ALLOW_SCALAR_COORD
#define FUNC_ALLOW_TERMINALS
/*
* Define Functions
*/
#define ARGS image& img, float x, float y, blt::size_t argc, const image** argv, const data_t& extra_data
void f_x(ARGS);
void f_y(ARGS);
void f_random(ARGS);
void f_noise(ARGS);
void f_cnoise(ARGS);
void f_scalar(ARGS);
void f_color(ARGS);
void f_log(ARGS);
void f_sqrt(ARGS);
void f_sin(ARGS);
void f_cos(ARGS);
void f_atan(ARGS);
void f_add(ARGS);
void f_sub(ARGS);
void f_mul(ARGS);
void f_div(ARGS);
void f_or(ARGS);
void f_and(ARGS);
void f_xor(ARGS);
void f_if(ARGS);
void f_equ(ARGS);
void f_lt(ARGS);
void f_gt(ARGS);
void f_lte(ARGS);
void f_gte(ARGS);
/*
* Define function enums / lists
*/
// NAME MIN MAX FUNC ALLOWED FUNC LIST
#define FUNC_FUNCTIONS \
FUNC_DEFINE(X, 0, 0, f_x, FUNC_ALLOW_NONE) \
FUNC_DEFINE(Y, 0, 0, f_y, FUNC_ALLOW_NONE) \
FUNC_DEFINE(RANDOM, 0, 0, f_random, FUNC_ALLOW_NONE) \
FUNC_DEFINE(NOISE, 0, 2, f_noise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
FUNC_DEFINE(CNOISE, 0, 6, f_cnoise, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR, FUNC_ALLOW_SCALAR) \
FUNC_DEFINE(SCALAR, 0, 0, f_scalar, FUNC_ALLOW_NONE) \
FUNC_DEFINE(COLOR, 0, 0, f_color, FUNC_ALLOW_NONE) \
FUNC_DEFINE(LOG, 1, 1, f_log, FUNC_ALLOW_ANY) \
FUNC_DEFINE(SQRT, 1, 1, f_sqrt, FUNC_ALLOW_ANY) \
FUNC_DEFINE(SIN, 1, 1, f_sin, FUNC_ALLOW_ANY) \
FUNC_DEFINE(COS, 1, 1, f_cos, FUNC_ALLOW_ANY) \
FUNC_DEFINE(ATAN, 1, 1, f_atan, FUNC_ALLOW_ANY) \
FUNC_DEFINE(ADD, 2, 2, f_add, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(SUB, 2, 2, f_sub, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(MUL, 2, 2, f_mul, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(DIV, 2, 2, f_div, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(OR, 2, 2, f_or, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(AND, 2, 2, f_and, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(XOR, 2, 2, f_xor, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(IF, 3, 3, f_if, FUNC_ALLOW_BOOL, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(EQU, 2, 2, f_equ, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(LT, 2, 2, f_lt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(GT, 2, 2, f_gt, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(LTE, 2, 2, f_lte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY) \
FUNC_DEFINE(GTE, 2, 2, f_gte, FUNC_ALLOW_ANY, FUNC_ALLOW_ANY)
#undef FUNC_ALLOW_ANY
#undef FUNC_ALLOW_NONE
#undef FUNC_ALLOW_BOOL
#undef FUNC_ALLOW_COORD
#undef FUNC_ALLOW_SCALAR
#undef FUNC_ALLOW_SCALAR_COORD
#undef FUNC_ALLOW_TERMINALS
/*
* Construct enum
*/
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) NAME,
enum class function_t : blt::i32
{
FUNC_FUNCTIONS
m_END
};
#undef FUNC_DEFINE
static inline blt::i32 to_underlying(function_t f)
{
return static_cast<blt::i32>(f);
}
static inline constexpr blt::i32 OPERATOR_COUNT = static_cast<int>(function_t::m_END);
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MAX_ARGS,
static inline constexpr blt::i32 MAX_ARGS = std::max({FUNC_FUNCTIONS});
#undef FUNC_DEFINE
/*
* Define function lists
*/
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) function_t::NAME,
#define DEF_FUNC_LIST(NAME, ...) \
static inline const allowed_funcs_set<function_t> NAME##_SET{__VA_ARGS__}; \
static inline const allowed_funcs<function_t> NAME{__VA_ARGS__};
DEF_FUNC_LIST(FUNC_ALLOW_ANY, FUNC_FUNCTIONS);
DEF_FUNC_LIST(FUNC_ALLOW_NONE,);
DEF_FUNC_LIST(FUNC_ALLOW_BOOL, function_t::OR, function_t::AND, function_t::XOR, function_t::EQU, function_t::GT, function_t::LT, function_t::GTE,
function_t::LTE);
DEF_FUNC_LIST(FUNC_ALLOW_COORD, function_t::X, function_t::Y);
DEF_FUNC_LIST(FUNC_ALLOW_SCALAR, function_t::SCALAR);
DEF_FUNC_LIST(FUNC_ALLOW_SCALAR_COORD, function_t::SCALAR, function_t::X, function_t::Y);
DEF_FUNC_LIST(FUNC_ALLOW_TERMINALS, function_t::SCALAR, function_t::X, function_t::Y, function_t::COLOR, function_t::RANDOM);
#undef FUNC_DEFINE
/*
* Create mappings
*/
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MIN_ARGS,
[[maybe_unused]] static inline std::array<blt::i32, OPERATOR_COUNT> function_arg_min_map = {
FUNC_FUNCTIONS
};
#undef FUNC_DEFINE
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) MAX_ARGS,
[[maybe_unused]] static inline std::array<blt::i32, OPERATOR_COUNT> function_arg_max_map = {
FUNC_FUNCTIONS
};
#undef FUNC_DEFINE
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) func_list<function_t>{__VA_ARGS__},
[[maybe_unused]] static inline std::array<func_list<function_t>, OPERATOR_COUNT> function_arg_allowed_map = {
FUNC_FUNCTIONS
};
#undef FUNC_DEFINE
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) convert(func_list<function_t>{__VA_ARGS__}),
[[maybe_unused]] static inline std::array<func_set<function_t>, OPERATOR_COUNT> function_arg_allowed_set_map = {
FUNC_FUNCTIONS
};
#undef FUNC_DEFINE
#define FUNC_DEFINE(NAME, MIN_ARGS, MAX_ARGS, FUNC, ...) #NAME,
[[maybe_unused]] static inline std::array<std::string, OPERATOR_COUNT> function_name_map = {
FUNC_FUNCTIONS
};
#undef FUNC_DEFINE
/*
* Helper functions
*/
inline static allowed_funcs<function_t> intersection(const allowed_funcs<function_t>& vec, const allowed_funcs_set<function_t>& has)
{
allowed_funcs<function_t> set;
for (auto v : vec)
if (has.contains(v))
set.push_back(v);
return set;
}
inline static allowed_funcs<function_t> intersection_comp(const allowed_funcs<function_t>& vec, const allowed_funcs_set<function_t>& has)
{
allowed_funcs<function_t> set;
for (auto v : vec)
if (!has.contains(v))
set.push_back(v);
return set;
}
// distribution from normality (DFN)
float eval_DNF_SW(const image& img);
float eval_DNF_SW_1(const image& img);
float eval_BAM(const image& img, const image& compare, float allowed_diff);
float eval_DST(const image& img, const image& compare);
//template<typename F>
//bool isNan(F f)
//{
// return f == std::numeric_limits<F>::quiet_NaN() || f == std::numeric_limits<F>::signaling_NaN();
//}
template<typename F>
bool isInf(F f)
{
return f == std::numeric_limits<F>::infinity() || f == -std::numeric_limits<F>::infinity();
}
#endif //GP_IMAGE_TEST_FUNCTIONS_H