Brett 2024-11-19 15:48:33 -05:00
parent 73da5ff006
commit b9a8d3ffbc
11 changed files with 234 additions and 368 deletions

View File

@ -1,222 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AnalysisUIOptions">
<option name="ANALYZE_INJECTED_CODE" value="false" />
<option name="SCOPE_TYPE" value="3" />
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="BackendCodeEditorMiscSettings">
<option name="/Default/RiderDebugger/RiderRestoreDecompile/RestoreDecompileSetting/@EntryValue" value="false" type="bool" />
<option name="/Default/Housekeeping/GlobalSettingsUpgraded/IsUpgraded/@EntryValue" value="true" type="bool" />
<option name="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=SwitchToGoToActionSuggester/@EntryIndexedValue" value="true" type="bool" />
<option name="/Default/Housekeeping/FeatureSuggestion/FeatureSuggestionManager/DisabledSuggesters/=SwitchToGoToActionSuggester/@EntryIndexRemoved" />
<option name="/Default/Environment/Hierarchy/GeneratedFilesCacheKey/Timestamp/@EntryValue" value="14" type="long" />
<option name="/Default/Housekeeping/OptionsDialog/SelectedPageId/@EntryValue" value="CppFormatterOtherPage" type="string" />
</component>
<component name="CMakePresetLoader">{
&quot;useNewFormat&quot;: true
}</component>
<component name="CMakeProjectFlavorService">
<option name="flavorId" value="CMakePlainProjectFlavor" />
</component>
<component name="CMakeReloadState">
<option name="reloaded" value="true" />
</component>
<component name="CMakeRunConfigurationManager">
<generated>
<config projectName="COSC-4P80-Assignment-3" targetName="BLT_WITH_GRAPHICS" />
<config projectName="COSC-4P80-Assignment-3" targetName="freetype" />
<config projectName="COSC-4P80-Assignment-3" targetName="BLT" />
<config projectName="COSC-4P80-Assignment-3" targetName="COSC-4P80-Assignment-3" />
</generated>
</component>
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
<configuration PROFILE_NAME="Release" ENABLED="true" CONFIG_NAME="Release" />
<configuration PROFILE_NAME="RelWithDebInfo" ENABLED="true" CONFIG_NAME="RelWithDebInfo" />
<configuration PROFILE_NAME="RelWithDebInfo Addrsan" ENABLED="true" CONFIG_NAME="RelWithDebInfo" GENERATION_OPTIONS="-DENABLE_ADDRSAN=ON -DENABLE_UBSAN=ON" />
<configuration PROFILE_NAME="RelWithDebInfo ubsan" ENABLED="true" CONFIG_NAME="RelWithDebInfo" GENERATION_OPTIONS="-DENABLE_UBSAN=ON" />
<configuration PROFILE_NAME="Debug Addrsan" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DENABLE_ADDRSAN=ON" />
</configurations>
</component>
<component name="ChangeListManager">
<list default="true" id="df4fb81f-8c9e-43af-9712-6ff8baeb587a" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/gen-llil.pl" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/gen-llil.pl" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/gen_files" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/gen_files" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/run_llil4map" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/examples/llil_utils/run_llil4map" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/phmap_lldb.py" beforeDir="false" afterPath="$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/libraries/parallel-hashmap/phmap_lldb.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ClangdSettings">
<option name="formatViaClangd" value="false" />
<option name="indexerUseModules" value="false" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="CMakeBuildProfile:RelWithDebInfo" />
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/include/assign3/array.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/include/assign3/file.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/include/assign3/functions.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/include/assign3/neuron.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/include/assign3/som.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/include/assign3/ui.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/lib/blt-with-graphics/include/blt/gfx/font/font_awesome_defines.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/lib/blt-with-graphics/include/blt/gfx/renderer/font_renderer.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/lib/blt-with-graphics/libraries/BLT/include/blt/std/ranges.h" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/array.cpp" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/file.cpp" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/functions.cpp" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/main.cpp" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/neuron.cpp" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/src/som.cpp" root0="FORCE_HIGHLIGHTING" />
</component>
<component name="ProblemsViewState">
<option name="selectedTabId" value="CurrentFile" />
</component>
<component name="ProjectApplicationVersion">
<option name="ide" value="CLion" />
<option name="majorVersion" value="2024" />
<option name="minorVersion" value="1.3" />
<option name="productBranch" value="Classic" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 7
}</component>
<component name="ProjectId" id="2oG5NNX4GedKhxLJDuzQ5OR5kr5" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;CMake Application.COSC-4P80-Assignment-3.executor&quot;: &quot;Run&quot;,
&quot;NIXITCH_NIXPKGS_CONFIG&quot;: &quot;/etc/nix/nixpkgs-config.nix&quot;,
&quot;NIXITCH_NIX_CONF_DIR&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_OTHER_STORES&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_PATH&quot;: &quot;/home/brett/.nix-defexpr/channels:nixpkgs=/nix/var/nix/profiles/per-user/root/channels/nixos:nixos-config=/etc/nixos/configuration.nix:/nix/var/nix/profiles/per-user/root/channels&quot;,
&quot;NIXITCH_NIX_PROFILES&quot;: &quot;/run/current-system/sw /nix/var/nix/profiles/default /etc/profiles/per-user/brett /home/brett/.local/state/nix/profile /nix/profile /home/brett/.nix-profile&quot;,
&quot;NIXITCH_NIX_REMOTE&quot;: &quot;&quot;,
&quot;NIXITCH_NIX_USER_PROFILE_DIR&quot;: &quot;/nix/var/nix/profiles/per-user/brett&quot;,
&quot;RunOnceActivity.RadMigrateCodeStyle&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;RunOnceActivity.readMode.enableVisualFormatting&quot;: &quot;true&quot;,
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;cf.advertisement.text.has.clang-format&quot;: &quot;true&quot;,
&quot;cf.first.check.clang-format&quot;: &quot;false&quot;,
&quot;cidr.known.project.marker&quot;: &quot;true&quot;,
&quot;git-widget-placeholder&quot;: &quot;main&quot;,
&quot;last_opened_file_path&quot;: &quot;/home/brett/Documents/Brock/CS 4P80/COSC-4P80-Assignment-3&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;run.code.analysis.last.selected.profile&quot;: &quot;pProject Default&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.sourceCode.C/C++&quot;,
&quot;structure.view.defaults.are.configured&quot;: &quot;true&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/lib/blt-with-graphics/include/blt/gfx/font" />
</key>
</component>
<component name="RunManager" selected="CMake Application.COSC-4P80-Assignment-3">
<configuration name="BLT" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="COSC-4P80-Assignment-3" TARGET_NAME="BLT" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="BLT_WITH_GRAPHICS" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="COSC-4P80-Assignment-3" TARGET_NAME="BLT_WITH_GRAPHICS" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="COSC-4P80-Assignment-3" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="COSC-4P80-Assignment-3" TARGET_NAME="COSC-4P80-Assignment-3" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="COSC-4P80-Assignment-3" RUN_TARGET_NAME="COSC-4P80-Assignment-3">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="freetype" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="COSC-4P80-Assignment-3" TARGET_NAME="freetype" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<configuration name="msdfgen-core" type="CMakeRunConfiguration" factoryName="Application" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="COSC-4P80-Assignment-3" TARGET_NAME="msdfgen-core" CONFIG_NAME="Debug">
<method v="2">
<option name="com.jetbrains.cidr.execution.CidrBuildBeforeRunTaskProvider$BuildBeforeRunTask" enabled="true" />
</method>
</configuration>
<list>
<item itemvalue="CMake Application.BLT_WITH_GRAPHICS" />
<item itemvalue="CMake Application.BLT" />
<item itemvalue="CMake Application.COSC-4P80-Assignment-3" />
<item itemvalue="CMake Application.freetype" />
<item itemvalue="CMake Application.msdfgen-core" />
</list>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="df4fb81f-8c9e-43af-9712-6ff8baeb587a" name="Changes" comment="" />
<created>1730483030448</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1730483030448</updated>
<workItem from="1730483031471" duration="57000" />
<workItem from="1730483139508" duration="22719000" />
<workItem from="1730760265254" duration="6300000" />
<workItem from="1730932443628" duration="1866000" />
<workItem from="1731098529771" duration="11456000" />
<workItem from="1731298352794" duration="46000" />
<workItem from="1731298462144" duration="20154000" />
<workItem from="1731370094158" duration="776000" />
<workItem from="1731430940789" duration="18816000" />
<workItem from="1731607891598" duration="688000" />
<workItem from="1731608714255" duration="241000" />
<workItem from="1731609005148" duration="269000" />
<workItem from="1731609278663" duration="148000" />
<workItem from="1731609433368" duration="774000" />
<workItem from="1731610215063" duration="10825000" />
<workItem from="1731969052837" duration="4000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VCPKGProject">
<isAutomaticCheckingOnLaunch value="false" />
<isAutomaticFoundErrors value="true" />
<isAutomaticReloadCMake value="true" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="XSLT-Support.FileAssociations.UIState">
<expand />
<select />
</component>
</project>

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25)
project(COSC-4P80-Assignment-3 VERSION 0.0.21)
project(COSC-4P80-Assignment-3 VERSION 0.0.22)
include(FetchContent)
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
@ -14,6 +14,12 @@ FetchContent_Declare(implot
FIND_PACKAGE_ARGS)
FetchContent_MakeAvailable(implot)
FetchContent_Declare(matplotplusplus
GIT_REPOSITORY https://github.com/alandefreitas/matplotplusplus
GIT_TAG v1.2.1
FIND_PACKAGE_ARGS)
FetchContent_MakeAvailable(matplotplusplus)
add_subdirectory(lib/blt-with-graphics)
include_directories(include/)
@ -26,7 +32,7 @@ add_executable(COSC-4P80-Assignment-3 ${PROJECT_BUILD_FILES} ${IM_PLOT_FILES})
target_compile_options(COSC-4P80-Assignment-3 PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_link_options(COSC-4P80-Assignment-3 PRIVATE -Wall -Wextra -Wpedantic -Wno-comment)
target_link_libraries(COSC-4P80-Assignment-3 PRIVATE BLT_WITH_GRAPHICS)
target_link_libraries(COSC-4P80-Assignment-3 PRIVATE BLT_WITH_GRAPHICS matplot)
if (${ENABLE_ADDRSAN} MATCHES ON)
target_compile_options(COSC-4P80-Assignment-3 PRIVATE -fsanitize=address)

View File

@ -21,6 +21,7 @@
#include <assign3/fwdecl.h>
#include <blt/std/ranges.h>
#include <memory>
namespace assign3
{
@ -58,6 +59,8 @@ namespace assign3
[[nodiscard]] virtual Scalar distance(blt::span<const Scalar> x, blt::span<const Scalar> y) const = 0;
virtual ~distance_function_t() = default;
static std::unique_ptr<distance_function_t> from_shape(shape_t shape, blt::u32 som_width, blt::u32 som_height);
};
struct euclidean_distance_function_t : public distance_function_t

View File

@ -90,21 +90,7 @@ namespace assign3
void regenerate_network()
{
switch (static_cast<shape_t>(selected_som_mode))
{
case shape_t::GRID:
distance_function = std::make_unique<euclidean_distance_function_t>();
break;
case shape_t::GRID_WRAP:
distance_function = std::make_unique<toroidal_euclidean_distance_function_t>(som_width, som_height);
break;
case shape_t::GRID_OFFSET:
distance_function = std::make_unique<axial_distance_function_t>();
break;
case shape_t::GRID_OFFSET_WRAP:
distance_function = std::make_unique<toroidal_axial_distance_function_t>(som_width, som_height);
break;
}
distance_function = distance_function_t::from_shape(static_cast<shape_t>(selected_som_mode), som_width, som_height);
som = std::make_unique<som_t>(motor_data.files[currently_selected_network], som_width, som_height, max_epochs,
distance_function.get(), topology_function.get(), static_cast<shape_t>(selected_som_mode),
static_cast<init_t>(selected_init_type), normalize_init);

View File

@ -42,12 +42,18 @@ namespace assign3
Scalar topological_error();
Scalar quantization_error();
void compute_neuron_activations(Scalar distance = 2, Scalar activation = 0.5);
void write_activations(std::ostream& out);
void write_topology_errors(std::ostream& out);
void write_quantization_errors(std::ostream& out);
void write_all_errors(std::ostream& out);
[[nodiscard]] const array_t& get_array() const
{ return array; }
@ -60,6 +66,9 @@ namespace assign3
[[nodiscard]] const std::vector<Scalar>& get_topological_errors() const
{ return topological_errors; }
[[nodiscard]] const std::vector<Scalar>& get_quantization_errors() const
{ return quantization_errors; }
private:
array_t array;
data_file_t file;
@ -68,7 +77,11 @@ namespace assign3
distance_function_t* dist_func;
topology_function_t* topology_function;
// normalized value for which below this will be considered neural
float quantization_distance = 0.25;
std::vector<Scalar> topological_errors;
std::vector<Scalar> quantization_errors;
};
}

