Skip to content

math

Abstract

math.hpp contains functions for mathematical and statistical calculations.
math.hpp は数学・統計計算用の関数を収録します.

Header file

namespace sstd{
    float  round2even(float n);
    double round2even(double n);

    float  round2odd(float n);
    double round2odd(double n);

    template<typename T> T sum(const std::vector<T>& rhs);
    template<typename T> T sum(const std::vector<T>& rhs, uint a, uint b);
    template<class Itr> typename std::iterator_traits<Itr>::value_type sum(const Itr first, const Itr last);

    // using Pairwise summation algorithm.
    float  sum    (const std::vector<float>::iterator first, const std::vector<float>::iterator last);
    float  sum    (const std::vector<float>& rhs, uint a, uint b); // 配列の a 番目から b 番目までの合計. sum of the a th to b th of array.
    float  sum    (const std::vector<float>& rhs);
    float  sum_abs(const std::vector<float>& rhs);
    float  ave    (const std::vector<float>& rhs); // 平均値: average
    float  med    (      std::vector<float>  rhs); // 中央値: median // copy rhs // If rhs.size () is even, average of the two median values is returned.
//  float  mod    (const std::vector<float>& rhs); // 最頻値: mode
    float  var    (const std::vector<float>& rhs); // 不偏分散/標本分散 (variance): u^2 = (1/(n-1))*Σ(x_i-μ)^2
    float  var_p  (const std::vector<float>& rhs); // 母分散 (variance population): σ^2 = (1/n)*Σ(x_i-μ)^2
    float  stdev  (const std::vector<float>& rhs); // 標本標準偏差 (sample standard deviation): u = SQRT( (1/(n-1))*Σ(x_i-μ)^2 )
    float  stdev_p(const std::vector<float>& rhs); // 標準偏差 (standard deviation): σ = SQRT( (1/n)*Σ(x_i-μ)^2 )

    double sum    (const std::vector<double>::iterator first, const std::vector<double>::iterator last);
    double sum    (const std::vector<double>& rhs, uint a, uint b); // 配列の a 番目から b 番目までの合計. sum of the a th to b th of array.
    double sum    (const std::vector<double>& rhs);
    double sum_abs(const std::vector<double>& rhs);
    double ave    (const std::vector<double>& rhs); // 平均値: average
    double med    (      std::vector<double>  rhs); // 中央値: median // copy rhs // If rhs.size () is even, average of the two median values is returned.
//  double mod    (const std::vector<double>& rhs); // 最頻値: mode
    double var    (const std::vector<double>& rhs); // 不偏分散/標本分散 (variance): u^2 = (1/(n-1))*Σ(x_i-μ)^2
    double var_p  (const std::vector<double>& rhs); // 母分散 (variance population): σ^2 = (1/n)*Σ(x_i-μ)^2
    double stdev  (const std::vector<double>& rhs); // 標本標準偏差 (sample standard deviation): u = SQRT( (1/(n-1))*Σ(x_i-μ)^2 )
    double stdev_p(const std::vector<double>& rhs); // 標準偏差 (standard deviation): σ = SQRT( (1/n)*Σ(x_i-μ)^2 )

    // K: using Kahan summation algorithm
    float  sumK    (const std::vector<float>& rhs, uint a, uint b); // 配列の a 番目から b 番目までの合計. sum of the a th to b th of array.
    float  sumK    (const std::vector<float>& rhs);
    float  sumK_abs(const std::vector<float>& rhs);
    float  aveK    (const std::vector<float>& rhs);           // 平均値: average
    float  aveK    (const std::vector<float>& rhs, uint num); // 平均値: average in the first num elements.
    float  varK    (const std::vector<float>& rhs); // 不偏分散/標本分散 (variance): u^2 = (1/(n-1))*Σ(x_i-μ)^2
    float  varK_p  (const std::vector<float>& rhs); // 母分散 (variance population): σ^2 = (1/n)*Σ(x_i-μ)^2
    float  stdevK  (const std::vector<float>& rhs); // 標本標準偏差 (sample standard deviation): u = SQRT( (1/(n-1))*Σ(x_i-μ)^2 )
    float  stdevK_p(const std::vector<float>& rhs); // 標準偏差 (standard deviation): σ = SQRT( (1/n)*Σ(x_i-μ)^2 )

    double sumK    (const std::vector<double>& rhs);
    double sumK    (const std::vector<double>& rhs, uint a, uint b); // 配列の a 番目から b 番目までの合計. sum of the a th to b th of array.
    double sumK_abs(const std::vector<double>& rhs);
    double aveK    (const std::vector<double>& rhs);           // 平均値: average
    double aveK    (const std::vector<double>& rhs, uint num); // 平均値: average in the first num elements.
    double varK    (const std::vector<double>& rhs); // 不偏分散/標本分散 (variance): u^2 = (1/(n-1))*Σ(x_i-μ)^2
    double varK_p  (const std::vector<double>& rhs); // 母分散 (variance population): σ^2 = (1/n)*Σ(x_i-μ)^2
    double stdevK  (const std::vector<double>& rhs); // 標本標準偏差 (sample standard deviation): u = SQRT( (1/(n-1))*Σ(x_i-μ)^2 )
    double stdevK_p(const std::vector<double>& rhs); // 標準偏差 (standard deviation): σ = SQRT( (1/n)*Σ(x_i-μ)^2 )

    std::vector<uint64> prime(uint64 rhs);                                  // get a list of prime number under rhs.
    struct fact{
        uint64 prime;
        uint64 num;
    };
    std::vector<struct fact> factor(uint64 rhs);                            // get a list of prime factorization
    std::vector<uint64> divisor(const std::vector<struct sstd::fact>& rhs); // get a list of all divisors
    std::vector<uint64> divisor(uint64 rhs);                                // get a list of all of the divisors.

    uint8  pow(const uint8 & base, const uint8 & exp);
    uint16 pow(const uint16& base, const uint16& exp);
    uint32 pow(const uint32& base, const uint32& exp);
    uint64 pow(const uint64& base, const uint64& exp);
     float pow(const  float& base, const  float& exp);
    double pow(const double& base, const double& exp);

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    template<typename T> inline T min    (const std::vector<T>& rhs);
    template<typename T> inline T min_abs(const std::vector<T>& rhs);
    template<typename T> inline T max    (const std::vector<T>& rhs);
    template<typename T> inline T max_abs(const std::vector<T>& rhs);

    template<typename T> inline T min    (const sstd::mat_c<T>& rhs);
    template<typename T> inline T min_abs(const sstd::mat_c<T>& rhs);
    template<typename T> inline T max    (const sstd::mat_c<T>& rhs);
    template<typename T> inline T max_abs(const sstd::mat_c<T>& rhs);

    template<typename T> inline T min    (const sstd::mat_r<T>& rhs);
    template<typename T> inline T min_abs(const sstd::mat_r<T>& rhs);
    template<typename T> inline T max    (const sstd::mat_r<T>& rhs);
    template<typename T> inline T max_abs(const sstd::mat_r<T>& rhs);

    template<typename T> inline T min(T&& lhs, T&& rhs);
    template<typename T> inline T min(T&& head1, T&& head2, T&& tail);
    template<typename Head, typename... Tail>
    inline Head min(Head&& head1, Head&& head2, Tail&&... tail);

    template<typename T> inline T max(T&& lhs, T&& rhs);
    template<typename T> inline T max(T&& head1, T&& head2, T&& tail);
    template<typename Head, typename... Tail>
    inline Head max(Head&& head1, Head&& head2, Tail&&... tail);

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    template<typename T> uint argmin    (const std::vector<T>& rhs);
    template<typename T> uint argmin_abs(const std::vector<T>& rhs);
    template<typename T> uint argmax    (const std::vector<T>& rhs);
    template<typename T> uint argmax_abs(const std::vector<T>& rhs);

    template<typename T> uint argmin    (const sstd::mat_c<T>& rhs);
    template<typename T> uint argmin_abs(const sstd::mat_c<T>& rhs);
    template<typename T> uint argmax    (const sstd::mat_c<T>& rhs);
    template<typename T> uint argmax_abs(const sstd::mat_c<T>& rhs);

    template<typename T> uint argmin    (const sstd::mat_r<T>& rhs);
    template<typename T> uint argmin_abs(const sstd::mat_r<T>& rhs);
    template<typename T> uint argmax    (const sstd::mat_r<T>& rhs);
    template<typename T> uint argmax_abs(const sstd::mat_r<T>& rhs);
    /*
    // TODO: argmin
    // TODO: argmax

    template<typename T> std::tuple<uint,uint> argminXY    (const sstd::mat_c<T>& rhs);
    template<typename T> std::tuple<uint,uint> argminXY_abs(const sstd::mat_c<T>& rhs);
    template<typename T> std::tuple<uint,uint> argmaxXY    (const sstd::mat_c<T>& rhs);
    template<typename T> std::tuple<uint,uint> argmaxXY_abs(const sstd::mat_c<T>& rhs);

    template<typename T> std::tuple<uint,uint> argminXY    (const sstd::mat_r<T>& rhs);
    template<typename T> std::tuple<uint,uint> argminXY_abs(const sstd::mat_r<T>& rhs);
    template<typename T> std::tuple<uint,uint> argmaxXY    (const sstd::mat_r<T>& rhs);
    template<typename T> std::tuple<uint,uint> argmaxXY_abs(const sstd::mat_r<T>& rhs);
    //*/
    //-----------------------------------------------------------------------------------------------------------------------------------------------
    // binary search

    template<typename T> T       nearest_down(const std::vector<T>& v, const T& value);
    template<typename T> T       nearest_up  (const std::vector<T>& v, const T& value);
    template<typename T> uint argnearest_down(const std::vector<T>& v, const T& value);
    template<typename T> uint argnearest_up  (const std::vector<T>& v, const T& value);

    //-----------------------------------------------------------------------------------------------------------------------------------------------
    // sort

    template <typename T> inline void           sort     (      std::vector<T>&  rhs   ){                            std::sort(rhs.begin(), rhs.end());             }                    // Ascending: 昇順: 0, 1, 2, ...
    template <typename T> inline std::vector<T> sorted   (const std::vector<T>&  rhs_in){ std::vector<T> rhs=rhs_in; std::sort(rhs.begin(), rhs.end()); return rhs; }                    // Ascending: 昇順: 0, 1, 2, ...
    template <typename T> inline std::vector<T> sorted   (      std::vector<T>&& rhs   ){                            std::sort(rhs.begin(), rhs.end()); return rhs; }                    // Ascending: 昇順: 0, 1, 2, ...
    template <typename T> inline void           sort_gr  (      std::vector<T>&  rhs   ){                            std::sort(rhs.begin(), rhs.end(), std::greater<T>());             } // Descending: 降順: 9, 8, 7, ...
    template <typename T> inline std::vector<T> sorted_gr(const std::vector<T>&  rhs_in){ std::vector<T> rhs=rhs_in; std::sort(rhs.begin(), rhs.end(), std::greater<T>()); return rhs; } // Descending: 降順: 9, 8, 7, ...
    template <typename T> inline std::vector<T> sorted_gr(      std::vector<T>&& rhs   ){                            std::sort(rhs.begin(), rhs.end(), std::greater<T>()); return rhs; } // Descending: 降順: 9, 8, 7, ...

    //-----------------------------------------------------------------------------------------------------------------------------------------------
    // sort for multiple vector

    template<typename Head, typename... Tail> inline void sort   (Head&& head, Tail&&... tail); // Ascending: 昇順: 0, 1, 2, ...
    template<typename Head, typename... Tail> inline void sort_gr(Head&& head, Tail&&... tail); // Descending: 降順: 9, 8, 7, ...

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    template <typename T> std::vector<T> nonzero(const std::vector<T>& rhs);
//  template <typename T> void padding (std::vector<T>& vecLhs, std::vector<T>& vecRhs); // <--> sstd::suppress();
//  template <typename T> void suppress(std::vector<T>& vecLhs, std::vector<T>& vecRhs); // <--> sstd::padding(); or zfill
    template <typename... Args> void suppress(Args&... args);
}

Description

Numerical calculation

Function name Description
round2even()
round2odd()
sum()
sum_abs()
ave()
med()
var()
var_p()
stdev()
stdev_p()
sumK()
sumK_abs()
aveK()
varK()
varK_p()
stdevK()
stdevK_p()
pow()

prime number calculation

Function name Description
prime()
factor()
divisor()
Function name Description
min() returns minimum value of given arg(s). min() can specifies multiple args while args have the same type and is defined < operator.
与えられた値の内,最も小さい値を返します.同一型で operator < が定義されている型であれば,複数の引数を指定できます.
min_abs()
max() returns minimum value of given arg(s). min() can specifies multiple args while args have the same type and is defined < operator.
与えられた値の内,最も大きい値を返します.同一型で operator < が定義されている型であれば,複数の引数を指定できます.
max_abs()
argmin()
argmin_abs()
argmax()
argmax_abs()
nearest_down()
nearest_up()
argnearest_down()
argnearest_up()

