silly functions
parent
a69e3274dc
commit
3b13e48f36
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.25)
|
||||
project(COSC-4P80-Assignment-3 VERSION 0.0.8)
|
||||
project(COSC-4P80-Assignment-3 VERSION 0.0.9)
|
||||
include(FetchContent)
|
||||
|
||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define COSC_4P80_ASSIGNMENT_3_FUNCTIONS_H
|
||||
|
||||
#include <assign3/fwdecl.h>
|
||||
#include <blt/std/ranges.h>
|
||||
|
||||
namespace assign3
|
||||
{
|
||||
|
@ -39,6 +40,16 @@ namespace assign3
|
|||
[[nodiscard]] Scalar call(Scalar dist, Scalar r) const final;
|
||||
};
|
||||
|
||||
struct distance_function_t
|
||||
{
|
||||
[[nodiscard]] virtual Scalar distance(blt::span<const Scalar> x, blt::span<const Scalar> y) const = 0;
|
||||
};
|
||||
|
||||
struct euclidean_distance_function_t : public distance_function_t
|
||||
{
|
||||
[[nodiscard]] Scalar distance(blt::span<const Scalar> x, blt::span<const Scalar> y) const final;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //COSC_4P80_ASSIGNMENT_3_FUNCTIONS_H
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
/*
|
||||
* 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 COSC_4P80_ASSIGNMENT_3_UI_H
|
||||
#define COSC_4P80_ASSIGNMENT_3_UI_H
|
||||
|
||||
namespace assign3 {
|
||||
|
||||
}
|
||||
|
||||
#endif //COSC_4P80_ASSIGNMENT_3_UI_H
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#include <assign3/functions.h>
|
||||
#include <cmath>
|
||||
#include "blt/iterator/zip.h"
|
||||
|
||||
namespace assign3
|
||||
{
|
||||
|
@ -26,4 +27,15 @@ namespace assign3
|
|||
auto dist_sq = dist * dist;
|
||||
return std::exp(-r * dist_sq);
|
||||
}
|
||||
|
||||
Scalar euclidean_distance_function_t::distance(blt::span<const Scalar> x, blt::span<const Scalar> y) const
|
||||
{
|
||||
Scalar dist = 0;
|
||||
for (auto [a, b] : blt::in_pairs(x, y))
|
||||
{
|
||||
auto d = a - b;
|
||||
dist += d * d;
|
||||
}
|
||||
return std::sqrt(dist);
|
||||
}
|
||||
}
|
86
src/main.cpp
86
src/main.cpp
|
@ -21,9 +21,26 @@ blt::gfx::first_person_camera_2d camera;
|
|||
|
||||
blt::size_t som_width = 7;
|
||||
blt::size_t som_height = 7;
|
||||
blt::size_t max_epochs = 100;
|
||||
blt::size_t max_epochs = 1000;
|
||||
Scalar initial_learn_rate = 0.1;
|
||||
|
||||
int currently_selected_network = 0;
|
||||
std::vector<std::string> map_files_names;
|
||||
|
||||
float neuron_scale = 35;
|
||||
float draw_width = neuron_scale * static_cast<float>(som_width);
|
||||
float draw_height = neuron_scale * static_cast<float>(som_height);
|
||||
|
||||
void generate_network(int selection)
|
||||
{
|
||||
som = std::make_unique<som_t>(files[selection].normalize(), som_width, som_height, max_epochs);
|
||||
}
|
||||
|
||||
const char* get_selection_string(void*, int selection)
|
||||
{
|
||||
return map_files_names[selection].c_str();
|
||||
}
|
||||
|
||||
void init(const blt::gfx::window_data&)
|
||||
{
|
||||
using namespace blt::gfx;
|
||||
|
@ -33,15 +50,16 @@ void init(const blt::gfx::window_data&)
|
|||
resources.load_resources();
|
||||
renderer_2d.create();
|
||||
|
||||
som = std::make_unique<som_t>(
|
||||
*std::find_if(files.begin(), files.end(), [](const data_file_t& v) { return v.data_points.begin()->bins.size() == 32; }),
|
||||
som_width, som_height, max_epochs);
|
||||
for (const auto& data : files)
|
||||
map_files_names.emplace_back(std::to_string(data.data_points.begin()->bins.size()));
|
||||
|
||||
generate_network(currently_selected_network);
|
||||
}
|
||||
|
||||
void update(const blt::gfx::window_data& data)
|
||||
void update(const blt::gfx::window_data& window_data)
|
||||
{
|
||||
using namespace blt::gfx;
|
||||
global_matrices.update_perspectives(data.width, data.height, 90, 0.1, 2000);
|
||||
global_matrices.update_perspectives(window_data.width, window_data.height, 90, 0.1, 2000);
|
||||
|
||||
camera.update();
|
||||
camera.update_view(global_matrices);
|
||||
|
@ -49,6 +67,10 @@ void update(const blt::gfx::window_data& data)
|
|||
|
||||
if (ImGui::Begin("Controls"))
|
||||
{
|
||||
ImGui::Text("Network Select");
|
||||
if (ImGui::ListBox("##Network Select", ¤tly_selected_network, get_selection_string, nullptr, static_cast<int>(map_files_names.size())))
|
||||
generate_network(currently_selected_network);
|
||||
|
||||
if (ImGui::Button("Run Epoch"))
|
||||
{
|
||||
static gaussian_function_t func;
|
||||
|
@ -71,8 +93,8 @@ void update(const blt::gfx::window_data& data)
|
|||
activations.clear();
|
||||
activations.resize(som->get_array().get_map().size());
|
||||
|
||||
auto& meow = *std::find_if(files.begin(), files.end(), [](const data_file_t& v) { return v.data_points.begin()->bins.size() == 32; });
|
||||
for (auto& v : meow.data_points)
|
||||
auto current_data_file = files[currently_selected_network].normalize();
|
||||
for (auto& v : current_data_file.data_points)
|
||||
{
|
||||
auto nearest = som->get_closest_neuron(v.bins);
|
||||
activations[nearest] += v.is_bad ? -1 : 1;
|
||||
|
@ -83,20 +105,58 @@ void update(const blt::gfx::window_data& data)
|
|||
|
||||
for (auto [i, v] : blt::enumerate(som->get_array().get_map()))
|
||||
{
|
||||
float scale = 35;
|
||||
|
||||
auto activation = activations[i];
|
||||
|
||||
blt::vec4 color = blt::make_color(1,1,1);
|
||||
blt::vec4 color = blt::make_color(1, 1, 1);
|
||||
if (activation > 0)
|
||||
color = blt::make_color(0, static_cast<Scalar>(activation) / static_cast<Scalar>(max), 0);
|
||||
else if (activation < 0)
|
||||
color = blt::make_color(std::abs(static_cast<Scalar>(activation) / static_cast<Scalar>(min)), 0, 0);
|
||||
|
||||
renderer_2d.drawPointInternal(color, point2d_t{v.get_x() * scale + scale, v.get_y() * scale + scale, scale});
|
||||
renderer_2d.drawPointInternal(color,
|
||||
point2d_t{v.get_x() * neuron_scale + neuron_scale, v.get_y() * neuron_scale + neuron_scale, neuron_scale});
|
||||
}
|
||||
|
||||
renderer_2d.render(data.width, data.height);
|
||||
static std::vector<float> closest_type;
|
||||
closest_type.clear();
|
||||
closest_type.resize(som->get_array().get_map().size());
|
||||
|
||||
for (auto [i, v] : blt::enumerate(som->get_array().get_map()))
|
||||
{
|
||||
Scalar lowest_distance = std::numeric_limits<Scalar>::max();
|
||||
bool is_bad = false;
|
||||
for (const auto& data : current_data_file.data_points)
|
||||
{
|
||||
auto dist = v.dist(data.bins);
|
||||
if (dist < lowest_distance)
|
||||
{
|
||||
lowest_distance = dist;
|
||||
is_bad = data.is_bad;
|
||||
}
|
||||
}
|
||||
// BLT_TRACE(is_bad ? -lowest_distance : lowest_distance);
|
||||
closest_type[i] = is_bad ? -lowest_distance : lowest_distance;
|
||||
}
|
||||
|
||||
auto min_dist = *std::min_element(closest_type.begin(), closest_type.end());
|
||||
auto max_dist = *std::max_element(closest_type.begin(), closest_type.end());
|
||||
|
||||
for (auto [i, v] : blt::enumerate(som->get_array().get_map()))
|
||||
{
|
||||
auto type = closest_type[i];
|
||||
|
||||
blt::vec4 color = blt::make_color(1, 1, 1);
|
||||
if (type >= 0)
|
||||
color = blt::make_color(0, 1 - (type / max_dist) + 0.1f, 0);
|
||||
else if (type < 0)
|
||||
color = blt::make_color(1 - (type / min_dist) + 0.1f, 0, 0);
|
||||
|
||||
renderer_2d.drawPointInternal(color,
|
||||
point2d_t{draw_width + neuron_scale * 2 + v.get_x() * neuron_scale + neuron_scale,
|
||||
v.get_y() * neuron_scale + neuron_scale, neuron_scale});
|
||||
}
|
||||
|
||||
renderer_2d.render(window_data.width, window_data.height);
|
||||
}
|
||||
|
||||
void destroy(const blt::gfx::window_data&)
|
||||
|
|
|
@ -49,19 +49,13 @@ namespace assign3
|
|||
|
||||
Scalar neuron_t::dist(const std::vector<Scalar>& X) const
|
||||
{
|
||||
Scalar dist = 0;
|
||||
for (auto [v, x] : blt::zip(data, X))
|
||||
{
|
||||
auto loc = (v - x);
|
||||
dist += loc * loc;
|
||||
}
|
||||
return std::sqrt(dist);
|
||||
euclidean_distance_function_t dist_func;
|
||||
return dist_func.distance(data, X);
|
||||
}
|
||||
|
||||
Scalar neuron_t::distance(const neuron_t& n1, const neuron_t& n2)
|
||||
{
|
||||
auto dx = n1.get_x() - n2.get_x();
|
||||
auto dy = n1.get_y() - n2.get_y();
|
||||
return std::sqrt(dx * dx + dy * dy);
|
||||
euclidean_distance_function_t dist_func;
|
||||
return dist_func.distance({n1.get_x(), n1.get_y()}, {n2.get_x(), n2.get_y()});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue