diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..567609b1234a9b8806c5a05da6c866e480aa148d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..7b4090919146c8fd3232aaa0fe726824f16f8d97 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/docopt.cpp"] + path = external/docopt.cpp + url = https://github.com/docopt/docopt.cpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 13bf3d0861ecf4db417b10e72903b029397c125f..2e114c9455965d5ca0248fdcd02d1c8e42a1e56d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,35 @@ cmake_minimum_required(VERSION 3.17) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + project(librstat VERSION 1.0 LANGUAGES CXX) add_library(rstat SHARED src/RunningStatistics.cpp) +add_library(rstatStatic STATIC src/RunningStatistics.cpp) + +add_subdirectory(external/docopt.cpp) + +add_executable(rstatExe src/rstat.cpp) find_package(GSL 2.4 REQUIRED) +#find_package(docopt COMPONENTS CXX REQUIRED) -target_include_directories(rstat PRIVATE include) +target_include_directories(rstat PUBLIC include) target_link_libraries(rstat GSL::gsl GSL::gslcblas) +target_link_libraries(rstatExe rstat docopt) + +target_include_directories(rstatStatic PRIVATE include) +target_link_libraries(rstatStatic GSL::gsl GSL::gslcblas) + set_target_properties(rstat PROPERTIES PUBLIC_HEADER include/RunningStatistics.hpp) +set_target_properties(rstatStatic PROPERTIES PUBLIC_HEADER include/RunningStatistics.hpp) +set_target_properties(rstatStatic PROPERTIES OUTPUT_NAME rstat) +set_target_properties(rstatExe PROPERTIES OUTPUT_NAME rstat) include(GNUInstallDirs) -install(TARGETS rstat +install(TARGETS rstat rstatStatic rstatExe LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/external/docopt.cpp b/external/docopt.cpp new file mode 160000 index 0000000000000000000000000000000000000000..6f5de76970be94a6f1e4556d1716593100e285d2 --- /dev/null +++ b/external/docopt.cpp @@ -0,0 +1 @@ +Subproject commit 6f5de76970be94a6f1e4556d1716593100e285d2 diff --git a/src/RunningStatistics.cpp b/src/RunningStatistics.cpp index a03970458f9dc69ddba5d846155dd927346f9948..ee50413845618a78e56734d1abf17e662e335f83 100644 --- a/src/RunningStatistics.cpp +++ b/src/RunningStatistics.cpp @@ -20,7 +20,7 @@ #include <gsl/gsl_rstat.h> -#include "RunningStatistics.hpp" +#include <RunningStatistics.hpp> RunningStatistics::RunningStatistics() { diff --git a/src/rstat.cpp b/src/rstat.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9dfa486b10273a840f260f78efd53491f696ae3b --- /dev/null +++ b/src/rstat.cpp @@ -0,0 +1,64 @@ +#include <iostream> +#include <iomanip> +#include <fstream> +#include <cstdlib> +#include <string> + +#include "RunningStatistics.hpp" + +//#define DOCOPT_HEADER_ONLY +#include <docopt.h> + +static const char USAGE[] = +R"(Usage: rstat [options] FILE + +Options: + -m, --mean print mean + -o, --stddev-mean print standard deviation of mean + -s, --stddev print standard deviation + -v, --variance print variance + -n, --numsamples print number of samples + --min print minimum + --max print maximum + --precision=<digits> number of digits to print [default: 5] +)"; + +int main(int argc, char** argv) { + std::map<std::string, docopt::value> args = docopt::docopt(USAGE, + { argv + 1, argv + argc }, true, "rstat 0.1"); + + std::string const filename = args["FILE"].asString() == "-"? "/dev/stdin" : args["FILE"].asString(); + std::ifstream input(filename); + + auto digits = args["--precision"].asLong(); + + RunningStatistics statistics; + + for (double v; input >> v;) + { + statistics.add(v); + } + + if (auto a = args["--numsamples"]; a && a.asBool()) + std::cout << "samples: " << std::setw(digits) << statistics.n() << std::endl; + + if (auto a = args["--mean"]; a && a.asBool()) + std::cout << "mean: " << std::setw(digits) << statistics.mean() << std::endl; + + if (auto a = args["--stddev-mean"]; a && a.asBool()) + std::cout << "std. dev. mean: " << std::setw(digits) << statistics.std_dev_mean() << std::endl; + + if (auto a = args["--stddev"]; a && a.asBool()) + std::cout << "std. dev.: " << std::setw(digits) << statistics.std_dev() << std::endl; + + if (auto a = args["--variance"]; a && a.asBool()) + std::cout << "variance: " << std::setw(digits) << statistics.variance() << std::endl; + + if (auto a = args["--min"]; a && a.asBool()) + std::cout << "minimum: " << std::setw(digits) << statistics.min() << std::endl; + + if (auto a = args["--max"]; a && a.asBool()) + std::cout << "maximum: " << std::setw(digits) << statistics.max() << std::endl; + + return EXIT_SUCCESS; +}