sort

Function name Description
sort() sorts arg(s) value directly in ascending order. When multiple std::vector<T>s are specified to arg, all std::vector<T>s will be sorted according to the 1st arg. There is no limit to the number or type of std::vector<T> specified in the argument.
引数の値を直接ソートする.値は昇順にソートされる.引数に std::vector<T> が複数与えられた場合は,第1引数の順序に従って他の引数をソートする.引数に指定する std::vector<T> の数や型に制限はない.
sorted() returns sorted value of arg(s) in ascending order, and arg(s) will not changed.
ソート結果を昇順で返す.引数は変更されない.
sort_gr() sorts arg(s) value directly in descending order. When multiple std::vector<T>s are specified to arg, all std::vector<T>s will be sorted according to the 1st arg. There is no limit to the number or type of std::vector<T> specified in the argument.
引数の値を直接ソートする.値は降順にソートされる.引数に std::vector<T> が複数与えられた場合は,第1引数の順序に従って他の引数をソートする.引数に指定する std::vector<T> の数や型に制限はない.
sorted_gr() returns sorted value of arg(s) in descending order, and arg(s) will not changed.
ソート結果を降順で返す.引数は変更されない.

preprocess

Function name Description
nonzero()
suppress()

Usage

Rounding

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        sstd::printn( sstd::round2even(1.5) );
        sstd::printn( sstd::round2even(2.5) );
    
        sstd::printn( sstd::round2odd(1.5) );
        sstd::printn( sstd::round2odd(2.5) );
    }
    
  • Execution result
    sstd::round2even(1.5) = 2.
    sstd::round2even(2.5) = 2.
    sstd::round2odd(1.5) = 1.
    sstd::round2odd(2.5) = 3.
    

Statistical processing

sum(), sum_abs(), ave(), med(), var(), var_p(), min(), min_abs(), max(), max_abs(), argmin(), argmin_abs(), argmax() and argmax_abs()

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<double> v = {-5,-4,-3,-2,-1,0,1,2,3,4};
        sstd::printn( sstd::sum( v ) );
        sstd::printn( sstd::sum_abs( v ) );
        sstd::printn( sstd::ave( v ) );
        sstd::printn( sstd::med( v ) );
        sstd::printn( sstd::var( v ) );
        sstd::printn( sstd::var_p( v ) );
        sstd::printn( sstd::stdev( v ) );
        sstd::printn( sstd::stdev_p( v ) );
        printf("\n");
    
        sstd::printn( sstd::min( v ) );
        sstd::printn( sstd::min_abs( v ) );
        sstd::printn( sstd::max( v ) );
        sstd::printn( sstd::max_abs( v ) );
        printf("\n");
    
        sstd::printn( sstd::argmin( v ) );
        sstd::printn( sstd::argmin_abs( v ) );
        sstd::printn( sstd::argmax( v ) );
        sstd::printn( sstd::argmax_abs( v ) );
    }
    
  • Execution result
    sstd::sum( v ) = -5.
    sstd::sum_abs( v ) = 25.
    sstd::ave( v ) = -0.5
    sstd::med( v ) = -0.5
    sstd::var( v ) = 9.16667
    sstd::var_p( v ) = 8.25
    sstd::stdev( v ) = 3.02765
    sstd::stdev_p( v ) = 2.87228
    
    sstd::min( v ) = -5.
    sstd::min_abs( v ) = 0.
    sstd::max( v ) = 4.
    sstd::max_abs( v ) = -5.
    
    sstd::argmin( v ) = 0
    sstd::argmin_abs( v ) = 5
    sstd::argmax( v ) = 9
    sstd::argmax_abs( v ) = 0
    

min() and max() for equal or more than three args

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        sstd::printn( sstd::min(-5,-4,-3,-2,-1,0,1,2,3,4) );
        sstd::printn( sstd::max(-5,-4,-3,-2,-1,0,1,2,3,4) );
    }
    
  • Execution result
    sstd::min(-5,-4,-3,-2,-1,0,1,2,3,4) = -5
    sstd::max(-5,-4,-3,-2,-1,0,1,2,3,4) = 4
    

