diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cdf9b5..d91ef1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,11 @@ target_link_options(gp_image_test PRIVATE -Wall -Wextra -Werror -Wpedantic -Wno- target_link_libraries(gp_image_test BLT_WITH_GRAPHICS) -target_link_libraries(gp_image_test ${CMAKE_SOURCE_DIR}/extern/bindings/target/release/libbindings.so) +if (${BUILD_SHARED_LIBS}) + target_link_libraries(gp_image_test ${CMAKE_SOURCE_DIR}/extern/bindings/target/release/libbindings.so) +else () + target_link_libraries(gp_image_test ${CMAKE_SOURCE_DIR}/extern/bindings/target/release/libbindings.a) +endif () if (${ENABLE_ADDRSAN} MATCHES ON) target_compile_options(gp_image_test PRIVATE -fsanitize=address) diff --git a/extern/bindings/Cargo.toml b/extern/bindings/Cargo.toml index a1e2564..9cf0854 100644 --- a/extern/bindings/Cargo.toml +++ b/extern/bindings/Cargo.toml @@ -4,8 +4,13 @@ version = "0.1.0" edition = "2021" [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "staticlib"] +#crate-type = ["staticlib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] stattest = { git = "https://github.com/Tri11Paragon/stattest" } + +[profile.release] +strip = "debuginfo" +lto = true diff --git a/extern/bindings/src/lib.rs b/extern/bindings/src/lib.rs index b38c55f..f25ed0a 100644 --- a/extern/bindings/src/lib.rs +++ b/extern/bindings/src/lib.rs @@ -4,3 +4,59 @@ pub extern "C" fn test() { println!("Hello"); } + +#[repr(C)] +#[derive(Default)] +pub struct Bruh { + error: i8, + estimate: f64, + p_value: f64, + + weights: Option>, + weights_len: usize, + weights_capacity: usize, +} + +#[no_mangle] +pub extern "C-unwind" fn willbert(data: *const f64, len: usize) -> Bruh { + use stattest::test::{ShapiroWilkError, ShapiroWilkStatus}; + + let slice = unsafe { std::slice::from_raw_parts(data, len) }; + let result = stattest::test::ShapiroWilkTest::new(slice); + match result { + Ok(results) => { + let (weights, weights_len, weights_capacity) = { + let ptr = results.weights.as_ptr(); + let len = results.weights.len(); + let capacity = results.weights.capacity(); + + std::mem::forget(results.weights); + + (std::ptr::NonNull::new(ptr.cast_mut()), len, capacity) + }; + + Bruh { + error: match results.status { + ShapiroWilkStatus::Ok => 0, + ShapiroWilkStatus::TooMany => 1, + }, + estimate: results.estimate, + p_value: results.p_value, + weights, + weights_capacity, + weights_len, + } + } + Err(error) => { + let error = match error { + ShapiroWilkError::TooFew => -1, + ShapiroWilkError::NoDifference => -2, + ShapiroWilkError::CannotMakeDistribution => -3, + }; + Bruh { + error, + ..Default::default() + } + } + } +} diff --git a/include/extern.h b/include/extern.h new file mode 100644 index 0000000..06f658a --- /dev/null +++ b/include/extern.h @@ -0,0 +1,69 @@ +/* + * + * 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 . + */ + +#ifndef GP_IMAGE_TEST_EXTERN_H +#define GP_IMAGE_TEST_EXTERN_H + +#include + +struct shapiro_wilk_results +{ + blt::i8 error; + double estimate; + double p_value; + double* weights; + blt::size_t weights_len; + blt::size_t weights_capacity; +}; + +extern "C" shapiro_wilk_results willbert(const double* data, blt::size_t len); + +extern "C" void test(); + +class willbruh +{ + private: + shapiro_wilk_results results; + public: + explicit willbruh(const std::vector& data): results(willbert(data.data(), data.size())) + {} + explicit willbruh(const double* data, blt::size_t size): results(willbert(data, size)) + {} + + willbruh(const willbruh& copy) = delete; + willbruh(const willbruh&& move) = delete; + + willbruh& operator=(const willbruh& copy) = delete; + willbruh& operator=(const willbruh&& move) = delete; + + shapiro_wilk_results& get() + { + return results; + } + + shapiro_wilk_results* operator->(){ + return &results; + } + + ~willbruh() + { + free(results.weights); + } +}; + +#endif //GP_IMAGE_TEST_EXTERN_H diff --git a/src/functions.cpp b/src/functions.cpp index 23b38cb..2b8f837 100644 --- a/src/functions.cpp +++ b/src/functions.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #define FUNCTION_COORD() \ int xi = static_cast(x); \ @@ -231,17 +232,48 @@ void f_if(image& img, float x, float y, blt::size_t argc, const image** argv, co img.set(i3, xi, yi); } +double on_data(const double* data, blt::size_t len) +{ + static float NEGATION = -1; + willbruh results(data, len); + switch (results->error) + { + case 0: + return results->estimate; + case 1: + BLT_INFO("Somehow we have sent more than 5000 values!"); + case -1: + case -3: + return 0; + case -2: + // should never consider this a valid solution / punish for having large sections of no difference + return NEGATION; + } +} + float eval_DNF_SW(const image& img) { - std::vector order(width * height); - std::sort(order.begin(), order.end()); + std::vector order(width * height); for (const auto& v : img.getData()) order.push_back(v.magnitude()); + blt::size_t len = 5000; + blt::size_t current_pos = 0; + double total = 0; + while (true) + { + if (order.size() - current_pos < len) + { + len = order.size() - current_pos; + if (len <= 0) + break; + } + total += on_data(order.data() + current_pos, len); + current_pos += len; + } - - return 0; + return static_cast(total); } float eval_DNF_KS(const image& img) diff --git a/src/main.cpp b/src/main.cpp index f3dd49c..daf42c3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,11 +9,11 @@ #include "blt/gfx/renderer/batch_2d_renderer.h" #include "blt/std/assert.h" #include "imgui.h" -#include "shifting.h" #include #include #include #include +#include blt::gfx::matrix_state_manager global_matrices; blt::gfx::resource_manager resources; @@ -21,8 +21,6 @@ blt::gfx::batch_renderer_2d renderer_2d(resources); constexpr blt::i32 MAX_DEPTH = 17; -extern "C" void test(); - struct node; blt::area_allocator node_allocator; @@ -346,8 +344,8 @@ void update(std::int32_t w, std::int32_t h) if (ImGui::Button("Eval")) { - //if (root && root->hasImage()) - //BLT_DEBUG(eval_AMF(root->getImage())); + if (root && root->hasImage()) + BLT_DEBUG(eval_DNF_SW(root->getImage())); } auto lw = 512.0f; @@ -362,7 +360,6 @@ void update(std::int32_t w, std::int32_t h) int main() { - test(); blt::gfx::init(blt::gfx::window_data{"Window of GP test", init, update}.setSyncInterval(1)); global_matrices.cleanup(); resources.cleanup();