Musa-Cpp-Lib-V2/lib/Base/Basic.h
2025-11-19 22:00:36 -05:00

149 lines
5.4 KiB
C

#pragma once
#include "error-codes.h"
#include "Array.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
int qsort_doubles_comparator_nonnan(const void* a, const void* b);
int qsort_doubles_comparator(const void* a, const void* b);
// @brief Calculates difference and approximate derivative for 1-dimensional data
// Caller needs to supply memory for output and understand that output_length = input_length - 1
PROTOTYPING_API Native_Error* Basic_Difference2 (ArrayView<f64> input, ArrayView<f64>& output);
PROTOTYPING_API Native_Error* Basic_Mean2 (ArrayView<f64> input, f64* mean);
PROTOTYPING_API Native_Error* Basic_QuickSortInPlace (ArrayView<f64> input);
PROTOTYPING_API Native_Error* Basic_Median2 (ArrayView<f64> unsorted_input, f64* median);
PROTOTYPING_API Native_Error* Basic_RescaleInPlace (ArrayView<f64> input, double min, double max);
PROTOTYPING_API Native_Error* Basic_Min2 (ArrayView<f64> input, f64* min_out);
PROTOTYPING_API Native_Error* Basic_Max2 (ArrayView<f64> input, f64* max_out);
double Basic_Max (double input1, double input2);
bool Basic_Is_Positive_Real (f32 input);
bool Basic_Is_Positive_Real (f64 input);
PROTOTYPING_API Native_Error* Basic_Standard_Deviation2 (ArrayView<f64> input, f64* stddev);
PROTOTYPING_API Native_Error* Basic_Variance2 (ArrayView<f64> input, f64* variance);
PROTOTYPING_API Native_Error* Basic_Root_Mean_Squared2 (ArrayView<f64> input, f64* rms);
// Sorts an array from largest to smallest, returning the indices of the sorted array
PROTOTYPING_API Native_Error* Basic_IndexSort2 (ArrayView<f64> input, ArrayView<s64> output);
PROTOTYPING_API Native_Error* Basic_Count_Non_Nan2 (ArrayView<f64> input, s64* non_nan_count);
PROTOTYPING_API Native_Error* Basic_Calculate_Percentile_New (ArrayView<f64> input, f64 percentile, f64* percentile_value_out);
// Does not include sort, because sorting is slow, and we may need to call this multiple
// times with the same sorted input.
PROTOTYPING_API Native_Error* Basic_CalculatePercentileNoSort (ArrayView<f64> input, f64 percentile, f64* percentile_value_out);
PROTOTYPING_API Native_Error* Basic_ReverseArrayInPlace (ArrayView<f64> input);
// Native_Error* Basic_Reverse_Array (double* input, int input_length);
// Native_Error* Basic_Reverse_Array (int* input, int input_length);
// Switches from row-order to column-order or vice-versa. #NOTE: you must know what the order
// and dimensions of the data are to begin with!!
PROTOTYPING_API Native_Error* Basic_2DArrayInvertMemoryOrder (ArrayView<f64> input, s64 first_dimension, s64 second_dimension, ArrayView<f64> output);
// In-place replacement of outliers (using interquartile method, with threshold of 1.5) with nearest values.
PROTOTYPING_API Native_Error* Basic_Replace_Outliers2 (ArrayView<f64> input, f64 outlier_threshold=1.5);
PROTOTYPING_API Native_Error* Basic_Replace_Values_Beyond_Threshold2 (ArrayView<f64> input, f64 low_threshold, f64 high_threshold, f64 replacement_value);
PROTOTYPING_API Native_Error* Basic_Roots_To_Polynomials2 (ArrayView<f64> roots, ArrayView<f64> polynomials);
// #TODO: Basic_Find (returns indices of non-zero elements).
// Need to make this generic, maybe using templates?
// PROTOTYPING_API ArrayView<s32> Basic_Find(ArrayView<f64> x, void* condition);
// Add parameters for peak prominence, height, etc.
// PROTOTYPING_API Native_Error* Basic_Find_Peaks (double* input, int input_length, int* peak_indices, int* peak_count);
struct Complex {
f64 real; f64 imag;
Complex() { real = 0; imag = 0; }
Complex(f64 _real) { real = _real; imag = 0; }
Complex(f64 _real, f64 _imag) { real = _real; imag = _imag; }
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
Complex operator-(const Complex& other) const {
return Complex(real - other.real, imag - other.imag);
}
Complex operator*(const Complex& other) const {
return Complex(
real * other.real - imag * other.imag,
real * other.imag + imag * other.real
);
}
Complex operator/(const Complex& other) const {
f64 denom = other.real * other.real + other.imag * other.imag;
return Complex(
(real * other.real + imag * other.imag) / denom,
(imag * other.real - real * other.imag) / denom
);
}
Complex& operator+=(const Complex& other) {
real += other.real;
imag += other.imag;
return *this;
}
Complex& operator-=(const Complex& other) {
real -= other.real;
imag -= other.imag;
return *this;
}
Complex& operator*=(const Complex& other) {
f64 r = real * other.real - imag * other.imag;
f64 i = real * other.imag + imag * other.real;
real = r;
imag = i;
return *this;
}
Complex& operator/=(const Complex& other) {
f64 denom = other.real * other.real + other.imag * other.imag;
f64 r = (real * other.real + imag * other.imag) / denom;
f64 i = (imag * other.real - real * other.imag) / denom;
real = r;
imag = i;
return *this;
}
bool operator==(const Complex& other) const {
return real == other.real && imag == other.imag;
}
bool operator!=(const Complex& other) const {
return !(*this == other);
}
};
struct Complex32 { f32 real; f32 imag; };
Complex exponential (Complex cx);
Complex conjugate (Complex cx);
f64 fabs(Complex cx);