View File

@ -88,4 +88,20 @@ namespace assign3
Scalar total = x_min + y_min;
return total - std::min(x_min, y_min);
}
std::unique_ptr<distance_function_t> distance_function_t::from_shape(shape_t shape, blt::u32 som_width, blt::u32 som_height)
{
switch (shape)
{
case shape_t::GRID:
return std::make_unique<euclidean_distance_function_t>();
case shape_t::GRID_WRAP:
return std::make_unique<toroidal_euclidean_distance_function_t>(som_width, som_height);
case shape_t::GRID_OFFSET:
return std::make_unique<axial_distance_function_t>();
case shape_t::GRID_OFFSET_WRAP:
return std::make_unique<toroidal_axial_distance_function_t>(som_width, som_height);
}
return nullptr;
}
}

View File

@ -1,125 +0,0 @@
#include <blt/std/logging.h>
#include <blt/parse/argparse.h>
#include <blt/gfx/window.h>
#include "blt/gfx/renderer/resource_manager.h"
#include "blt/gfx/renderer/camera.h"
#include "implot.h"
#include <assign3/file.h>
#include <assign3/manager.h>
using namespace assign3;
blt::gfx::matrix_state_manager global_matrices;
blt::gfx::resource_manager resources;
blt::gfx::first_person_camera_2d camera;
assign3::motor_data_t data{};
assign3::renderer_t renderer{data, resources, global_matrices};
void init(const blt::gfx::window_data&)
{
using namespace blt::gfx;
BLT_INFO("Hello World!");
global_matrices.create_internals();
resources.load_resources();
renderer.create();
ImPlot::CreateContext();
}
void update(const blt::gfx::window_data& window_data)
{
using namespace blt::gfx;
global_matrices.update_perspectives(window_data.width, window_data.height, 90, 0.1, 2000);
camera.update();
camera.update_view(global_matrices);
global_matrices.update();
renderer.render();
}
void destroy(const blt::gfx::window_data&)
{
global_matrices.cleanup();
resources.cleanup();
renderer.cleanup();
ImPlot::DestroyContext();
blt::gfx::cleanup();
BLT_INFO("Goodbye World!");
}
void load_data_files(const std::string& str)
{
data.files = assign3::data_file_t::load_data_files_from_path(str);
for (auto& v : data.files)
v = v.normalize();
data.update();
}
void action_start_graphics(const std::vector<std::string>& argv_vector)
{
blt::arg_parse parser{};
parser.addArgument(blt::arg_builder{"--file", "-f"}
.setDefault("../data")
.setHelp("Path to data files").build());
auto args = parser.parse_args(argv_vector);
load_data_files(args.get<std::string>("file"));
blt::gfx::init(blt::gfx::window_data{"My Sexy Window", init, update, destroy}.setSyncInterval(1).setMaximized(true));
}
void action_test(const std::vector<std::string>& argv_vector)
{
blt::arg_parse parser{};
parser.addArgument(blt::arg_builder{"--file", "-f"}
.setDefault("../data")
.setHelp("Path to data files").build());
auto args = parser.parse_args(argv_vector);
load_data_files(args.get<std::string>("file"));
}
void action_convert(const std::vector<std::string>& argv_vector)
{
}
int main(int argc, const char** argv)
{
std::vector<std::string> argv_vector;
for (int i = 0; i < argc; i++)
argv_vector.emplace_back(argv[i]);
blt::arg_parse parser{};
parser.addArgument(blt::arg_builder{"action"}
.setAction(blt::arg_action_t::SUBCOMMAND)
.setHelp("Action to run. Can be: [graphics, test, convert]").build());
auto args = parser.parse_args(argv_vector);
if (!args.contains("action"))
{
BLT_ERROR("Please provide an action");
return 0;
}
argv_vector.erase(argv_vector.begin() + 1);
auto action = blt::string::toLowerCase(args.get<std::string>("action"));
if (action == "graphics")
action_start_graphics(argv_vector);
else if (action == "test")
action_test(argv_vector);
else if (action == "convert")
action_convert(argv_vector);
}