Searching

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<double> v = {-5,-4,-3,-2,-1,0,1,2,3,4};
        sstd::printn( sstd::nearest_down(v, 0.5) );
        sstd::printn( sstd::nearest_up(v, 0.5) );
        printf("\n");
    
        sstd::printn( sstd::argnearest_down(v, 0.5) );
        sstd::printn( sstd::argnearest_up(v, 0.5) );
    }
    
  • Execution result
    sstd::nearest_down(v, 0.5) = 0.
    sstd::nearest_up(v, 0.5) = 1.
    
    sstd::argnearest_down(v, 0.5) = 5
    sstd::argnearest_up(v, 0.5) = 6
    

Sorting

sort(), sort_gr()

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<double> v_base = {-1,-5,2,-3,3,4,-2,0,1,-4};
    
        sstd::sort(v_base);
        sstd::printn(v_base);
    
        sstd::sort_gr(v_base);
        sstd::printn(v_base);
    }
    
  • Execution result
    v_base = [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]
    v_base = [4. 3. 2. 1. 0. -1. -2. -3. -4. -5.]
    

sort() for multiple vector

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<int>         v1_sorting_seed = {1, 3, 5, 2, 4};
        std::vector<std::string> v2              = {"one", "three", "five", "two", "four"};
        std::vector<std::string> v3              = {"1", "3", "5", "2", "4"};
        std::vector<std::string> v4              = {"a", "c", "e", "b", "d"};
        std::vector<std::string> v5              = {"A", "C", "E", "B", "D"};
    
        sstd::sort(v1_sorting_seed, v2, v3, v4, v5);
    
        sstd::printn(v1_sorting_seed);
        sstd::printn(v2);
        sstd::printn(v3);
        sstd::printn(v4);
        sstd::printn(v5);
    }
    
  • Execution result
    v1_sorting_seed = [1 2 3 4 5]
    v2 = ["one" "two" "three" "four" "five"]
    v3 = ["1" "2" "3" "4" "5"]
    v4 = ["a" "b" "c" "d" "e"]
    v5 = ["A" "B" "C" "D" "E"]
    

sort_gr() for multiple vector

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<int>         v1_sorting_seed = {1, 3, 5, 2, 4};
        std::vector<std::string> v2              = {"one", "three", "five", "two", "four"};
        std::vector<std::string> v3              = {"1", "3", "5", "2", "4"};
        std::vector<std::string> v4              = {"a", "c", "e", "b", "d"};
        std::vector<std::string> v5              = {"A", "C", "E", "B", "D"};
    
        sstd::sort_gr(v1_sorting_seed, v2, v3, v4, v5);
    
        sstd::printn(v1_sorting_seed);
        sstd::printn(v2);
        sstd::printn(v3);
        sstd::printn(v4);
        sstd::printn(v5);
    }
    
  • Execution result
    v1_sorting_seed = [5 4 3 2 1]
    v2 = ["five" "four" "three" "two" "one"]
    v3 = ["5" "4" "3" "2" "1"]
    v4 = ["e" "d" "c" "b" "a"]
    v5 = ["E" "D" "C" "B" "A"]
    

sorted(), sorted_gr()

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<double> v_base = {-1,-5,2,-3,3,4,-2,0,1,-4};
    
        sstd::printn( sstd::sorted( v_base )    );
        sstd::printn( sstd::sorted_gr( v_base ) );
        printf("\n");
    
        sstd::printn( v_base );
    }
    
  • Execution result
    sstd::sorted( v_base ) = [-5. -4. -3. -2. -1. 0. 1. 2. 3. 4.]
    sstd::sorted_gr( v_base ) = [4. 3. 2. 1. 0. -1. -2. -3. -4. -5.]
    
    v_base = [-1. -5. 2. -3. 3. 4. -2. 0. 1. -4.]
    

Preprocessing

  • main.cpp
    #include <sstd/sstd.hpp>
    
    int main(){
        std::vector<double> v={1,2,3,0,4};
        sstd::printn( sstd::nonzero(v) );
    
        // suppressing vector to the same length before 0.
        std::vector<double> in1={1,2,3,0,4};
        std::vector<double> in2={1,2,3};
        std::vector<uint>   in3={1,2,3};
        std::vector<double> in4={1,2,3,4};
        sstd::suppress(in1, in2, in3, in4);
    
        sstd::printn( in1 );
        sstd::printn( in2 );
        sstd::printn( in3 );
        sstd::printn( in4 );
    }
    
  • Execution result
    sstd::nonzero(v) = [1. 2. 3.]
    in1 = [1. 2. 3.]
    in2 = [1. 2. 3.]
    in3 = [1 2 3]
    in4 = [1. 2. 3.]
    

Implementation