View File

@ -6,6 +6,11 @@
#include "implot.h"
#include <assign3/file.h>
#include <assign3/manager.h>
#include <thread>
#include <mutex>
#include <fstream>
#include <filesystem>
#include <matplot/matplot.h>
using namespace assign3;
@ -73,6 +78,32 @@ void action_start_graphics(const std::vector<std::string>& argv_vector)
blt::gfx::init(blt::gfx::window_data{"My Sexy Window", init, update, destroy}.setSyncInterval(1).setMaximized(true));
}
struct activation
{
Scalar x, y, act;
};
struct task_t // NOLINT
{
data_file_t* file;
blt::u32 width, height;
blt::size_t max_epochs;
shape_t shape;
init_t init;
Scalar initial_learn_rate;
task_t() = default; // NOLINT
task_t(data_file_t* file, blt::u32 width, blt::u32 height, size_t maxEpochs, shape_t shape, init_t init, Scalar initial_learn_rate):
file(file), width(width), height(height), max_epochs(maxEpochs), shape(shape), init(init), initial_learn_rate(initial_learn_rate)
{}
gaussian_function_t topology_func{};
std::vector<std::vector<Scalar>> topological_errors{};
std::vector<std::vector<Scalar>> quantization_errors{};
std::vector<std::vector<activation>> activations{};
};
void action_test(const std::vector<std::string>& argv_vector)
{
blt::arg_parse parser{};
@ -86,7 +117,112 @@ void action_test(const std::vector<std::string>& argv_vector)
load_data_files(args.get<std::string>("file"));
std::vector<task_t> tasks;
std::vector<std::thread> threads;
std::mutex task_mutex;
tasks.emplace_back(&data.files[1], 5, 5, 1000, shape_t::GRID, init_t::RANDOM_DATA, 0.1);
static blt::size_t runs = 30;
for (blt::size_t i = 0; i < std::thread::hardware_concurrency(); i++)
{
threads.emplace_back([&task_mutex, &tasks]() {
do
{
task_t task;
{
std::scoped_lock lock(task_mutex);
if (tasks.empty())
break;
task = std::move(tasks.back());
tasks.pop_back();
}
for (blt::size_t i = 0; i < runs; i++)
{
gaussian_function_t func{};
auto dist = distance_function_t::from_shape(task.shape, task.width, task.height);
std::unique_ptr<som_t> som = std::make_unique<som_t>(*task.file, task.width, task.height, task.max_epochs, dist.get(),
&task.topology_func, task.shape, task.init, false);
while (som->get_current_epoch() < som->get_max_epochs())
som->train_epoch(task.initial_learn_rate);
som->compute_neuron_activations();
task.topological_errors.push_back(som->get_topological_errors());
task.quantization_errors.push_back(som->get_quantization_errors());
std::vector<activation> acts;
for (const auto& neuron : som->get_array().get_map())
acts.push_back({neuron.get_x(), neuron.get_y(), neuron.get_activation()});
task.activations.emplace_back(std::move(acts));
}
std::stringstream paths;
paths << "./bins-" << task.file->data_points.begin()->bins.size() << "/";
paths << task.width << "x" << task.height << '-' << task.max_epochs << '/';
std::string shape_name = shape_names[static_cast<int>(task.shape)];
blt::string::replaceAll(shape_name, " ", "-");
paths << shape_name << '/';
std::string init_name = init_names[static_cast<int>(task.init)];
blt::string::replaceAll(init_name, " ", "-");
paths << init_name << '-' << task.initial_learn_rate << '/';
auto path = paths.str();
std::filesystem::create_directories(path);
std::vector<Scalar> average_topological_errors;
std::vector<Scalar> average_quantization_errors;
std::vector<activation> average_activations;
average_topological_errors.resize(task.topological_errors.begin()->size());
average_quantization_errors.resize(task.quantization_errors.begin()->size());
average_activations.resize(task.activations.begin()->size());
for (const auto& vec : task.topological_errors)
for (auto [index, v] : blt::enumerate(vec))
average_topological_errors[index] += v;
for (const auto& vec : task.quantization_errors)
for (auto [index, v] : blt::enumerate(vec))
average_quantization_errors[index] += v;
for (const auto& vec : task.activations)
for (auto [index, v] : blt::enumerate(vec))
average_activations[index].act += v.act;
for (auto& v : average_topological_errors)
v /= static_cast<Scalar>(runs);
for (auto& v : average_quantization_errors)
v /= static_cast<Scalar>(runs);
for (auto& v : average_activations)
v.act /= static_cast<Scalar>(runs);
auto f = matplot::figure();
f->tiledlayout(2, 1);
auto axis = f->add_axes();
axis->hold(true);
axis->plot(matplot::linspace(0, static_cast<double>(task.max_epochs)), average_topological_errors)->display_name("Topological Error");
axis->title("Error");
axis->xlabel("Epoch");
axis->ylabel("Error");
axis->grid(true);
axis->plot(matplot::linspace(0, static_cast<double>(task.max_epochs)), average_quantization_errors)->display_name("Quantization Error");
f->title("Topological and Quantization Errors, " + std::to_string(runs) + " Runs");
f->save((path + "errors_plot.eps"), "postscript");
f->save((path + "errors_plot.tex"), "epslatex");
f->save((path + "errors_plot.png"), "png");
BLT_INFO("Task '%s' Complete", path.c_str());
} while (true);
});
}
while (!threads.empty())
{
if (threads.back().joinable())
{
threads.back().join();
threads.pop_back();
}
}
}
void action_convert(const std::vector<std::string>& argv_vector)

View File

@ -225,9 +225,15 @@ namespace assign3
ImPlot::EndPlot();
}
ImPlot::SetNextAxesLimits(0, max_epochs, 0, 1, ImPlotCond_Once);
if (ImPlot::BeginPlot("Error"))
if (ImPlot::BeginPlot("TError"))
{
ImPlot::PlotLine("##error", som->get_topological_errors().data(), static_cast<int>(som->get_topological_errors().size()));
ImPlot::PlotLine("##Terror", som->get_topological_errors().data(), static_cast<int>(som->get_topological_errors().size()));
ImPlot::EndPlot();
}
ImPlot::SetNextAxesLimits(0, max_epochs, 0, static_cast<int>(current_data_file.data_points.size()), ImPlotCond_Once);
if (ImPlot::BeginPlot("QError"))
{
ImPlot::PlotLine("##Qerror", som->get_quantization_errors().data(), static_cast<int>(som->get_quantization_errors().size()));
ImPlot::EndPlot();
}
}

View File

@ -34,7 +34,7 @@ namespace assign3
break;
case init_t::RANDOM_DATA:
{
static std::vector<Scalar> min_values, max_values;
static thread_local std::vector<Scalar> min_values, max_values;
min_values.clear();
max_values.clear();

View File

@ -22,6 +22,7 @@
#include <blt/iterator/enumerate.h>
#include <blt/std/logging.h>
#include <cstring>
#include "blt/iterator/zip.h"
namespace assign3
{
@ -34,6 +35,7 @@ namespace assign3
for (auto& v : array.get_map())
v.randomize(std::random_device{}(), init, normalize, file);
topological_errors.push_back(topological_error());
quantization_errors.push_back(quantization_error());
}
void som_t::train_epoch(Scalar initial_learn_rate)
@ -66,6 +68,7 @@ namespace assign3
}
current_epoch++;
topological_errors.push_back(topological_error());
quantization_errors.push_back(quantization_error());
}
blt::size_t som_t::get_closest_neuron(const std::vector<Scalar>& data)
@ -222,5 +225,49 @@ namespace assign3
out << i << ',' << v << '\n';
}
void som_t::write_quantization_errors(std::ostream& out)
{
out << "epoch,error\n";
for (auto [i, v] : blt::enumerate(quantization_errors))
out << i << ',' << v << '\n';
}
void som_t::write_all_errors(std::ostream& out)
{
out << "epoch,topology error,quantization error\n";
for (auto [i, v] : blt::in_pairs(topological_errors, quantization_errors).enumerate())
{
auto [t, q] = v;
out << i << ',' << t << ',' << q << '\n';
}
}
Scalar som_t::quantization_error()
{
Scalar incorrect = 0;
for (const auto& point : file.data_points)
{
const auto& nearest = array.get_map()[get_closest_neuron(point.bins)];
bool is_neural = nearest.get_activation() > -quantization_distance && nearest.get_activation() < quantization_distance;
if (is_neural)
{
incorrect++;
continue;
}
bool is_bad = nearest.get_activation() <= -quantization_distance;
bool is_good = nearest.get_activation() >= quantization_distance;
if ((is_bad && point.is_bad) || (is_good && !point.is_bad))
continue;
incorrect++;
}
return incorrect;
}
}