diff --git a/CMakeLists.txt b/CMakeLists.txt index a1c2d72..34b744f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.24) project( fstats LANGUAGES Fortran - VERSION 1.2.1 + VERSION 1.2.2 ) # Confgiure everything diff --git a/doc/index.html b/doc/index.html index 000c1c0..0e3ecce 100644 --- a/doc/index.html +++ b/doc/index.html @@ -108,7 +108,7 @@

Modules

Procedures

- +

diff --git a/doc/interface/bootstrap_resampling_routine.html b/doc/interface/bootstrap_resampling_routine.html index ca8832e..d2c1c77 100644 --- a/doc/interface/bootstrap_resampling_routine.html +++ b/doc/interface/bootstrap_resampling_routine.html @@ -74,7 +74,7 @@

bootstrap_resampling_routine
  • 12 statements + title=" 0.7% of total for procedures.">12 statements
  • @@ -153,7 +153,7 @@

    Arguments

    - + real(kind=real64), intent(in), @@ -205,7 +205,7 @@

    Description

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/bootstrap_statistic_routine.html b/doc/interface/bootstrap_statistic_routine.html index 2996269..f1533ab 100644 --- a/doc/interface/bootstrap_statistic_routine.html +++ b/doc/interface/bootstrap_statistic_routine.html @@ -74,7 +74,7 @@

    bootstrap_statistic_routine
  • 12 statements + title=" 0.7% of total for procedures.">12 statements
  • @@ -153,7 +153,7 @@

    Arguments

    - + real(kind=real64), intent(in), @@ -169,7 +169,7 @@

    Arguments

    -

    Return Value real(kind=real64)

    +

    Return Value real(kind=real64)

    The resulting statistic.

    Description

    Defines the signature of a function for computing the desired @@ -191,7 +191,7 @@

    Description

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/box_muller_sample.html b/doc/interface/box_muller_sample.html index 65df087..ed67567 100644 --- a/doc/interface/box_muller_sample.html +++ b/doc/interface/box_muller_sample.html @@ -74,7 +74,7 @@

    box_muller_sample
  • 4 statements + title="

    0.2% of total for procedures.

    Including implementation: 31 statements, 1.8% of total for procedures.">4 statements
  • @@ -262,7 +262,7 @@

    Arguments

    - + integer(kind=int32), intent(in) @@ -301,7 +301,7 @@

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/confidence_interval.html b/doc/interface/confidence_interval.html index 88550af..514d4da 100644 --- a/doc/interface/confidence_interval.html +++ b/doc/interface/confidence_interval.html @@ -74,7 +74,7 @@

    confidence_interval
  • 4 statements + title="

    0.2% of total for procedures.

    Including implementation: 22 statements, 1.3% of total for procedures.">4 statements
  • @@ -174,7 +174,7 @@

    Arguments

    - + class(distribution), intent(in) @@ -190,7 +190,7 @@

    Arguments

    - + real(kind=real64), intent(in) @@ -221,7 +221,7 @@

    Arguments

    - + integer(kind=int32), intent(in) @@ -265,7 +265,7 @@

    Arguments

    - + class(distribution), intent(in) @@ -281,7 +281,7 @@

    Arguments

    - + real(kind=real64), intent(in) @@ -297,7 +297,7 @@

    Arguments

    - + real(kind=real64), intent(in) @@ -336,7 +336,7 @@

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/distribution_function.html b/doc/interface/distribution_function.html index 732ed6e..4ff7e22 100644 --- a/doc/interface/distribution_function.html +++ b/doc/interface/distribution_function.html @@ -74,7 +74,7 @@

    distribution_function
  • 15 statements + title=" 0.9% of total for procedures.">15 statements
  • @@ -168,7 +168,7 @@

    Arguments

    - + real(kind=real64), intent(in) @@ -184,7 +184,7 @@

    Arguments

    -

    Return Value real(kind=real64)

    +

    Return Value real(kind=real64)

    The value of the function.

    Description

    Defines the interface for a probability distribution function.

    @@ -205,7 +205,7 @@

    Description

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/distribution_property.html b/doc/interface/distribution_property.html index 1a6a5cb..608f97e 100644 --- a/doc/interface/distribution_property.html +++ b/doc/interface/distribution_property.html @@ -74,7 +74,7 @@

    distribution_property
  • 15 statements + title=" 0.9% of total for procedures.">15 statements
  • @@ -169,7 +169,7 @@

    Arguments

    -

    Return Value real(kind=real64)

    +

    Return Value real(kind=real64)

    The property value.

    Description

    Computes the value of a distribution property.

    @@ -190,7 +190,7 @@

    Description

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/iteration_update.html b/doc/interface/iteration_update.html index ecc1d5d..37541db 100644 --- a/doc/interface/iteration_update.html +++ b/doc/interface/iteration_update.html @@ -246,7 +246,7 @@

    Arguments

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/interface/pooled_variance.html b/doc/interface/pooled_variance.html new file mode 100644 index 0000000..75bce1e --- /dev/null +++ b/doc/interface/pooled_variance.html @@ -0,0 +1,302 @@ + + + + + + + + + + + + + pooled_variance – FSTATS + + + + + + + + + + + + + + +
    + +
    + +
    +
    +

    pooled_variance + Interface + +

    +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + + +
    +

    public interface pooled_variance

    +

    Computes the pooled estimate of variance.

    +
    + + +

    Module Procedures

    +
    +

    private pure function pooled_variance_1(si, ni) result(rst) +

    +
    +

    Computes the pooled estimate of variance.

    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeIntentOptional AttributesName
    + + real(kind=real64), + intent(in), + dimension(:) + ::si +

    An N-element array containing the estimates for each of the N +variances.

    +
    + + integer(kind=int32), + intent(in), + dimension(size(si)) + ::ni +

    An N-element array containing the number of data points in each +of the data sets used to compute the variances in si.

    +
    + +

    + Return Value + real(kind=real64) +

    +

    The pooled variance.

    + +
    +
    + +
    +

    private pure function pooled_variance_2(x) result(rst) +

    +
    +

    Computes the pooled estimate of variance.

    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + +
    TypeIntentOptional AttributesName
    + + type(array_container), + intent(in), + dimension(:) + ::x +

    An array of arrays of data.

    +
    + +

    + Return Value + real(kind=real64) +

    +

    The pooled variance.

    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    FSTATS was developed by Jason Christopherson
    © 2024 +

    +
    +
    +

    + Documentation generated by + FORD + on 2024-04-19 07:47

    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/interface/regression_function.html b/doc/interface/regression_function.html index 43f71cb..05d32ed 100644 --- a/doc/interface/regression_function.html +++ b/doc/interface/regression_function.html @@ -231,7 +231,7 @@

    Arguments

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/lists/files.html b/doc/lists/files.html index e213cf5..0ffa18c 100644 --- a/doc/lists/files.html +++ b/doc/lists/files.html @@ -123,6 +123,10 @@

    Source Files

    fstats_special_functions.f90 + + + fstats_types.f90 + @@ -140,7 +144,7 @@

    Source Files

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/lists/modules.html b/doc/lists/modules.html index 93c63de..07ef61f 100644 --- a/doc/lists/modules.html +++ b/doc/lists/modules.html @@ -140,7 +140,12 @@

    Modules

    fstats_special_functions.f90 - + + fstats_types + fstats_types.f90 + + + @@ -156,7 +161,7 @@

    Modules

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/lists/procedures.html b/doc/lists/procedures.html index a382b14..de0191c 100644 --- a/doc/lists/procedures.html +++ b/doc/lists/procedures.html @@ -86,6 +86,12 @@

    Procedures

    Interface

    Performs an analysis of variance (ANOVA) on the supplied data set.

    Read more… + + + bartletts_test + fstats_hypothesis + Subroutine +

    Computes Bartlett's test statistic and associated probability.

    Read more… beta @@ -148,16 +154,6 @@

    Procedures

    Function

    Computes statistics for the quality of fit for a regression model.

    - - - coefficient_matrix - fstats_regression - Subroutine -

    Computes the coefficient matrix to the linear -least-squares regression problem of , where - is the coefficient matrix computed here, is -the vector of coefficients to be determined, and is the -vector of measured dependent variables.

    Read more… confidence_interval @@ -184,7 +180,17 @@

    Procedures

    Subroutine

    Computes the covariance matrix where and is computed -by coefficient_matrix.

    Read more… +by design_matrix.

    Read more… + + + design_matrix + fstats_regression + Subroutine +

    Computes the design matrix for the linear +least-squares regression problem of , where + is the matrix computed here, is +the vector of coefficients to be determined, and is the +vector of measured dependent variables.

    Read more… difference @@ -265,6 +271,12 @@

    Procedures

    fstats_regression Subroutine

    Computes the Jacobian matrix for a nonlinear regression problem.

    + + + levenes_test + fstats_hypothesis + Subroutine +

    Computes Levene's test statistic and associated probability.

    Read more… linear_least_squares @@ -298,6 +310,12 @@

    Procedures

    Subroutine

    Performs a nonlinear regression to fit a model using a version of the Levenberg-Marquardt algorithm.

    + + + pooled_variance + fstats_descriptive_statistics + Interface +

    Computes the pooled estimate of variance.

    quantile @@ -372,6 +390,14 @@

    Procedures

    fstats_errors Subroutine

    Reports an underdefined problem error.

    + + + sample_size + fstats_hypothesis + Function +

    Estimates the sample size required to achieve an experiment with the +desired power and significance levels to ascertain the desired +difference in parameter.

    Read more… scaled_random_resample @@ -434,7 +460,7 @@

    Procedures

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/lists/types.html b/doc/lists/types.html index 035443b..7d16e9e 100644 --- a/doc/lists/types.html +++ b/doc/lists/types.html @@ -74,6 +74,13 @@

    Derived Types

    fstats_anova None

    Defines an ANOVA factor result.

    + + + array_container + fstats_types + None +

    Provides a container for a real-valued array. A practical use of +this construct is in the construction of jagged arrays.

    binomial_distribution @@ -177,7 +184,7 @@

    Derived Types

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/module/fstats.html b/doc/module/fstats.html index 5a659e0..d77e1f4 100644 --- a/doc/module/fstats.html +++ b/doc/module/fstats.html @@ -74,7 +74,7 @@

    fstats
  • 81 statements + title=" 2.9% of total for modules and submodules.">85 statements
  • @@ -142,19 +142,19 @@

    Uses

    @@ -189,7 +189,7 @@

    Uses

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/module/fstats_allan.html b/doc/module/fstats_allan.html index ed84b50..b6a845d 100644 --- a/doc/module/fstats_allan.html +++ b/doc/module/fstats_allan.html @@ -74,7 +74,7 @@

    fstats_allan
  • 51 statements + title=" 1.7% of total for modules and submodules.">51 statements
  • @@ -189,7 +189,7 @@

    Arguments

    - + real(kind=real64), intent(in), @@ -220,7 +220,7 @@

    Arguments

    - + class(errors), intent(inout), @@ -273,7 +273,7 @@

    Documentation generated by FORD - on 2024-03-26 07:52

    + on 2024-04-19 07:47


    diff --git a/doc/module/fstats_anova.html b/doc/module/fstats_anova.html index 59a96af..4b198c6 100644 --- a/doc/module/fstats_anova.html +++ b/doc/module/fstats_anova.html @@ -74,7 +74,7 @@

    fstats_anova
  • 201 statements + title=" 6.8% of total for modules and submodules.">199 statements
  • @@ -163,11 +163,12 @@

    Uses

    • @@ -279,7 +280,7 @@

      Arguments

      - + real(kind=real64), intent(in) @@ -323,7 +324,7 @@

      Arguments

      - + real(kind=real64), intent(in) @@ -412,7 +413,7 @@

      Arguments

      - + class(errors), intent(inout), @@ -474,7 +475,7 @@

      Components

      - + real(kind=real64), public @@ -890,7 +891,7 @@

      Components

      Documentation generated by FORD - on 2024-03-26 07:52

      + on 2024-04-19 07:47


      diff --git a/doc/module/fstats_bootstrap.html b/doc/module/fstats_bootstrap.html index 6497349..0289935 100644 --- a/doc/module/fstats_bootstrap.html +++ b/doc/module/fstats_bootstrap.html @@ -74,7 +74,7 @@

      fstats_bootstrap
    • 351 statements + title="11.9% of total for modules and submodules.">351 statements
    • @@ -188,13 +188,13 @@

      Uses

      • @@ -238,7 +238,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -303,7 +303,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -636,7 +636,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -772,7 +772,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -1019,7 +1019,7 @@

        Arguments

        - + real(kind=real64), intent(in) @@ -1350,7 +1350,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -1406,7 +1406,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -1461,7 +1461,7 @@

        Arguments

        Documentation generated by FORD - on 2024-03-26 07:52

        + on 2024-04-19 07:47


        diff --git a/doc/module/fstats_descriptive_statistics.html b/doc/module/fstats_descriptive_statistics.html index 247cc51..a59c647 100644 --- a/doc/module/fstats_descriptive_statistics.html +++ b/doc/module/fstats_descriptive_statistics.html @@ -74,7 +74,7 @@

        fstats_descriptive_statistics
      • 130 statements + title=" 5.6% of total for modules and submodules.">164 statements
      • @@ -113,7 +113,18 @@

        Contents

        - + +
        @@ -156,10 +167,11 @@

        Uses

        @@ -172,6 +184,126 @@

        Uses

        +
        +

        Interfaces

        +
        +
        + +

        public interface pooled_variance +

        +
        +
        +

        Computes the pooled estimate of variance.

        +
        +
          +
        • +

          + private pure function pooled_variance_1(si, ni) result(rst) + +

          +

          Computes the pooled estimate of variance.

          + +

          Arguments

          + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + real(kind=real64), + intent(in), + dimension(:) + ::si +

          An N-element array containing the estimates for each of the N +variances.

          +
          + + integer(kind=int32), + intent(in), + dimension(size(si)) + ::ni +

          An N-element array containing the number of data points in each +of the data sets used to compute the variances in si.

          +
          + +

          + Return Value + real(kind=real64) +

          +

          The pooled variance.

          + +
        • +
        • +

          + private pure function pooled_variance_2(x) result(rst) + +

          +

          Computes the pooled estimate of variance.

          + +

          Arguments

          + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + type(array_container), + intent(in), + dimension(:) + ::x +

          An array of arrays of data.

          +
          + +

          + Return Value + real(kind=real64) +

          +

          The pooled variance.

          + +
        • +
        +
        + +
        +
        @@ -197,7 +329,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -212,7 +344,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -257,7 +389,7 @@

        Arguments

        - + real(kind=real64), intent(in) @@ -302,7 +434,7 @@

        Arguments

        - + real(kind=real64), intent(inout) @@ -349,7 +481,7 @@

        Arguments

        - + real(kind=real64), intent(in) @@ -409,7 +541,7 @@

        Arguments

        - + real(kind=real64), intent(in) @@ -454,7 +586,7 @@

        Arguments

        - + real(kind=real64), intent(inout), @@ -470,7 +602,7 @@

        Arguments

        - + real(kind=real64), intent(in), @@ -517,7 +649,7 @@

        Arguments

        - + real(kind=real64), intent(in) @@ -563,7 +695,7 @@

        Documentation generated by FORD - on 2024-03-26 07:52

        + on 2024-04-19 07:47


        diff --git a/doc/module/fstats_distributions.html b/doc/module/fstats_distributions.html index 8457860..7bf6a1b 100644 --- a/doc/module/fstats_distributions.html +++ b/doc/module/fstats_distributions.html @@ -74,7 +74,7 @@

        fstats_distributions
      • 303 statements + title="11.0% of total for modules and submodules.">323 statements
      • @@ -167,9 +167,9 @@

        Uses

        • @@ -227,7 +227,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -338,7 +338,7 @@

          Components

          - + integer(kind=int32), public @@ -355,7 +355,7 @@

          Components

          - + real(kind=real64), public @@ -407,6 +407,11 @@

          Type-Bound Procedures

          procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + + + procedure, public :: variance => bd_variance @@ -491,6 +496,11 @@

          Type-Bound Procedures

          procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + + + procedure, public :: variance => cs_variance @@ -542,6 +552,11 @@

          Type-Bound Procedures

          pdf ..\..\

          Computes the probability density function.<\p> + + procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + procedure(distribution_property), public, deferred, pass :: variance @@ -645,6 +660,11 @@

          Type-Bound Procedures

          procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + + + procedure, public :: variance => fd_variance @@ -751,6 +771,11 @@

          Type-Bound Procedures

          procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + + + procedure, public :: variance => nd_variance @@ -835,6 +860,11 @@

          Type-Bound Procedures

          procedure, public :: + standardized_variable => dist_std_var + ..\..\

          Computes the standardized variable for the distribution.<\p> + + + procedure, public :: variance => td_variance @@ -865,7 +895,7 @@

          Type-Bound Procedures

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/module/fstats_errors.html b/doc/module/fstats_errors.html index df7db54..ddc2658 100644 --- a/doc/module/fstats_errors.html +++ b/doc/module/fstats_errors.html @@ -74,7 +74,7 @@

          fstats_errors
        • 80 statements + title=" 2.7% of total for modules and submodules.">80 statements
        • @@ -173,8 +173,8 @@

          Uses

          @@ -366,7 +366,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -467,7 +467,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -582,7 +582,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -667,7 +667,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -797,7 +797,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -867,7 +867,7 @@

          Arguments

          - + class(errors), intent(inout) @@ -952,7 +952,7 @@

          Arguments

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/module/fstats_experimental_design.html b/doc/module/fstats_experimental_design.html index 52eb3d1..dcd36d1 100644 --- a/doc/module/fstats_experimental_design.html +++ b/doc/module/fstats_experimental_design.html @@ -74,7 +74,7 @@

          fstats_experimental_design
        • 66 statements + title=" 2.2% of total for modules and submodules.">66 statements
        • @@ -227,7 +227,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -290,7 +290,7 @@

          Arguments

          - + integer(kind=int32), intent(out) @@ -305,7 +305,7 @@

          Arguments

          - + integer(kind=int32), intent(out) @@ -320,7 +320,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -364,7 +364,7 @@

          Arguments

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/module/fstats_helper_routines.html b/doc/module/fstats_helper_routines.html index 6c1fd95..ca93467 100644 --- a/doc/module/fstats_helper_routines.html +++ b/doc/module/fstats_helper_routines.html @@ -189,7 +189,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -235,7 +235,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -281,7 +281,7 @@

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/module/fstats_hypothesis.html b/doc/module/fstats_hypothesis.html index 3a36896..20f7b8a 100644 --- a/doc/module/fstats_hypothesis.html +++ b/doc/module/fstats_hypothesis.html @@ -74,7 +74,7 @@

          fstats_hypothesis
        • 175 statements + title=" 9.1% of total for modules and submodules.">268 statements
        • @@ -127,7 +127,18 @@

          Interfaces

          - + +
          + bartletts_test f_test + levenes_test t_test_equal_variance t_test_paired t_test_unequal_variance @@ -164,12 +177,13 @@

          Uses

          @@ -218,7 +232,7 @@

          Arguments

          - + class(distribution), intent(in) @@ -234,7 +248,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -265,7 +279,7 @@

          Arguments

          - + integer(kind=int32), intent(in) @@ -308,7 +322,7 @@

          Arguments

          - + class(distribution), intent(in) @@ -324,7 +338,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -340,7 +354,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -371,9 +385,195 @@

          +
          +

          Functions

          +
          +

          public pure function sample_size(dist, var, delta, bet, alpha) result(rst) +

          +
          + +

          Estimates the sample size required to achieve an experiment with the +desired power and significance levels to ascertain the desired +difference in parameter.

          Read more… + +

          Arguments

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + class(distribution), + intent(in) + + ::dist +

          The distribution to utilize as a measure.

          +
          + + real(kind=real64), + intent(in) + + ::var +

          An estimate of the population variance.

          +
          + + real(kind=real64), + intent(in) + + ::delta +

          The parameter difference that is desired.

          +
          + + real(kind=real64), + intent(in),optional + + ::bet +

          The desired power level. The default for this value is 0.2, for a +power of 80%.

          +
          + + real(kind=real64), + intent(in),optional + + ::alpha +

          The desired significance level. The default for this value is 0.05 +for a confidence level of 95%.

          +
          + +

          + Return Value + real(kind=real64) +

          +

          The minimum sample size requried to achieve the desired experimental +outcome.

          + +
          +
          + +
          +

          Subroutines

          +
          +

          public subroutine bartletts_test(x, stat, p) +

          +
          + +

          Computes Bartlett's test statistic and associated probability.

          Read more… + +

          Arguments

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + type(array_container), + intent(in), + dimension(:) + ::x +

          The arrays of data to analyze.

          +
          + + real(kind=real64), + intent(out) + + ::stat +

          The Bartlett's test statistic.

          +
          + + real(kind=real64), + intent(out) + + ::p +

          The probability value that the variances of each data set are +equivalent. A low p-value, less than some significance level, +indicates a non-equivalance of variances.

          +
          + + +
          +
          +

          public subroutine f_test(x1, x2, stat, p, dof1, dof2)

          @@ -440,7 +640,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -457,7 +657,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -472,7 +672,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -489,6 +689,93 @@

          Arguments

          +
          +

          + +
          +

          public subroutine levenes_test(x, stat, p, err) +

          +
          + +

          Computes Levene's test statistic and associated probability.

          Read more… + +

          Arguments

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + type(array_container), + intent(in), + dimension(:) + ::x +

          The arrays of data to analyze.

          +
          + + real(kind=real64), + intent(out) + + ::stat +

          The Bartlett's test statistic.

          +
          + + real(kind=real64), + intent(out) + + ::p +

          The probability value that the variances of each data set are +equivalent. A low p-value, less than some significance level, +indicates a non-equivalance of variances.

          +
          + + class(errors), + intent(inout),optional, + target + ::err + +
          + +
          @@ -558,7 +845,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -575,7 +862,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -660,7 +947,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -677,7 +964,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -692,7 +979,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -782,7 +1069,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -799,7 +1086,7 @@

          Arguments

          - + real(kind=real64), intent(out) @@ -839,7 +1126,7 @@

          Arguments

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/module/fstats_regression.html b/doc/module/fstats_regression.html index 773cfa0..1036313 100644 --- a/doc/module/fstats_regression.html +++ b/doc/module/fstats_regression.html @@ -74,7 +74,7 @@

          fstats_regression
        • 861 statements + title="29.3% of total for modules and submodules.">861 statements
        • @@ -177,8 +177,8 @@

          Subroutines

          - coefficient_matrix covariance_matrix + design_matrix jacobian linear_least_squares nonlinear_least_squares @@ -207,14 +207,14 @@

          Uses

          • @@ -1137,7 +1137,7 @@

            Arguments

            - + integer(kind=int32), intent(in) @@ -1152,7 +1152,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -1184,7 +1184,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -1265,7 +1265,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -1297,7 +1297,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -1349,7 +1349,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -1364,7 +1364,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -1409,7 +1409,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -1441,7 +1441,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -1477,15 +1477,13 @@

            Subroutines

            -

            public subroutine coefficient_matrix(order, intercept, x, c, err) +

            public subroutine covariance_matrix(x, c, err)

            -

            Computes the coefficient matrix to the linear -least-squares regression problem of , where - is the coefficient matrix computed here, is -the vector of coefficients to be determined, and is the -vector of measured dependent variables.

            Read more… +

            Computes the covariance matrix where + and is computed +by design_matrix.

            Read more…

            Arguments

            @@ -1500,39 +1498,7 @@

            Arguments

            - - - - - - - - - - - - - - - - @@ -1540,15 +1506,15 @@

            Arguments

            - + @@ -1558,14 +1524,12 @@

            Arguments

            @@ -1578,8 +1542,10 @@

            Arguments

            A mechanism for communicating errors and warnings to the caller. Possible warning and error codes are as follows. - FS_NO_ERROR: No errors encountered. -- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. -- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.

            +- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not + sized correctly. +- FS_MEMORY_ERROR: Occurs if there is a memory allocation + error.

            @@ -1590,13 +1556,15 @@

            Arguments

            -

            public subroutine covariance_matrix(x, c, err) +

            public subroutine design_matrix(order, intercept, x, c, err)

            -

            Computes the covariance matrix where - and is computed -by coefficient_matrix.

            Read more… +

            Computes the design matrix for the linear +least-squares regression problem of , where + is the matrix computed here, is +the vector of coefficients to be determined, and is the +vector of measured dependent variables.

            Read more…

            Arguments

            - - integer(kind=int32), - intent(in) - - ::order -

            The order of the equation to fit. This value must be -at least one (linear equation), but can be higher as desired.

            -
            - - logical, - intent(in) - - ::intercept -

            Set to true if the intercept is being computed -as part of the regression; else, false.

            -
            - + real(kind=real64), intent(in) ::x(:)x(:,:) -

            An N-element array containing the independent variable -measurement points.

            +

            An M-by-N matrix containing the formatted independent data + matrix as computed by design_matrix.

            - + real(kind=real64), intent(out) :: c(:,:) -

            An N-by-K matrix where the results will be written. K -must equal order + 1 in the event intercept is true; -however, if intercept is false, K must equal order.

            +

            The N-by-N covariance matrix.

            - + class(errors), intent(inout),
            @@ -1611,7 +1579,39 @@

            Arguments

            + + + + + + + + + + + + + + + + @@ -1619,15 +1619,15 @@

            Arguments

            - + @@ -1637,12 +1637,14 @@

            Arguments

            @@ -1655,10 +1657,8 @@

            Arguments

            A mechanism for communicating errors and warnings to the caller. Possible warning and error codes are as follows. - FS_NO_ERROR: No errors encountered. -- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not - sized correctly. -- FS_MEMORY_ERROR: Occurs if there is a memory allocation - error.

            +- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. +- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.

            @@ -1815,7 +1815,7 @@

            Arguments

            @@ -1894,7 +1894,7 @@

            Arguments

            @@ -1910,7 +1910,7 @@

            Arguments

            @@ -2006,7 +2006,7 @@

            Arguments

            @@ -2069,7 +2069,7 @@

            Arguments

            @@ -2084,7 +2084,7 @@

            Arguments

            @@ -2296,7 +2296,7 @@

            Arguments

            @@ -2348,7 +2348,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/module/fstats_sampling.html b/doc/module/fstats_sampling.html index a231bf8..958c8fc 100644 --- a/doc/module/fstats_sampling.html +++ b/doc/module/fstats_sampling.html @@ -74,7 +74,7 @@

            fstats_sampling
          • 78 statements + title=" 2.7% of total for modules and submodules.">78 statements
          • @@ -161,8 +161,8 @@

            Uses

          • @@ -367,7 +367,7 @@

            Arguments

            @@ -444,7 +444,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/module/fstats_smoothing.html b/doc/module/fstats_smoothing.html index bf608f1..8a869c8 100644 --- a/doc/module/fstats_smoothing.html +++ b/doc/module/fstats_smoothing.html @@ -74,7 +74,7 @@

            fstats_smoothing
          • 215 statements + title=" 7.3% of total for modules and submodules.">215 statements
          • @@ -152,8 +152,8 @@

            Uses

          • @@ -194,7 +194,7 @@

            Arguments

            @@ -322,7 +322,7 @@

            Arguments

            @@ -367,7 +367,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/module/fstats_special_functions.html b/doc/module/fstats_special_functions.html index 2254b59..15667f4 100644 --- a/doc/module/fstats_special_functions.html +++ b/doc/module/fstats_special_functions.html @@ -74,7 +74,7 @@

            fstats_special_functions
          • 169 statements + title=" 5.7% of total for modules and submodules.">169 statements
          • @@ -194,7 +194,7 @@

            Arguments

          • @@ -209,7 +209,7 @@

            Arguments

            @@ -254,7 +254,7 @@

            Arguments

            @@ -299,7 +299,7 @@

            Arguments

            @@ -314,7 +314,7 @@

            Arguments

            @@ -329,7 +329,7 @@

            Arguments

            @@ -374,7 +374,7 @@

            Arguments

            @@ -389,7 +389,7 @@

            Arguments

            @@ -434,7 +434,7 @@

            Arguments

            @@ -449,7 +449,7 @@

            Arguments

            @@ -494,7 +494,7 @@

            Arguments

            @@ -509,7 +509,7 @@

            Arguments

            @@ -524,7 +524,7 @@

            Arguments

            @@ -570,7 +570,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/module/fstats_types.html b/doc/module/fstats_types.html new file mode 100644 index 0000000..40672fb --- /dev/null +++ b/doc/module/fstats_types.html @@ -0,0 +1,271 @@ + + + + + + + + + + + + + fstats_types – FSTATS + + + + + + + + + + + + + + +
            + +
            + +
            +
            +

            fstats_types + Module + +

            +
            +
            +
            + +
            +
            + +
            +
            +
            + + +
            + +
            +
            + + +
            + +
            + +
            +

            Uses

            +
            + +
            +
            + + +
            + + + + + + +
            +

            Derived Types

            +
            +
            + +

            + type, public ::  + array_container + +

            +
            +
            +

            Provides a container for a real-valued array. A practical use of +this construct is in the construction of jagged arrays.

            + +

            Components

            +

            - + + integer(kind=int32), + intent(in) + + ::order +

            The order of the equation to fit. This value must be +at least one (linear equation), but can be higher as desired.

            +
            + + logical, + intent(in) + + ::intercept +

            Set to true if the intercept is being computed +as part of the regression; else, false.

            +
            + real(kind=real64), intent(in) ::x(:,:)x(:) -

            An M-by-N matrix containing the formatted independent data - matrix as computed by coefficient_matrix.

            +

            An N-element array containing the independent variable +measurement points.

            - + real(kind=real64), intent(out) :: c(:,:) -

            The N-by-N covariance matrix.

            +

            An N-by-K matrix where the results will be written. K +must equal order + 1 in the event intercept is true; +however, if intercept is false, K must equal order.

            - + class(errors), intent(inout),
            - + class(errors), intent(inout),
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + class(errors), intent(inout),
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + class(errors), intent(inout),
            - + integer(kind=int32), intent(in)
            - + integer(kind=int32), intent(in)
            - + real(kind=real64), intent(in),
            - + class(errors), intent(inout),
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            - + real(kind=real64), intent(in)
            + + + + + + + + + + + + + + + + + + + + +
            TypeVisibility AttributesNameInitial
            + + real(kind=real64), + public, + allocatable, dimension(:) + ::x +

            The array.

            +
            + + + + +
            +

            + +
            +
            + + + + + +

          +
          + +
          + +
          +
          +
          +

          FSTATS was developed by Jason Christopherson
          © 2024 +

          +
          +
          +

          + Documentation generated by + FORD + on 2024-04-19 07:47

          +
          +
          +
          +
          +
          + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/proc/adjusted_r_squared.html b/doc/proc/adjusted_r_squared.html index 2c322e9..5af6dab 100644 --- a/doc/proc/adjusted_r_squared.html +++ b/doc/proc/adjusted_r_squared.html @@ -74,7 +74,7 @@

          adjusted_r_squared
        • 21 statements + title=" 1.2% of total for procedures.">21 statements
        • @@ -162,7 +162,7 @@

          Arguments

          - + integer(kind=int32), intent(in) @@ -177,7 +177,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -209,7 +209,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -232,7 +232,7 @@

          Arguments

          Return Value - + real(kind=real64)

          @@ -265,7 +265,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/allan_variance.html b/doc/proc/allan_variance.html index 47733ab..e109ceb 100644 --- a/doc/proc/allan_variance.html +++ b/doc/proc/allan_variance.html @@ -74,7 +74,7 @@

          allan_variance
        • 43 statements + title=" 2.6% of total for procedures.">43 statements
        • @@ -161,7 +161,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -192,7 +192,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -214,7 +214,7 @@

          Arguments

          Return Value - + real(kind=real64), allocatable, dimension(:,:)

          @@ -250,7 +250,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/bartletts_test.html b/doc/proc/bartletts_test.html new file mode 100644 index 0000000..592b0c0 --- /dev/null +++ b/doc/proc/bartletts_test.html @@ -0,0 +1,279 @@ + + + + + + + + + + + + + bartletts_test – FSTATS + + + + + + + + + + + + + + +
          + +
          + +
          +
          +

          bartletts_test + Subroutine + +

          +
          +
          +
          + +
          +
          + +
          +
          +
          + + +
          + +
          + + +
          +

          public subroutine bartletts_test(x, stat, p) +

          + + +

          Computes Bartlett's test statistic and associated probability.

          +

          The statistic is calculated as follows.

          +

          + +

          +

          Where and is the pooled +variance.

          +

          The probability is calculated as the right-tail probability of the +chi-squared distribution.

          +

          Bartlett's test is most relevant for distributions showing strong +normality. For distributions lacking strong normality, consider +Levene's test instead.

          +

          See Also

          + + + +

          Arguments

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          TypeIntentOptional AttributesName
          + + type(array_container), + intent(in), + dimension(:) + ::x +

          The arrays of data to analyze.

          +
          + + real(kind=real64), + intent(out) + + ::stat +

          The Bartlett's test statistic.

          +
          + + real(kind=real64), + intent(out) + + ::p +

          The probability value that the variances of each data set are +equivalent. A low p-value, less than some significance level, +indicates a non-equivalance of variances.

          +
          + +
          + + + + + + + + + + + + +
          +
          + +
          +
          +
          +
          +
          +

          FSTATS was developed by Jason Christopherson
          © 2024 +

          +
          +
          +

          + Documentation generated by + FORD + on 2024-04-19 07:47

          +
          +
          +
          +
          +
          + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/proc/beta.html b/doc/proc/beta.html index 86f8c8e..00116b3 100644 --- a/doc/proc/beta.html +++ b/doc/proc/beta.html @@ -160,7 +160,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -175,7 +175,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -193,7 +193,7 @@

          Arguments

          Return Value - + real(kind=real64)

          @@ -226,7 +226,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/bootstrap.html b/doc/proc/bootstrap.html index 34db7c6..9633783 100644 --- a/doc/proc/bootstrap.html +++ b/doc/proc/bootstrap.html @@ -74,7 +74,7 @@

          bootstrap
        • 50 statements + title=" 3.0% of total for procedures.">50 statements
        • @@ -171,7 +171,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -237,7 +237,7 @@

          Arguments

          Return Value - + type(bootstrap_statistics)

          @@ -271,7 +271,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/bootstrap_linear_least_squares.html b/doc/proc/bootstrap_linear_least_squares.html index c8f08a9..d16738e 100644 --- a/doc/proc/bootstrap_linear_least_squares.html +++ b/doc/proc/bootstrap_linear_least_squares.html @@ -74,7 +74,7 @@

          bootstrap_linear_least_squares
        • 94 statements + title=" 5.6% of total for procedures.">94 statements
        • @@ -190,7 +190,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -421,7 +421,7 @@

          Arguments

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/bootstrap_nonlinear_least_squares.html b/doc/proc/bootstrap_nonlinear_least_squares.html index 2302fbc..1da1c8c 100644 --- a/doc/proc/bootstrap_nonlinear_least_squares.html +++ b/doc/proc/bootstrap_nonlinear_least_squares.html @@ -74,7 +74,7 @@

          bootstrap_nonlinear_least_squares
        • 101 statements + title=" 6.0% of total for procedures.">101 statements
        • @@ -173,7 +173,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -508,7 +508,7 @@

          Arguments

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/calculate_regression_statistics.html b/doc/proc/calculate_regression_statistics.html index 8820fba..d6493e0 100644 --- a/doc/proc/calculate_regression_statistics.html +++ b/doc/proc/calculate_regression_statistics.html @@ -74,7 +74,7 @@

          calculate_regression_statistics
        • 44 statements + title=" 2.6% of total for procedures.">44 statements
        • @@ -184,7 +184,7 @@

          Arguments

          - + real(kind=real64), intent(in) @@ -216,7 +216,7 @@

          Arguments

          - + class(errors), intent(inout), @@ -240,7 +240,7 @@

          Arguments

          Return Value - + type(regression_statistics), allocatable, (:)

          @@ -273,7 +273,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/correlation.html b/doc/proc/correlation.html index 9823591..7141035 100644 --- a/doc/proc/correlation.html +++ b/doc/proc/correlation.html @@ -158,7 +158,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -173,7 +173,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -191,7 +191,7 @@

          Arguments

          Return Value - + real(kind=real64)

          @@ -224,7 +224,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/covariance.html b/doc/proc/covariance.html index 1cf0cc8..dc56632 100644 --- a/doc/proc/covariance.html +++ b/doc/proc/covariance.html @@ -74,7 +74,7 @@

          covariance
        • 21 statements + title=" 1.2% of total for procedures.">21 statements
        • @@ -156,7 +156,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -171,7 +171,7 @@

          Arguments

          - + real(kind=real64), intent(in), @@ -189,7 +189,7 @@

          Arguments

          Return Value - + real(kind=real64)

          @@ -222,7 +222,7 @@

          Return Value

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/proc/covariance_matrix.html b/doc/proc/covariance_matrix.html index 68d0f00..7727d51 100644 --- a/doc/proc/covariance_matrix.html +++ b/doc/proc/covariance_matrix.html @@ -74,7 +74,7 @@

          covariance_matrix
        • 30 statements + title=" 1.8% of total for procedures.">30 statements
        • @@ -139,7 +139,7 @@

          public subroutine covariance_matrix(x, c, err)

          Computes the covariance matrix where and is computed -by coefficient_matrix.

          +by design_matrix.

          See Also

          • Wikipedia
          • @@ -160,7 +160,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -171,12 +171,12 @@

            Arguments

            x(:,:)

            An M-by-N matrix containing the formatted independent data - matrix as computed by coefficient_matrix.

            + matrix as computed by design_matrix.

            - + real(kind=real64), intent(out) @@ -191,7 +191,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -241,7 +241,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/coefficient_matrix.html b/doc/proc/design_matrix.html similarity index 92% rename from doc/proc/coefficient_matrix.html rename to doc/proc/design_matrix.html index 45e8aa1..b77af0c 100644 --- a/doc/proc/coefficient_matrix.html +++ b/doc/proc/design_matrix.html @@ -10,7 +10,7 @@ - coefficient_matrix – FSTATS + design_matrix – FSTATS @@ -62,7 +62,7 @@
            -

            coefficient_matrix +

            design_matrix Subroutine

            @@ -74,7 +74,7 @@

            coefficient_matrix
          • 39 statements + title=" 2.3% of total for procedures.">39 statements
          • @@ -88,7 +88,7 @@

            coefficient_matrix

          • @@ -133,18 +133,20 @@

            Contents

            -

            public subroutine coefficient_matrix(order, intercept, x, c, err) +

            public subroutine design_matrix(order, intercept, x, c, err)

            -

            Computes the coefficient matrix to the linear +

            Computes the design matrix for the linear least-squares regression problem of , where - is the coefficient matrix computed here, is + is the matrix computed here, is the vector of coefficients to be determined, and is the vector of measured dependent variables.

            See Also

            @@ -193,7 +195,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -209,7 +211,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -226,7 +228,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -274,7 +276,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/difference.html b/doc/proc/difference.html index bad6cfa..7700f1d 100644 --- a/doc/proc/difference.html +++ b/doc/proc/difference.html @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -171,7 +171,7 @@

            Arguments

            Return Value - + real(kind=real64), allocatable, dimension(:)

            @@ -205,7 +205,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/digamma.html b/doc/proc/digamma.html index d446207..1c806f1 100644 --- a/doc/proc/digamma.html +++ b/doc/proc/digamma.html @@ -74,7 +74,7 @@

            digamma
          • 26 statements + title=" 1.5% of total for procedures.">26 statements
          • @@ -162,7 +162,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -180,7 +180,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -213,7 +213,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/f_test.html b/doc/proc/f_test.html index 1b39f67..c361462 100644 --- a/doc/proc/f_test.html +++ b/doc/proc/f_test.html @@ -74,7 +74,7 @@

            f_test
          • 33 statements + title=" 1.9% of total for procedures.">32 statements
          • @@ -203,7 +203,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -220,7 +220,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -235,7 +235,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -279,7 +279,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/factorial.html b/doc/proc/factorial.html index 552ff76..9f0d46d 100644 --- a/doc/proc/factorial.html +++ b/doc/proc/factorial.html @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -171,7 +171,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -204,7 +204,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/full_factorial.html b/doc/proc/full_factorial.html index 15f284c..154e7b9 100644 --- a/doc/proc/full_factorial.html +++ b/doc/proc/full_factorial.html @@ -74,7 +74,7 @@

            full_factorial
          • 30 statements + title=" 1.8% of total for procedures.">30 statements
          • @@ -236,7 +236,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -285,7 +285,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/get_full_factorial_matrix_size.html b/doc/proc/get_full_factorial_matrix_size.html index 337411c..533d511 100644 --- a/doc/proc/get_full_factorial_matrix_size.html +++ b/doc/proc/get_full_factorial_matrix_size.html @@ -74,7 +74,7 @@

            get_full_factorial_matrix_size
          • 27 statements + title=" 1.6% of total for procedures.">27 statements
          • @@ -171,7 +171,7 @@

            Arguments

            - + integer(kind=int32), intent(out) @@ -186,7 +186,7 @@

            Arguments

            - + integer(kind=int32), intent(out) @@ -201,7 +201,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -249,7 +249,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/incomplete_beta.html b/doc/proc/incomplete_beta.html index e99c920..28adf60 100644 --- a/doc/proc/incomplete_beta.html +++ b/doc/proc/incomplete_beta.html @@ -159,7 +159,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -174,7 +174,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -189,7 +189,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -207,7 +207,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -240,7 +240,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/incomplete_gamma_lower.html b/doc/proc/incomplete_gamma_lower.html index b4263c2..f6971e9 100644 --- a/doc/proc/incomplete_gamma_lower.html +++ b/doc/proc/incomplete_gamma_lower.html @@ -74,7 +74,7 @@

            incomplete_gamma_lower
          • 38 statements + title=" 2.3% of total for procedures.">38 statements
          • @@ -160,7 +160,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -175,7 +175,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -193,7 +193,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -226,7 +226,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/incomplete_gamma_upper.html b/doc/proc/incomplete_gamma_upper.html index 19724c7..b96189c 100644 --- a/doc/proc/incomplete_gamma_upper.html +++ b/doc/proc/incomplete_gamma_upper.html @@ -74,7 +74,7 @@

            incomplete_gamma_upper
          • 39 statements + title=" 2.3% of total for procedures.">39 statements
          • @@ -160,7 +160,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -175,7 +175,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -193,7 +193,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -226,7 +226,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/jacobian.html b/doc/proc/jacobian.html index 45d2d02..2d7e7a9 100644 --- a/doc/proc/jacobian.html +++ b/doc/proc/jacobian.html @@ -74,7 +74,7 @@

            jacobian
          • 64 statements + title=" 3.8% of total for procedures.">64 statements
          • @@ -280,7 +280,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -330,7 +330,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/levenes_test.html b/doc/proc/levenes_test.html new file mode 100644 index 0000000..9c6a1b1 --- /dev/null +++ b/doc/proc/levenes_test.html @@ -0,0 +1,292 @@ + + + + + + + + + + + + + levenes_test – FSTATS + + + + + + + + + + + + + + +
            + +
            + +
            +
            +

            levenes_test + Subroutine + +

            +
            +
            +
            + +
            +
            + +
            +
            +
            + + +
            + +
            + + +
            +

            public subroutine levenes_test(x, stat, p, err) +

            + + +

            Computes Levene's test statistic and associated probability.

            +

            The statistic is calculated as follows. + +

            +

            Where: + + + +

            +

            As the test statistic is approximately F-distributed, the F-distribution +is used to calculate the probability term.

            +

            See Also

            + + + +

            Arguments

            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            TypeIntentOptional AttributesName
            + + type(array_container), + intent(in), + dimension(:) + ::x +

            The arrays of data to analyze.

            +
            + + real(kind=real64), + intent(out) + + ::stat +

            The Bartlett's test statistic.

            +
            + + real(kind=real64), + intent(out) + + ::p +

            The probability value that the variances of each data set are +equivalent. A low p-value, less than some significance level, +indicates a non-equivalance of variances.

            +
            + + class(errors), + intent(inout),optional, + target + ::err + +
            + +
            + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +

            FSTATS was developed by Jason Christopherson
            © 2024 +

            +
            +
            +

            + Documentation generated by + FORD + on 2024-04-19 07:47

            +
            +
            +
            +
            +
            + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/proc/linear_least_squares.html b/doc/proc/linear_least_squares.html index 510d923..90b1c9a 100644 --- a/doc/proc/linear_least_squares.html +++ b/doc/proc/linear_least_squares.html @@ -74,7 +74,7 @@

            linear_least_squares
          • 78 statements + title=" 4.6% of total for procedures.">78 statements
          • @@ -191,7 +191,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -207,7 +207,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -303,7 +303,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -354,7 +354,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/lowess.html b/doc/proc/lowess.html index 9daee95..4627e33 100644 --- a/doc/proc/lowess.html +++ b/doc/proc/lowess.html @@ -74,7 +74,7 @@

            lowess
          • 141 statements + title=" 8.4% of total for procedures.">141 statements
          • @@ -160,7 +160,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -288,7 +288,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -337,7 +337,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/mean.html b/doc/proc/mean.html index 0e29516..4edd8ea 100644 --- a/doc/proc/mean.html +++ b/doc/proc/mean.html @@ -74,7 +74,7 @@

            mean
          • 15 statements + title=" 0.9% of total for procedures.">15 statements
          • @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -171,7 +171,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -204,7 +204,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/median.html b/doc/proc/median.html index a421eab..0db278a 100644 --- a/doc/proc/median.html +++ b/doc/proc/median.html @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(inout) @@ -172,7 +172,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -205,7 +205,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/nonlinear_least_squares.html b/doc/proc/nonlinear_least_squares.html index 4a35ce7..9887bce 100644 --- a/doc/proc/nonlinear_least_squares.html +++ b/doc/proc/nonlinear_least_squares.html @@ -74,7 +74,7 @@

            nonlinear_least_squares
          • 149 statements + title=" 8.9% of total for procedures.">149 statements
          • @@ -169,7 +169,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -184,7 +184,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -396,7 +396,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -452,7 +452,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/quantile.html b/doc/proc/quantile.html index 9f5339f..d32f58a 100644 --- a/doc/proc/quantile.html +++ b/doc/proc/quantile.html @@ -74,7 +74,7 @@

            quantile
          • 19 statements + title=" 1.1% of total for procedures.">19 statements
          • @@ -158,7 +158,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -191,7 +191,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -224,7 +224,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/r_squared.html b/doc/proc/r_squared.html index b2f6dca..d7f7778 100644 --- a/doc/proc/r_squared.html +++ b/doc/proc/r_squared.html @@ -74,7 +74,7 @@

            r_squared
          • 28 statements + title=" 1.7% of total for procedures.">28 statements
          • @@ -164,7 +164,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -196,7 +196,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -219,7 +219,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -252,7 +252,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/random_resample.html b/doc/proc/random_resample.html index e9c358b..db8e0f8 100644 --- a/doc/proc/random_resample.html +++ b/doc/proc/random_resample.html @@ -74,7 +74,7 @@

            random_resample
          • 17 statements + title=" 1.0% of total for procedures.">17 statements
          • @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -212,7 +212,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/regularized_beta.html b/doc/proc/regularized_beta.html index f74c9c3..c2255d0 100644 --- a/doc/proc/regularized_beta.html +++ b/doc/proc/regularized_beta.html @@ -74,7 +74,7 @@

            regularized_beta
          • 40 statements + title=" 2.4% of total for procedures.">40 statements
          • @@ -160,7 +160,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -175,7 +175,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -190,7 +190,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -208,7 +208,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -241,7 +241,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/rejection_sample.html b/doc/proc/rejection_sample.html index a720e4b..90b2a49 100644 --- a/doc/proc/rejection_sample.html +++ b/doc/proc/rejection_sample.html @@ -74,7 +74,7 @@

            rejection_sample
          • 33 statements + title=" 2.0% of total for procedures.">33 statements
          • @@ -168,7 +168,7 @@

            Arguments

            - + integer(kind=int32), intent(in) @@ -216,7 +216,7 @@

            Arguments

            Return Value - + real(kind=real64), allocatable, dimension(:)

            @@ -250,7 +250,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_array_size_error.html b/doc/proc/report_array_size_error.html index 19bdd09..ae1d9f3 100644 --- a/doc/proc/report_array_size_error.html +++ b/doc/proc/report_array_size_error.html @@ -164,7 +164,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -302,7 +302,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_arrays_not_same_size_error.html b/doc/proc/report_arrays_not_same_size_error.html index 2cf3bd6..7cd4bbc 100644 --- a/doc/proc/report_arrays_not_same_size_error.html +++ b/doc/proc/report_arrays_not_same_size_error.html @@ -74,7 +74,7 @@

            report_arrays_not_same_size_error
          • 12 statements + title=" 0.7% of total for procedures.">12 statements
          • @@ -165,7 +165,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -318,7 +318,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_iteration_count_error.html b/doc/proc/report_iteration_count_error.html index c9f641c..7a39a58 100644 --- a/doc/proc/report_iteration_count_error.html +++ b/doc/proc/report_iteration_count_error.html @@ -164,7 +164,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -287,7 +287,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_matrix_size_error.html b/doc/proc/report_matrix_size_error.html index 54ed898..33eafb3 100644 --- a/doc/proc/report_matrix_size_error.html +++ b/doc/proc/report_matrix_size_error.html @@ -164,7 +164,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -332,7 +332,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_memory_error.html b/doc/proc/report_memory_error.html index 125a801..a414970 100644 --- a/doc/proc/report_memory_error.html +++ b/doc/proc/report_memory_error.html @@ -74,7 +74,7 @@

            report_memory_error
          • 9 statements + title=" 0.5% of total for procedures.">9 statements
          • @@ -164,7 +164,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -272,7 +272,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/report_underdefined_error.html b/doc/proc/report_underdefined_error.html index e74f925..4e1f66a 100644 --- a/doc/proc/report_underdefined_error.html +++ b/doc/proc/report_underdefined_error.html @@ -164,7 +164,7 @@

            Arguments

            - + class(errors), intent(inout) @@ -287,7 +287,7 @@

            Variables

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/sample_size.html b/doc/proc/sample_size.html new file mode 100644 index 0000000..740c428 --- /dev/null +++ b/doc/proc/sample_size.html @@ -0,0 +1,305 @@ + + + + + + + + + + + + + sample_size – FSTATS + + + + + + + + + + + + + + +
            + +
            + +
            +
            +

            sample_size + Function + +

            +
            +
            +
            + +
            +
            + +
            +
            +
            + + +
            + +
            + + +
            +

            public pure function sample_size(dist, var, delta, bet, alpha) result(rst) +

            + + +

            Estimates the sample size required to achieve an experiment with the +desired power and significance levels to ascertain the desired +difference in parameter.

            +

            See Also

            + + + +

            Arguments

            + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            TypeIntentOptional AttributesName
            + + class(distribution), + intent(in) + + ::dist +

            The distribution to utilize as a measure.

            +
            + + real(kind=real64), + intent(in) + + ::var +

            An estimate of the population variance.

            +
            + + real(kind=real64), + intent(in) + + ::delta +

            The parameter difference that is desired.

            +
            + + real(kind=real64), + intent(in),optional + + ::bet +

            The desired power level. The default for this value is 0.2, for a +power of 80%.

            +
            + + real(kind=real64), + intent(in),optional + + ::alpha +

            The desired significance level. The default for this value is 0.05 +for a confidence level of 95%.

            +
            + +

            Return Value + + + real(kind=real64) + +

            +

            The minimum sample size requried to achieve the desired experimental +outcome.

            +
            + + + + + + + + + + + + +
            +
            + +
            +
            +
            +
            +
            +

            FSTATS was developed by Jason Christopherson
            © 2024 +

            +
            +
            +

            + Documentation generated by + FORD + on 2024-04-19 07:47

            +
            +
            +
            +
            +
            + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/proc/scaled_random_resample.html b/doc/proc/scaled_random_resample.html index e3f0adb..2319f9f 100644 --- a/doc/proc/scaled_random_resample.html +++ b/doc/proc/scaled_random_resample.html @@ -154,7 +154,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -213,7 +213,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/standard_deviation.html b/doc/proc/standard_deviation.html index 1e7646c..c65af27 100644 --- a/doc/proc/standard_deviation.html +++ b/doc/proc/standard_deviation.html @@ -156,7 +156,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -174,7 +174,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -207,7 +207,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/t_test_equal_variance.html b/doc/proc/t_test_equal_variance.html index dc5c024..929d975 100644 --- a/doc/proc/t_test_equal_variance.html +++ b/doc/proc/t_test_equal_variance.html @@ -74,7 +74,7 @@

            t_test_equal_variance
          • 25 statements + title=" 1.5% of total for procedures.">25 statements
          • @@ -203,7 +203,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -220,7 +220,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -264,7 +264,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/t_test_paired.html b/doc/proc/t_test_paired.html index 5060677..60444d7 100644 --- a/doc/proc/t_test_paired.html +++ b/doc/proc/t_test_paired.html @@ -74,7 +74,7 @@

            t_test_paired
          • 44 statements + title=" 2.6% of total for procedures.">44 statements
          • @@ -202,7 +202,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -219,7 +219,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -234,7 +234,7 @@

            Arguments

            - + class(errors), intent(inout), @@ -282,7 +282,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/t_test_unequal_variance.html b/doc/proc/t_test_unequal_variance.html index fd141fa..14b4a5b 100644 --- a/doc/proc/t_test_unequal_variance.html +++ b/doc/proc/t_test_unequal_variance.html @@ -74,7 +74,7 @@

            t_test_unequal_variance
          • 24 statements + title=" 1.4% of total for procedures.">24 statements
          • @@ -203,7 +203,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -220,7 +220,7 @@

            Arguments

            - + real(kind=real64), intent(out) @@ -264,7 +264,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/trimmed_mean.html b/doc/proc/trimmed_mean.html index e78d9ae..8e1388e 100644 --- a/doc/proc/trimmed_mean.html +++ b/doc/proc/trimmed_mean.html @@ -74,7 +74,7 @@

            trimmed_mean
          • 17 statements + title=" 1.0% of total for procedures.">17 statements
          • @@ -153,7 +153,7 @@

            Arguments

            - + real(kind=real64), intent(inout), @@ -169,7 +169,7 @@

            Arguments

            - + real(kind=real64), intent(in), @@ -189,7 +189,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -222,7 +222,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/proc/variance.html b/doc/proc/variance.html index a507e8c..af50412 100644 --- a/doc/proc/variance.html +++ b/doc/proc/variance.html @@ -74,7 +74,7 @@

            variance
          • 21 statements + title=" 1.2% of total for procedures.">21 statements
          • @@ -155,7 +155,7 @@

            Arguments

            - + real(kind=real64), intent(in) @@ -173,7 +173,7 @@

            Arguments

            Return Value - + real(kind=real64)

            @@ -206,7 +206,7 @@

            Return Value

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/search.html b/doc/search.html index 999ebb8..55e9fbd 100644 --- a/doc/search.html +++ b/doc/search.html @@ -95,7 +95,7 @@

            Search Results

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats.f90.html b/doc/sourcefile/fstats.f90.html index 58a8a56..284b22b 100644 --- a/doc/sourcefile/fstats.f90.html +++ b/doc/sourcefile/fstats.f90.html @@ -74,7 +74,7 @@

            fstats.f90
          • 81 statements + title=" 2.9% of total for source files.">85 statements
          • @@ -202,7 +202,7 @@

            Source Code

            public :: digamma public :: incomplete_gamma_upper public :: incomplete_gamma_lower - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: regression_statistics @@ -231,11 +231,15 @@

            Source Code

            public :: box_muller_sample public :: rejection_sample public :: lowess - public :: FS_LEVENBERG_MARQUARDT_UPDATE - public :: FS_QUADRATIC_UPDATE - public :: FS_NIELSEN_UPDATE - -end module + public :: pooled_variance + public :: bartletts_test + public :: levenes_test + public :: sample_size + public :: FS_LEVENBERG_MARQUARDT_UPDATE + public :: FS_QUADRATIC_UPDATE + public :: FS_NIELSEN_UPDATE + +end module @@ -254,7 +258,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_allan.f90.html b/doc/sourcefile/fstats_allan.f90.html index f4a3d8a..f0bc6b6 100644 --- a/doc/sourcefile/fstats_allan.f90.html +++ b/doc/sourcefile/fstats_allan.f90.html @@ -74,7 +74,7 @@

            fstats_allan.f90
          • 51 statements + title=" 1.7% of total for source files.">51 statements
          • @@ -269,7 +269,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_anova.f90.html b/doc/sourcefile/fstats_anova.f90.html index 9f9e986..c46cf64 100644 --- a/doc/sourcefile/fstats_anova.f90.html +++ b/doc/sourcefile/fstats_anova.f90.html @@ -74,7 +74,7 @@

            fstats_anova.f90
          • 201 statements + title=" 6.8% of total for source files.">199 statements
          • @@ -158,447 +158,443 @@

            Source Code

            use fstats_descriptive_statistics use ferror use fstats_errors - implicit none - private - public :: anova_factor - public :: single_factor_anova_table - public :: two_factor_anova_table - public :: anova - - type anova_factor - !! Defines an ANOVA factor result. - real(real64) :: dof - !! The number of degrees of freedome. - real(real64) :: variance - !! The estimate of variance. - real(real64) :: sum_of_squares - !! The sum of the squares. - real(real64) :: f_statistic - !! The F-statistic. - real(real64) :: probability - !! The variance probability term. - end type - - type single_factor_anova_table - !! Defines a single-factor ANOVA results table. - type(anova_factor) :: main_factor - !! The main, or main factor, results. - type(anova_factor) :: within_factor - !! The within-treatement (error) results. - real(real64) :: total_dof - !! The total number of degrees of freedom. - real(real64) :: total_sum_of_squares - !! The total sum of squares. - real(real64) :: total_variance - !! The total variance estimate. - real(real64) :: overall_mean - !! The overall mean value. - end type - - type two_factor_anova_table - !! Defines a two-factor ANOVA results table. - type(anova_factor) :: main_factor_1 - !! The first main-factor results. - type(anova_factor) :: main_factor_2 - !! The second main-factor results. - type(anova_factor) :: interaction - !! The interaction effects. - type(anova_factor) :: within_factor - !! The within (error) factor results. - real(real64) :: total_dof - !! The total number of degrees of freedom. - real(real64) :: total_sum_of_squares - !! The total sum of squares. - real(real64) :: total_variance - !! The total variance estimate. - real(real64) :: overall_mean - !! The overall mean value. - end type - - interface anova - !! Performs an analysis of variance (ANOVA) on the supplied data - !! set. - !! - !! The following example illustrates a single-factor ANOVA on a - !! data set. - !! ```fortran - !! program example - !! use iso_fortran_env - !! use fstats - !! implicit none - !! - !! ! Local Variables - !! character, parameter :: tab = achar(9) - !! real(real64) :: x(10, 2) - !! type(single_factor_anova_table) :: tbl - !! - !! ! Define the data - !! x = reshape( & - !! [ & - !! 3.086d3, 3.082d3, 3.069d3, 3.072d3, 3.045d3, 3.070d3, 3.079d3, & - !! 3.050d3, 3.062d3, 3.062d3, 3.075d3, 3.061d3, 3.063d3, 3.038d3, & - !! 3.070d3, 3.062d3, 3.070d3, 3.049d3, 3.042d3, 3.063d3 & - !! ], & - !! [10, 2] & - !! ) - !! - !! ! Perform the ANOVA - !! tbl = anova(x) - !! - !! ! Print out the table - !! print '(A)', "Description" // tab // "DOF" // tab // "Sum of Sq." // & - !! tab // "Variance" // tab // "F-Stat" // tab // "P-Value" - !! print '(AF2.0AF5.1AF5.1AF5.3AF5.3)', "Main Factor: " // tab, & - !! tbl%main_factor%dof, tab, & - !! tbl%main_factor%sum_of_squares, tab // tab, & - !! tbl%main_factor%variance, tab // tab, & - !! tbl%main_factor%f_statistic, tab, & - !! tbl%main_factor%probability - !! - !! print '(AF3.0AF6.1AF5.1)', "Within: " // tab, & - !! tbl%within_factor%dof, tab, & - !! tbl%within_factor%sum_of_squares, tab // tab, & - !! tbl%within_factor%variance - !! - !! print '(AF3.0AF6.1AF5.1)', "Total: " // tab // tab, & - !! tbl%total_dof, tab, & - !! tbl%total_sum_of_squares, tab // tab, & - !! tbl%total_variance - !! - !! print '(AF6.1)', "Overall Mean: ", tbl%overall_mean - !! end program - !! ``` - !! The above program produces the following output. - !! ```text - !! Description DOF Sum of Sq. Variance F-Stat P-Value - !! Main Factor: 1. 352.8 352.8 2.147 0.160 - !! Within: 18. 2958.2 164.3 - !! Total: 19. 3311.0 174.3 - !! Overall Mean: 3063.5 - !! ``` - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Analysis_of_variance) - !! - [SPC Excel Single Factor ANOVA](https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova) - !! - [SPC Excel Gage R&R](https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1) - !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) - !! - [NIST - Two Way ANOVA](https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm) - module procedure :: anova_1_factor - module procedure :: anova_2_factor - module procedure :: anova_model_fit - end interface -contains -! ------------------------------------------------------------------------------ -! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova -function anova_1_factor(x) result(rst) - !! Performs an analysis of variance (ANOVA) on the supplied data set. - real(real64), intent(in) :: x(:,:) - !! An M-by-N matrix containing the M replications of the N test - !! points of interest. - type(single_factor_anova_table) :: rst - !! A single_factor_anova_table instance containing the ANOVA results. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - - ! Local Variables - integer(int32) :: j, a, n, nt - real(real64) :: sum_all, tssq, essq, bssq - - ! Initialization - a = size(x, 2) - nt = size(x, 1) - n = nt * a - rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) - rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) - - ! Determine the degrees of freedom - rst%main_factor%dof = a - 1 - rst%within_factor%dof = n - a - rst%total_dof = n - 1 - - ! Quick Return - if (a == 1 .or. nt == 1) then - rst%main_factor%sum_of_squares = zero - rst%main_factor%variance = zero - rst%main_factor%f_statistic = zero - rst%main_factor%probability = zero - rst%within_factor%sum_of_squares = zero - rst%within_factor%variance = zero - rst%total_variance = variance(pack(x, .true.)) - rst%total_sum_of_squares = rst%total_variance * rst%total_dof - rst%overall_mean = mean(pack(x, .true.)) - return - end if - - ! Compute the sum of squares for all factors - sum_all = sum(x) - tssq = sum(x**2) - (sum_all**2 / n) - - bssq = zero - do j = 1, a - bssq = bssq + sum(x(:,j))**2 - end do - bssq = (bssq / nt) - (sum_all**2 / n) - essq = tssq - bssq - - rst%main_factor%sum_of_squares = bssq - rst%within_factor%sum_of_squares = essq - rst%total_sum_of_squares = tssq - - ! Compute the variance terms - rst%main_factor%variance = bssq / rst%main_factor%dof - rst%within_factor%variance = essq / rst%within_factor%dof - rst%total_variance = tssq / rst%total_dof - - ! Compute the overall mean - rst%overall_mean = mean(pack(x, .true.)) - - ! Compute the F-statistic and probability term - call anova_probability( & - rst%main_factor%variance, & - rst%within_factor%variance, & - rst%main_factor%dof, & - rst%within_factor%dof, & - rst%main_factor%f_statistic, & - rst%main_factor%probability & - ) -end function - -! ------------------------------------------------------------------------------ -! REF: https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1 -! REF: https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm -! Data set is expected as a 3D array with each of the K pages containing the R -! treatments of N tests such that the array size is N-by-R-by-K -function anova_2_factor(x) result(rst) - !! Performs an analysis of variance (ANOVA) on the supplied data set. - real(real64), intent(in) :: x(:,:,:) - !! An M-by-N-by-K array containing the M replications of the - !! N first factor results, and the K second factor results. - type(two_factor_anova_table) :: rst - !! A two_factor_anova_table instance containing the ANOVA results. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, j, jj, k, r, n - real(real64) :: factorMean, sum_all - real(real64), allocatable :: xpack(:) - - ! Initialization - n = size(x, 3) - k = size(x, 2) - r = size(x, 1) - rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) - rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) - - ! Quick Return - if (k == 1) then - ! This is a one-factor anova - end if - - ! Determine the number of DOF - rst%main_factor_1%dof = k - one - rst%main_factor_2%dof = n - 1 - rst%interaction%dof = (k - 1) * (n - 1) - rst%within_factor%dof = n * k * (r - 1) - rst%total_dof = n * k * r - 1 - - ! Compute the overall mean, sum of squares, and variance - xpack = pack(x, .true.) - rst%overall_mean = mean(xpack) - rst%total_sum_of_squares = sum((xpack - rst%overall_mean)**2) - rst%total_variance = rst%total_sum_of_squares / rst%total_dof - - ! Compute factor 1 results - rst%main_factor_1%sum_of_squares = zero - do i = 1, k - factorMean = mean(pack(x(:,i,:), .true.)) - rst%main_factor_1%sum_of_squares = rst%main_factor_1%sum_of_squares + & - (factorMean - rst%overall_mean)**2 - end do - rst%main_factor_1%sum_of_squares = n * r * rst%main_factor_1%sum_of_squares - rst%main_factor_1%variance = rst%main_factor_1%sum_of_squares / & - rst%main_factor_1%dof - - ! Compute factor 2 results - rst%main_factor_2%sum_of_squares = zero - do i = 1, n - factorMean = mean(pack(x(:,:,i), .true.)) - rst%main_factor_2%sum_of_squares = rst%main_factor_2%sum_of_squares + & - (factorMean - rst%overall_mean)**2 - end do - rst%main_factor_2%sum_of_squares = k * r * rst%main_factor_2%sum_of_squares - rst%main_factor_2%variance = rst%main_factor_2%sum_of_squares / & - rst%main_factor_2%dof - - ! Compute the within (error) term - rst%within_factor%sum_of_squares = zero - do j = 1, k - do i = 1, n - factorMean = mean(x(:,j,i)) - do jj = 1, r - rst%within_factor%sum_of_squares = & - rst%within_factor%sum_of_squares + & - (x(jj,j,i) - factorMean)**2 - end do - end do - end do - rst%within_factor%variance = rst%within_factor%sum_of_squares /& - rst%within_factor%dof - - ! Compute the interaction term - rst%interaction%sum_of_squares = rst%total_sum_of_squares - ( & - rst%main_factor_1%sum_of_squares + & - rst%main_factor_2%sum_of_squares + & - rst%within_factor%sum_of_squares & - ) - rst%interaction%variance = rst%interaction%sum_of_squares / & - rst%interaction%dof - - ! Compute the F-statistics - call anova_probability( & - rst%main_factor_1%variance, & - rst%within_factor%variance, & - rst%main_factor_1%dof, & - rst%within_factor%dof, & - rst%main_factor_1%f_statistic, & - rst%main_factor_1%probability & - ) - call anova_probability( & - rst%main_factor_2%variance, & - rst%within_factor%variance, & - rst%main_factor_2%dof, & - rst%within_factor%dof, & - rst%main_factor_2%f_statistic, & - rst%main_factor_2%probability & - ) - call anova_probability( & - rst%interaction%variance, & - rst%within_factor%variance, & - rst%interaction%dof, & - rst%within_factor%dof, & - rst%interaction%f_statistic, & - rst%interaction%probability & - ) -end function - -! ------------------------------------------------------------------------------ -! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1 -function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) - !! Performs an analysis of variance (ANOVA) on the supplied data set. - integer(int32), intent(in) :: nmodelparams - !! The number of model parameters. - real(real64), intent(in) :: ymeas(:) - !! An N-element array containing the measured dependent variable data. - real(real64), intent(in) :: ymod(:) - !! An N-element array containing the modeled dependent variable data. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the - !! same length. - !! - FS_MEMORY_ERROR: Occurs if a memory error is encountered. - type(single_factor_anova_table) :: rst - !! A single_factor_anova_table instance containing the ANOVA results. - - ! Local Variables - integer(int32) :: n, flag - real(real64), allocatable :: ypack(:) - real(real64) :: sum_all - class(errors), pointer :: errmgr - type(errors), target :: deferr - - ! Initialization - n = size(ymeas) - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) - rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) - - ! Input Checking - if (size(ymod) /= n) then - call report_arrays_not_same_size_error(errmgr, "anova_model_fit", & - "YMEAS", "YMOD", n, size(ymod)) - return - end if - - ! Memory Allocation - allocate(ypack(2 * n), stat = flag) - if (flag /= 0) then - call report_memory_error(errmgr, "anova_model_fit", flag) - return - end if - - ! Determine the number of DOF - rst%main_factor%dof = nmodelparams - 1 - rst%within_factor%dof = n - rst%main_factor%dof - 1 - rst%total_dof = n - 1 - - ! Process - ypack(1:n) = ymeas - ypack(n+1:2*n) = ymod - rst%overall_mean = mean(ypack) - rst%total_sum_of_squares = sum((ymeas - rst%overall_mean)**2) - rst%main_factor%sum_of_squares = sum((ymod - rst%overall_mean)**2) - rst%within_factor%sum_of_squares = sum((ymeas - ymod)**2) - - rst%total_variance = rst%total_sum_of_squares / rst%total_dof - rst%main_factor%variance = rst%main_factor%sum_of_squares / & - rst%main_factor%dof - rst%within_factor%variance = rst%within_factor%sum_of_squares / & - rst%within_factor%dof - - ! Compute the F-statistic and probability term - call anova_probability( & - rst%main_factor%variance, & - rst%within_factor%variance, & - rst%main_factor%dof, & - rst%within_factor%dof, & - rst%main_factor%f_statistic, & - rst%main_factor%probability & - ) - - ! Formatting -100 format(A, I0, A, I0, A) -101 format(A, I0, A) -end function - -! ****************************************************************************** -! PRIVATE ROUTINES -! ------------------------------------------------------------------------------ -subroutine anova_probability(v1, v2, dof1, dof2, f, p) - ! Arguments - real(real64), intent(in) :: v1, v2, dof1, dof2 - real(real64), intent(out) :: f, p - - ! Local Variables - real(real64) :: d1, d2, a, b, x - - ! Process - f = v1 / v2 - d1 = dof1 - d2 = dof2 - - a = 0.5d0 * d2 - b = 0.5d0 * d1 - x = d2 / (d2 + d1 * f) - - p = regularized_beta(a, b, x) - if (p > 1.0d0) then - p = 2.0d0 - p - end if -end subroutine - -! ------------------------------------------------------------------------------ -end module + use fstats_distributions + implicit none + private + public :: anova_factor + public :: single_factor_anova_table + public :: two_factor_anova_table + public :: anova + + type anova_factor + !! Defines an ANOVA factor result. + real(real64) :: dof + !! The number of degrees of freedome. + real(real64) :: variance + !! The estimate of variance. + real(real64) :: sum_of_squares + !! The sum of the squares. + real(real64) :: f_statistic + !! The F-statistic. + real(real64) :: probability + !! The variance probability term. + end type + + type single_factor_anova_table + !! Defines a single-factor ANOVA results table. + type(anova_factor) :: main_factor + !! The main, or main factor, results. + type(anova_factor) :: within_factor + !! The within-treatement (error) results. + real(real64) :: total_dof + !! The total number of degrees of freedom. + real(real64) :: total_sum_of_squares + !! The total sum of squares. + real(real64) :: total_variance + !! The total variance estimate. + real(real64) :: overall_mean + !! The overall mean value. + end type + + type two_factor_anova_table + !! Defines a two-factor ANOVA results table. + type(anova_factor) :: main_factor_1 + !! The first main-factor results. + type(anova_factor) :: main_factor_2 + !! The second main-factor results. + type(anova_factor) :: interaction + !! The interaction effects. + type(anova_factor) :: within_factor + !! The within (error) factor results. + real(real64) :: total_dof + !! The total number of degrees of freedom. + real(real64) :: total_sum_of_squares + !! The total sum of squares. + real(real64) :: total_variance + !! The total variance estimate. + real(real64) :: overall_mean + !! The overall mean value. + end type + + interface anova + !! Performs an analysis of variance (ANOVA) on the supplied data + !! set. + !! + !! The following example illustrates a single-factor ANOVA on a + !! data set. + !! ```fortran + !! program example + !! use iso_fortran_env + !! use fstats + !! implicit none + !! + !! ! Local Variables + !! character, parameter :: tab = achar(9) + !! real(real64) :: x(10, 2) + !! type(single_factor_anova_table) :: tbl + !! + !! ! Define the data + !! x = reshape( & + !! [ & + !! 3.086d3, 3.082d3, 3.069d3, 3.072d3, 3.045d3, 3.070d3, 3.079d3, & + !! 3.050d3, 3.062d3, 3.062d3, 3.075d3, 3.061d3, 3.063d3, 3.038d3, & + !! 3.070d3, 3.062d3, 3.070d3, 3.049d3, 3.042d3, 3.063d3 & + !! ], & + !! [10, 2] & + !! ) + !! + !! ! Perform the ANOVA + !! tbl = anova(x) + !! + !! ! Print out the table + !! print '(A)', "Description" // tab // "DOF" // tab // "Sum of Sq." // & + !! tab // "Variance" // tab // "F-Stat" // tab // "P-Value" + !! print '(AF2.0AF5.1AF5.1AF5.3AF5.3)', "Main Factor: " // tab, & + !! tbl%main_factor%dof, tab, & + !! tbl%main_factor%sum_of_squares, tab // tab, & + !! tbl%main_factor%variance, tab // tab, & + !! tbl%main_factor%f_statistic, tab, & + !! tbl%main_factor%probability + !! + !! print '(AF3.0AF6.1AF5.1)', "Within: " // tab, & + !! tbl%within_factor%dof, tab, & + !! tbl%within_factor%sum_of_squares, tab // tab, & + !! tbl%within_factor%variance + !! + !! print '(AF3.0AF6.1AF5.1)', "Total: " // tab // tab, & + !! tbl%total_dof, tab, & + !! tbl%total_sum_of_squares, tab // tab, & + !! tbl%total_variance + !! + !! print '(AF6.1)', "Overall Mean: ", tbl%overall_mean + !! end program + !! ``` + !! The above program produces the following output. + !! ```text + !! Description DOF Sum of Sq. Variance F-Stat P-Value + !! Main Factor: 1. 352.8 352.8 2.147 0.160 + !! Within: 18. 2958.2 164.3 + !! Total: 19. 3311.0 174.3 + !! Overall Mean: 3063.5 + !! ``` + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Analysis_of_variance) + !! - [SPC Excel Single Factor ANOVA](https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova) + !! - [SPC Excel Gage R&R](https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1) + !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) + !! - [NIST - Two Way ANOVA](https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm) + module procedure :: anova_1_factor + module procedure :: anova_2_factor + module procedure :: anova_model_fit + end interface +contains +! ------------------------------------------------------------------------------ +! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova +function anova_1_factor(x) result(rst) + !! Performs an analysis of variance (ANOVA) on the supplied data set. + real(real64), intent(in) :: x(:,:) + !! An M-by-N matrix containing the M replications of the N test + !! points of interest. + type(single_factor_anova_table) :: rst + !! A single_factor_anova_table instance containing the ANOVA results. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + + ! Local Variables + integer(int32) :: j, a, n, nt + real(real64) :: sum_all, tssq, essq, bssq + + ! Initialization + a = size(x, 2) + nt = size(x, 1) + n = nt * a + rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) + rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) + + ! Determine the degrees of freedom + rst%main_factor%dof = a - 1 + rst%within_factor%dof = n - a + rst%total_dof = n - 1 + + ! Quick Return + if (a == 1 .or. nt == 1) then + rst%main_factor%sum_of_squares = zero + rst%main_factor%variance = zero + rst%main_factor%f_statistic = zero + rst%main_factor%probability = zero + rst%within_factor%sum_of_squares = zero + rst%within_factor%variance = zero + rst%total_variance = variance(pack(x, .true.)) + rst%total_sum_of_squares = rst%total_variance * rst%total_dof + rst%overall_mean = mean(pack(x, .true.)) + return + end if + + ! Compute the sum of squares for all factors + sum_all = sum(x) + tssq = sum(x**2) - (sum_all**2 / n) + + bssq = zero + do j = 1, a + bssq = bssq + sum(x(:,j))**2 + end do + bssq = (bssq / nt) - (sum_all**2 / n) + essq = tssq - bssq + + rst%main_factor%sum_of_squares = bssq + rst%within_factor%sum_of_squares = essq + rst%total_sum_of_squares = tssq + + ! Compute the variance terms + rst%main_factor%variance = bssq / rst%main_factor%dof + rst%within_factor%variance = essq / rst%within_factor%dof + rst%total_variance = tssq / rst%total_dof + + ! Compute the overall mean + rst%overall_mean = mean(pack(x, .true.)) + + ! Compute the F-statistic and probability term + call anova_probability( & + rst%main_factor%variance, & + rst%within_factor%variance, & + rst%main_factor%dof, & + rst%within_factor%dof, & + rst%main_factor%f_statistic, & + rst%main_factor%probability & + ) +end function + +! ------------------------------------------------------------------------------ +! REF: https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1 +! REF: https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm +! Data set is expected as a 3D array with each of the K pages containing the R +! treatments of N tests such that the array size is N-by-R-by-K +function anova_2_factor(x) result(rst) + !! Performs an analysis of variance (ANOVA) on the supplied data set. + real(real64), intent(in) :: x(:,:,:) + !! An M-by-N-by-K array containing the M replications of the + !! N first factor results, and the K second factor results. + type(two_factor_anova_table) :: rst + !! A two_factor_anova_table instance containing the ANOVA results. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, j, jj, k, r, n + real(real64) :: factorMean, sum_all + real(real64), allocatable :: xpack(:) + + ! Initialization + n = size(x, 3) + k = size(x, 2) + r = size(x, 1) + rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) + rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) + + ! Quick Return + if (k == 1) then + ! This is a one-factor anova + end if + + ! Determine the number of DOF + rst%main_factor_1%dof = k - one + rst%main_factor_2%dof = n - 1 + rst%interaction%dof = (k - 1) * (n - 1) + rst%within_factor%dof = n * k * (r - 1) + rst%total_dof = n * k * r - 1 + + ! Compute the overall mean, sum of squares, and variance + xpack = pack(x, .true.) + rst%overall_mean = mean(xpack) + rst%total_sum_of_squares = sum((xpack - rst%overall_mean)**2) + rst%total_variance = rst%total_sum_of_squares / rst%total_dof + + ! Compute factor 1 results + rst%main_factor_1%sum_of_squares = zero + do i = 1, k + factorMean = mean(pack(x(:,i,:), .true.)) + rst%main_factor_1%sum_of_squares = rst%main_factor_1%sum_of_squares + & + (factorMean - rst%overall_mean)**2 + end do + rst%main_factor_1%sum_of_squares = n * r * rst%main_factor_1%sum_of_squares + rst%main_factor_1%variance = rst%main_factor_1%sum_of_squares / & + rst%main_factor_1%dof + + ! Compute factor 2 results + rst%main_factor_2%sum_of_squares = zero + do i = 1, n + factorMean = mean(pack(x(:,:,i), .true.)) + rst%main_factor_2%sum_of_squares = rst%main_factor_2%sum_of_squares + & + (factorMean - rst%overall_mean)**2 + end do + rst%main_factor_2%sum_of_squares = k * r * rst%main_factor_2%sum_of_squares + rst%main_factor_2%variance = rst%main_factor_2%sum_of_squares / & + rst%main_factor_2%dof + + ! Compute the within (error) term + rst%within_factor%sum_of_squares = zero + do j = 1, k + do i = 1, n + factorMean = mean(x(:,j,i)) + do jj = 1, r + rst%within_factor%sum_of_squares = & + rst%within_factor%sum_of_squares + & + (x(jj,j,i) - factorMean)**2 + end do + end do + end do + rst%within_factor%variance = rst%within_factor%sum_of_squares /& + rst%within_factor%dof + + ! Compute the interaction term + rst%interaction%sum_of_squares = rst%total_sum_of_squares - ( & + rst%main_factor_1%sum_of_squares + & + rst%main_factor_2%sum_of_squares + & + rst%within_factor%sum_of_squares & + ) + rst%interaction%variance = rst%interaction%sum_of_squares / & + rst%interaction%dof + + ! Compute the F-statistics + call anova_probability( & + rst%main_factor_1%variance, & + rst%within_factor%variance, & + rst%main_factor_1%dof, & + rst%within_factor%dof, & + rst%main_factor_1%f_statistic, & + rst%main_factor_1%probability & + ) + call anova_probability( & + rst%main_factor_2%variance, & + rst%within_factor%variance, & + rst%main_factor_2%dof, & + rst%within_factor%dof, & + rst%main_factor_2%f_statistic, & + rst%main_factor_2%probability & + ) + call anova_probability( & + rst%interaction%variance, & + rst%within_factor%variance, & + rst%interaction%dof, & + rst%within_factor%dof, & + rst%interaction%f_statistic, & + rst%interaction%probability & + ) +end function + +! ------------------------------------------------------------------------------ +! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1 +function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) + !! Performs an analysis of variance (ANOVA) on the supplied data set. + integer(int32), intent(in) :: nmodelparams + !! The number of model parameters. + real(real64), intent(in) :: ymeas(:) + !! An N-element array containing the measured dependent variable data. + real(real64), intent(in) :: ymod(:) + !! An N-element array containing the modeled dependent variable data. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the + !! same length. + !! - FS_MEMORY_ERROR: Occurs if a memory error is encountered. + type(single_factor_anova_table) :: rst + !! A single_factor_anova_table instance containing the ANOVA results. + + ! Local Variables + integer(int32) :: n, flag + real(real64), allocatable :: ypack(:) + real(real64) :: sum_all + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + n = size(ymeas) + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + rst%within_factor%f_statistic = ieee_value(sum_all, IEEE_QUIET_NAN) + rst%within_factor%probability = ieee_value(sum_all, IEEE_QUIET_NAN) + + ! Input Checking + if (size(ymod) /= n) then + call report_arrays_not_same_size_error(errmgr, "anova_model_fit", & + "YMEAS", "YMOD", n, size(ymod)) + return + end if + + ! Memory Allocation + allocate(ypack(2 * n), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "anova_model_fit", flag) + return + end if + + ! Determine the number of DOF + rst%main_factor%dof = nmodelparams - 1 + rst%within_factor%dof = n - rst%main_factor%dof - 1 + rst%total_dof = n - 1 + + ! Process + ypack(1:n) = ymeas + ypack(n+1:2*n) = ymod + rst%overall_mean = mean(ypack) + rst%total_sum_of_squares = sum((ymeas - rst%overall_mean)**2) + rst%main_factor%sum_of_squares = sum((ymod - rst%overall_mean)**2) + rst%within_factor%sum_of_squares = sum((ymeas - ymod)**2) + + rst%total_variance = rst%total_sum_of_squares / rst%total_dof + rst%main_factor%variance = rst%main_factor%sum_of_squares / & + rst%main_factor%dof + rst%within_factor%variance = rst%within_factor%sum_of_squares / & + rst%within_factor%dof + + ! Compute the F-statistic and probability term + call anova_probability( & + rst%main_factor%variance, & + rst%within_factor%variance, & + rst%main_factor%dof, & + rst%within_factor%dof, & + rst%main_factor%f_statistic, & + rst%main_factor%probability & + ) + + ! Formatting +100 format(A, I0, A, I0, A) +101 format(A, I0, A) +end function + +! ****************************************************************************** +! PRIVATE ROUTINES +! ------------------------------------------------------------------------------ +subroutine anova_probability(v1, v2, dof1, dof2, f, p) + ! Arguments + real(real64), intent(in) :: v1, v2, dof1, dof2 + real(real64), intent(out) :: f, p + + ! Local Variables + type(f_distribution) :: dist + + ! Process + f = v1 / v2 + dist%d1 = dof1 + dist%d2 = dof2 + p = 1.0d0 - dist%cdf(f) + if (p > 1.0d0) then + p = 2.0d0 - p + end if +end subroutine + +! ------------------------------------------------------------------------------ +end module @@ -617,7 +613,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_bootstrap.f90.html b/doc/sourcefile/fstats_bootstrap.f90.html index 76845d3..3fc4d80 100644 --- a/doc/sourcefile/fstats_bootstrap.f90.html +++ b/doc/sourcefile/fstats_bootstrap.f90.html @@ -74,7 +74,7 @@

            fstats_bootstrap.f90
          • 351 statements + title="11.9% of total for source files.">351 statements
          • @@ -869,7 +869,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_descriptive_statistics.f90.html b/doc/sourcefile/fstats_descriptive_statistics.f90.html index 1aee557..f8b762c 100644 --- a/doc/sourcefile/fstats_descriptive_statistics.f90.html +++ b/doc/sourcefile/fstats_descriptive_statistics.f90.html @@ -74,7 +74,7 @@

            fstats_descriptive_statistics.f90
          • 130 statements + title=" 5.6% of total for source files.">164 statements
          • @@ -156,242 +156,297 @@

            Source Code

            use linalg, only : sort use ferror use fstats_errors - implicit none - private - public :: mean - public :: variance - public :: standard_deviation - public :: median - public :: quantile - public :: trimmed_mean - public :: covariance - -contains -! ------------------------------------------------------------------------------ -pure function mean(x) result(rst) - !! Computes the mean of the values in an array. - real(real64), intent(in) :: x(:) - !! The array of values to analyze. - real(real64) :: rst - !! The result. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - - ! Local Variables - integer(int32) :: i, n - - ! Process - n = size(x) - if (n == 0) then - rst = zero - else - rst = x(1) - do i = 2, n - rst = rst + (x(i) - rst) / i - end do - end if -end function - -! ------------------------------------------------------------------------------ -pure function variance(x) result(rst) - !! Computes the sample variance of the values in an array. - !! - !! The variance computed is the sample variance such that - !! $$ s^2 = \frac{\Sigma \left( x_{i} - \bar{x} \right)^2}{n - 1} $$. - real(real64), intent(in) :: x(:) - !! The array of values to analyze. - real(real64) :: rst - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, n - real(real64) :: oldMean, newMean - - ! Process - n = size(x) - if (n <= 1) then - rst = zero - else - oldMean = x(1) - rst = zero - do i = 2, n - newMean = oldMean + (x(i) - oldMean) / i - rst = rst + (x(i) - oldMean) * (x(i) - newMean) - oldMean = newMean - end do - rst = rst / (n - one) - end if -end function - -! ------------------------------------------------------------------------------ -pure function standard_deviation(x) result(rst) - !! Computes the sample standard deviation of the values in an array. - !! - !! The value computed is the sample standard deviation. - !! $$ s = \sqrt{ \frac{\Sigma \left( x_{i} - \bar{x} \right)^2}{n - 1} } $$ - real(real64), intent(in) :: x(:) - !! The array of values to analyze. - real(real64) :: rst - !! The result. - - ! Process - rst = sqrt(variance(x)) -end function - -! ------------------------------------------------------------------------------ -function median(x) result(rst) - !! Computes the median of the values in an array. - real(real64), intent(inout) :: x(:) - !! The array of values to analyze. On output, this array is sorted into - !! ascending order. - real(real64) :: rst - !! The result. - - ! Parameters - real(real64), parameter :: half = 0.5d0 - - ! Local Variables - integer(int32) :: n, nmid, nmidp1, flag, iflag - - ! Initialization - n = size(x) - nmid = n / 2 - nmidp1 = nmid + 1 - iflag = n - 2 * nmid - - ! Sort the array in ascending order - call sort(x, .true.) - - ! Find the median - if (iflag == 0) then - rst = half * (x(nmid) + x(nmidp1)) - else - rst = x(nmidp1) - end if -end function - -! ------------------------------------------------------------------------------ -! REF: https://fortranwiki.org/fortran/show/Quartiles -! -! This is the method used by Minitab -pure function quantile(x, q) result(rst) - !! Computes the specified quantile of a data set using the SAS - !! Method 4. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Quantile) - real(real64), intent(in) :: x(:) - !! An N-element array containing the data. - real(real64), intent(in) :: q - !! The quantile to compute (e.g. 0.25 computes the 25% quantile). - real(real64) :: rst - !! The result. - - ! Parameters - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - real(real64) :: a, b, c, tol - integer(int32) :: n, ib + use fstats_types + implicit none + private + public :: mean + public :: variance + public :: standard_deviation + public :: median + public :: quantile + public :: trimmed_mean + public :: covariance + public :: pooled_variance + + interface pooled_variance + !! Computes the pooled estimate of variance. + module procedure :: pooled_variance_1 + module procedure :: pooled_variance_2 + end interface +contains +! ------------------------------------------------------------------------------ +pure function mean(x) result(rst) + !! Computes the mean of the values in an array. + real(real64), intent(in) :: x(:) + !! The array of values to analyze. + real(real64) :: rst + !! The result. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + + ! Local Variables + integer(int32) :: i, n + + ! Process + n = size(x) + if (n == 0) then + rst = zero + else + rst = x(1) + do i = 2, n + rst = rst + (x(i) - rst) / i + end do + end if +end function + +! ------------------------------------------------------------------------------ +pure function variance(x) result(rst) + !! Computes the sample variance of the values in an array. + !! + !! The variance computed is the sample variance such that + !! $$ s^2 = \frac{\Sigma \left( x_{i} - \bar{x} \right)^2}{n - 1} $$. + real(real64), intent(in) :: x(:) + !! The array of values to analyze. + real(real64) :: rst + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, n + real(real64) :: oldMean, newMean + + ! Process + n = size(x) + if (n <= 1) then + rst = zero + else + oldMean = x(1) + rst = zero + do i = 2, n + newMean = oldMean + (x(i) - oldMean) / i + rst = rst + (x(i) - oldMean) * (x(i) - newMean) + oldMean = newMean + end do + rst = rst / (n - one) + end if +end function + +! ------------------------------------------------------------------------------ +pure function standard_deviation(x) result(rst) + !! Computes the sample standard deviation of the values in an array. + !! + !! The value computed is the sample standard deviation. + !! $$ s = \sqrt{ \frac{\Sigma \left( x_{i} - \bar{x} \right)^2}{n - 1} } $$ + real(real64), intent(in) :: x(:) + !! The array of values to analyze. + real(real64) :: rst + !! The result. + + ! Process + rst = sqrt(variance(x)) +end function + +! ------------------------------------------------------------------------------ +function median(x) result(rst) + !! Computes the median of the values in an array. + real(real64), intent(inout) :: x(:) + !! The array of values to analyze. On output, this array is sorted into + !! ascending order. + real(real64) :: rst + !! The result. + + ! Parameters + real(real64), parameter :: half = 0.5d0 + + ! Local Variables + integer(int32) :: n, nmid, nmidp1, flag, iflag + + ! Initialization + n = size(x) + nmid = n / 2 + nmidp1 = nmid + 1 + iflag = n - 2 * nmid + + ! Sort the array in ascending order + call sort(x, .true.) + + ! Find the median + if (iflag == 0) then + rst = half * (x(nmid) + x(nmidp1)) + else + rst = x(nmidp1) + end if +end function + +! ------------------------------------------------------------------------------ +! REF: https://fortranwiki.org/fortran/show/Quartiles +! +! This is the method used by Minitab +pure function quantile(x, q) result(rst) + !! Computes the specified quantile of a data set using the SAS + !! Method 4. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Quantile) + real(real64), intent(in) :: x(:) + !! An N-element array containing the data. + real(real64), intent(in) :: q + !! The quantile to compute (e.g. 0.25 computes the 25% quantile). + real(real64) :: rst + !! The result. - ! Initialization - tol = sqrt(epsilon(tol)) - n = size(x) - - ! Process - a = (n + one) * q - b = mod(a, one) - c = a - b - - ib = int(c, int32) - if ((ib + 1) > n) then - rst = (one - b) * x(ib) + b * x(n) - else - rst = (one - b) * x(ib) + b * x(ib + 1) - end if -end function - -! ------------------------------------------------------------------------------ -function trimmed_mean(x, p) result(rst) - !! Computes the trimmed mean of a data set. - real(real64), intent(inout), dimension(:) :: x - !! An N-element array containing the data. On output, the - !! array is sorted into ascending order. - real(real64), intent(in), optional :: p - !! An optional parameter specifying the percentage of values - !! from either end of the distribution to remove. The default - !! is 0.05 such that the bottom 5% and top 5% are removed. - real(real64) :: rst - !! The trimmed mean. - - ! Local Variables - integer(int32) :: i1, i2, n - real(real64) :: pv - - ! Initialization - if (present(p)) then - pv = abs(p) - else - pv = 0.05d0 - end if + ! Parameters + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + real(real64) :: a, b, c, tol + integer(int32) :: n, ib + + ! Initialization + tol = sqrt(epsilon(tol)) + n = size(x) + + ! Process + a = (n + one) * q + b = mod(a, one) + c = a - b + + ib = int(c, int32) + if ((ib + 1) > n) then + rst = (one - b) * x(ib) + b * x(n) + else + rst = (one - b) * x(ib) + b * x(ib + 1) + end if +end function + +! ------------------------------------------------------------------------------ +function trimmed_mean(x, p) result(rst) + !! Computes the trimmed mean of a data set. + real(real64), intent(inout), dimension(:) :: x + !! An N-element array containing the data. On output, the + !! array is sorted into ascending order. + real(real64), intent(in), optional :: p + !! An optional parameter specifying the percentage of values + !! from either end of the distribution to remove. The default + !! is 0.05 such that the bottom 5% and top 5% are removed. + real(real64) :: rst + !! The trimmed mean. + + ! Local Variables + integer(int32) :: i1, i2, n + real(real64) :: pv - ! Sort the array into ascending order - call sort(x, .true.) - - ! Find the limiting indices - n = size(x) - i1 = max(floor(n * pv, int32), 1) - i2 = min(n, n - i1 + 1) - rst = mean(x(i1:i2)) -end function + ! Initialization + if (present(p)) then + pv = abs(p) + else + pv = 0.05d0 + end if + + ! Sort the array into ascending order + call sort(x, .true.) -! ------------------------------------------------------------------------------ -pure function covariance(x, y) result(rst) - !! Computes the sample covariance of two data sets. - !! - !! The covariance computed is the sample covariance such that - !! $$ q_{jk} = \frac{\Sigma \left( x_{i} - \bar{x} \right) - !! \left( y_{i} - \bar{y} \right)}{n - 1} $$. - real(real64), intent(in), dimension(:) :: x - !! The first N-element data set. - real(real64), intent(in), dimension(size(x)) :: y - !! The second N-element data set. - real(real64) :: rst - !! The covariance. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, n - real(real64) :: meanX, meanY - - ! Process - n = size(x) - if (n <= 1) then - rst = zero - else - ! Compute the means - meanX = x(1) - meanY = y(1) - do i = 2, n - meanX = meanX + (x(i) - meanX) / i - meanY = meanY + (y(i) - meanY) / i - end do - - ! Compute the covariance - rst = sum((x - meanX) * (y - meanY)) / (n - one) - end if -end function - -! ------------------------------------------------------------------------------ -end module + ! Find the limiting indices + n = size(x) + i1 = max(floor(n * pv, int32), 1) + i2 = min(n, n - i1 + 1) + rst = mean(x(i1:i2)) +end function + +! ------------------------------------------------------------------------------ +pure function covariance(x, y) result(rst) + !! Computes the sample covariance of two data sets. + !! + !! The covariance computed is the sample covariance such that + !! $$ q_{jk} = \frac{\Sigma \left( x_{i} - \bar{x} \right) + !! \left( y_{i} - \bar{y} \right)}{n - 1} $$. + real(real64), intent(in), dimension(:) :: x + !! The first N-element data set. + real(real64), intent(in), dimension(size(x)) :: y + !! The second N-element data set. + real(real64) :: rst + !! The covariance. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, n + real(real64) :: meanX, meanY + + ! Process + n = size(x) + if (n <= 1) then + rst = zero + else + ! Compute the means + meanX = x(1) + meanY = y(1) + do i = 2, n + meanX = meanX + (x(i) - meanX) / i + meanY = meanY + (y(i) - meanY) / i + end do + + ! Compute the covariance + rst = sum((x - meanX) * (y - meanY)) / (n - one) + end if +end function + +! ------------------------------------------------------------------------------ +pure function pooled_variance_1(si, ni) result(rst) + !! Computes the pooled estimate of variance. + real(real64), intent(in), dimension(:) :: si + !! An N-element array containing the estimates for each of the N + !! variances. + integer(int32), intent(in), dimension(size(si)) :: ni + !! An N-element array containing the number of data points in each + !! of the data sets used to compute the variances in si. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n + + ! Process + k = size(si) + rst = 0.0d0 + n = 0 + do i = 1, k + n = n + ni(i) + rst = rst + (ni(i) - 1.0d0) * si(i) + end do + rst = rst / real(n - k, real64) +end function + +pure function pooled_variance_2(x) result(rst) + !! Computes the pooled estimate of variance. + type(array_container), intent(in), dimension(:) :: x + !! An array of arrays of data. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n, ni + + ! Process + k = size(x) + n = 0 + rst = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + rst = rst + variance(x(i)%x) * (ni - 1.0) + end do + rst = rst / real(n - k, real64) +end function + +! ------------------------------------------------------------------------------ +end module @@ -410,7 +465,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_distributions.f90.html b/doc/sourcefile/fstats_distributions.f90.html index 03695d2..6db10f8 100644 --- a/doc/sourcefile/fstats_distributions.f90.html +++ b/doc/sourcefile/fstats_distributions.f90.html @@ -74,7 +74,7 @@

            fstats_distributions.f90
          • 303 statements + title="11.0% of total for source files.">323 statements
          • @@ -184,601 +184,635 @@

            Source Code

            !! Computes the mode of the distribution. procedure(distribution_property), deferred, pass :: variance !! Computes the variance of the distribution. - end type - - interface - pure elemental function distribution_function(this, x) result(rst) - !! Defines the interface for a probability distribution function. - use iso_fortran_env, only : real64 - import distribution - class(distribution), intent(in) :: this - !! The distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - end function - - pure function distribution_property(this) result(rst) - !! Computes the value of a distribution property. - use iso_fortran_env, only : real64 - import distribution - class(distribution), intent(in) :: this - !! The distribution object. - real(real64) :: rst - !! The property value. - end function - end interface - -! ------------------------------------------------------------------------------ - type, extends(distribution) :: t_distribution - !! Defines Student's T-Distribution. - real(real64) :: dof - !! The number of degrees of freedom. - contains - procedure, public :: pdf => td_pdf - procedure, public :: cdf => td_cdf - procedure, public :: mean => td_mean - procedure, public :: median => td_median - procedure, public :: mode => td_mode - procedure, public :: variance => td_variance - end type -! ------------------------------------------------------------------------------ - type, extends(distribution) :: normal_distribution - !! Defines a normal distribution. - real(real64) :: standard_deviation - !! The standard deviation of the distribution. - real(real64) :: mean_value - !! The mean value of the distribution. - contains - procedure, public :: pdf => nd_pdf - procedure, public :: cdf => nd_cdf - procedure, public :: mean => nd_mean - procedure, public :: median => nd_median - procedure, public :: mode => nd_mode - procedure, public :: variance => nd_variance - procedure, public :: standardize => nd_standardize - end type - -! ------------------------------------------------------------------------------ - type, extends(distribution) :: f_distribution - !! Defines an F-distribution. - real(real64) :: d1 - !! The measure of degrees of freedom for the first data set. - real(real64) :: d2 - !! The measure of degrees of freedom for the second data set. - contains - procedure, public :: pdf => fd_pdf - procedure, public :: cdf => fd_cdf - procedure, public :: mean => fd_mean - procedure, public :: median => fd_median - procedure, public :: mode => fd_mode - procedure, public :: variance => fd_variance - end type - -! ------------------------------------------------------------------------------ - type, extends(distribution) :: chi_squared_distribution - !! Defines a Chi-squared distribution. - integer(int32) :: dof - !! The number of degrees of freedom. - contains - procedure, public :: pdf => cs_pdf - procedure, public :: cdf => cs_cdf - procedure, public :: mean => cs_mean - procedure, public :: median => cs_median - procedure, public :: mode => cs_mode - procedure, public :: variance => cs_variance - end type - -! ------------------------------------------------------------------------------ - type, extends(distribution) :: binomial_distribution - !! Defines a binomial distribution. The binomial distribution describes - !! the probability p of getting k successes in n independent trials. - integer(int32) :: n - !! The number of independent trials. - real(real64) :: p - !! The success probability for each trial. This parameter must - !! exist on the set [0, 1]. - contains - procedure, public :: pdf => bd_pdf - procedure, public :: cdf => bd_cdf - procedure, public :: mean => bd_mean - procedure, public :: median => bd_median - procedure, public :: mode => bd_mode - procedure, public :: variance => bd_variance - end type - -! ------------------------------------------------------------------------------ -contains -! ****************************************************************************** -! STUDENT'S T-DISTRIBUTION -! ------------------------------------------------------------------------------ -! REF: https://en.wikipedia.org/wiki/Student%27s_t-distribution -pure elemental function td_pdf(this, x) result(rst) - !! Computes the probability density function. - !! - !! The PDF for Student's T-Distribution is given as - !! $$ f(t) = \frac{ \Gamma \left( \frac{\nu + 1}{2} \right) } - !! { \sqrt{\nu \pi} \Gamma \left( \frac{\nu}{2} \right) } - !! \left( 1 + \frac{t^2}{\nu} \right)^{-(\nu + 1) / 2} $$. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Process - rst = gamma((this%dof + 1.0d0) / 2.0d0) / & - (sqrt(this%dof * pi) * gamma(this%dof / 2.0d0)) *& - (1.0d0 + x**2 / this%dof)**(-0.5d0 * (1.0d0 + this%dof)) -end function - -! ------------------------------------------------------------------------------ -pure elemental function td_cdf(this, x) result(rst) - !! Computes the cumulative distribution function. - !! - !! The CDF for Student's T-Distribution is given as - !! $$ F(t) = \int_{-\infty}^{t} f(u) \,du = 1 - \frac{1}{2} I_{x(t)} - !! \left( \frac{\nu}{2}, \frac{1}{2} \right) $$ - !! where $$ x(t) = \frac{\nu}{\nu + t^2} $$. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Process - real(real64) :: t - t = this%dof / (this%dof + x**2) - rst = 1.0d0 - 0.5d0 * regularized_beta(0.5d0 * this%dof, 0.5d0, t) - if (x < 0) rst = 1.0d0 - rst -end function - -! ------------------------------------------------------------------------------ -pure function td_mean(this) result(rst) - !! Computes the mean of the distribution. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64) :: rst - !! The mean. - - ! Process - if (this%dof < 1.0d0) then - rst = ieee_value(rst, IEEE_QUIET_NAN) - else - rst = 0.0d0 - end if -end function - -! ------------------------------------------------------------------------------ -pure function td_median(this) result(rst) - !! Computes the median of the distribution. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64) :: rst - - ! Process - rst = 0.0d0 -end function + procedure, public :: standardized_variable => dist_std_var + !! Computes the standardized variable for the distribution. + end type + + interface + pure elemental function distribution_function(this, x) result(rst) + !! Defines the interface for a probability distribution function. + use iso_fortran_env, only : real64 + import distribution + class(distribution), intent(in) :: this + !! The distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + end function + + pure function distribution_property(this) result(rst) + !! Computes the value of a distribution property. + use iso_fortran_env, only : real64 + import distribution + class(distribution), intent(in) :: this + !! The distribution object. + real(real64) :: rst + !! The property value. + end function + end interface + +! ------------------------------------------------------------------------------ + type, extends(distribution) :: t_distribution + !! Defines Student's T-Distribution. + real(real64) :: dof + !! The number of degrees of freedom. + contains + procedure, public :: pdf => td_pdf + procedure, public :: cdf => td_cdf + procedure, public :: mean => td_mean + procedure, public :: median => td_median + procedure, public :: mode => td_mode + procedure, public :: variance => td_variance + end type +! ------------------------------------------------------------------------------ + type, extends(distribution) :: normal_distribution + !! Defines a normal distribution. + real(real64) :: standard_deviation + !! The standard deviation of the distribution. + real(real64) :: mean_value + !! The mean value of the distribution. + contains + procedure, public :: pdf => nd_pdf + procedure, public :: cdf => nd_cdf + procedure, public :: mean => nd_mean + procedure, public :: median => nd_median + procedure, public :: mode => nd_mode + procedure, public :: variance => nd_variance + procedure, public :: standardize => nd_standardize + end type + +! ------------------------------------------------------------------------------ + type, extends(distribution) :: f_distribution + !! Defines an F-distribution. + real(real64) :: d1 + !! The measure of degrees of freedom for the first data set. + real(real64) :: d2 + !! The measure of degrees of freedom for the second data set. + contains + procedure, public :: pdf => fd_pdf + procedure, public :: cdf => fd_cdf + procedure, public :: mean => fd_mean + procedure, public :: median => fd_median + procedure, public :: mode => fd_mode + procedure, public :: variance => fd_variance + end type + +! ------------------------------------------------------------------------------ + type, extends(distribution) :: chi_squared_distribution + !! Defines a Chi-squared distribution. + integer(int32) :: dof + !! The number of degrees of freedom. + contains + procedure, public :: pdf => cs_pdf + procedure, public :: cdf => cs_cdf + procedure, public :: mean => cs_mean + procedure, public :: median => cs_median + procedure, public :: mode => cs_mode + procedure, public :: variance => cs_variance + end type + +! ------------------------------------------------------------------------------ + type, extends(distribution) :: binomial_distribution + !! Defines a binomial distribution. The binomial distribution describes + !! the probability p of getting k successes in n independent trials. + integer(int32) :: n + !! The number of independent trials. + real(real64) :: p + !! The success probability for each trial. This parameter must + !! exist on the set [0, 1]. + contains + procedure, public :: pdf => bd_pdf + procedure, public :: cdf => bd_cdf + procedure, public :: mean => bd_mean + procedure, public :: median => bd_median + procedure, public :: mode => bd_mode + procedure, public :: variance => bd_variance + end type + +contains +! ------------------------------------------------------------------------------ +pure elemental function dist_std_var(this, x) result(rst) + !! Computes the standardized variable for the distribution. + class(distribution), intent(in) :: this + !! The distribution object. + real(real64), intent(in) :: x + !! The value of interest. + real(real64) :: rst + !! The result. + + ! Local Variables + integer(int32), parameter :: maxiter = 100 + real(real64), parameter :: tol = 1.0d-6 + integer(int32) :: i + real(real64) :: f, df, h, twoh, dy + + ! Process + ! + ! We use a simplified Newton's method to solve for the independent variable + ! of the CDF function + h = 1.0d-6 + twoh = 2.0d0 * h + rst = 0.5d0 ! just an initial guess + do i = 1, maxiter + ! Compute the CDF and its derivative at y + f = this%cdf(rst) - x + df = (this%cdf(rst + h) - this%cdf(rst - h)) / twoh + dy = f / df + rst = rst - dy + if (abs(dy) < tol) exit + end do +end function + +! ****************************************************************************** +! STUDENT'S T-DISTRIBUTION +! ------------------------------------------------------------------------------ +! REF: https://en.wikipedia.org/wiki/Student%27s_t-distribution +pure elemental function td_pdf(this, x) result(rst) + !! Computes the probability density function. + !! + !! The PDF for Student's T-Distribution is given as + !! $$ f(t) = \frac{ \Gamma \left( \frac{\nu + 1}{2} \right) } + !! { \sqrt{\nu \pi} \Gamma \left( \frac{\nu}{2} \right) } + !! \left( 1 + \frac{t^2}{\nu} \right)^{-(\nu + 1) / 2} $$. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + ! Process + rst = gamma((this%dof + 1.0d0) / 2.0d0) / & + (sqrt(this%dof * pi) * gamma(this%dof / 2.0d0)) *& + (1.0d0 + x**2 / this%dof)**(-0.5d0 * (1.0d0 + this%dof)) +end function + +! ------------------------------------------------------------------------------ +pure elemental function td_cdf(this, x) result(rst) + !! Computes the cumulative distribution function. + !! + !! The CDF for Student's T-Distribution is given as + !! $$ F(t) = \int_{-\infty}^{t} f(u) \,du = 1 - \frac{1}{2} I_{x(t)} + !! \left( \frac{\nu}{2}, \frac{1}{2} \right) $$ + !! where $$ x(t) = \frac{\nu}{\nu + t^2} $$. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. -! ------------------------------------------------------------------------------ -pure function td_mode(this) result(rst) - !! Computes the mode of the distribution. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64) :: rst - !! The mode. - - ! Process - rst = 0.0d0 -end function - -! ------------------------------------------------------------------------------ -pure function td_variance(this) result(rst) - !! Computes the variance of the distribution. - class(t_distribution), intent(in) :: this - !! The t_distribution object. - real(real64) :: rst - !! The variance. - - ! Process - if (this%dof <= 1.0d0) then - rst = ieee_value(rst, IEEE_QUIET_NAN) - else if (this%dof > 1.0d0 .and. this%dof <= 2.0d0) then - rst = ieee_value(rst, IEEE_POSITIVE_INF) - else - rst = this%dof / (this%dof - 2.0d0) - end if -end function + ! Process + real(real64) :: t + t = this%dof / (this%dof + x**2) + rst = 1.0d0 - 0.5d0 * regularized_beta(0.5d0 * this%dof, 0.5d0, t) + if (x < 0) rst = 1.0d0 - rst +end function + +! ------------------------------------------------------------------------------ +pure function td_mean(this) result(rst) + !! Computes the mean of the distribution. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64) :: rst + !! The mean. + + ! Process + if (this%dof < 1.0d0) then + rst = ieee_value(rst, IEEE_QUIET_NAN) + else + rst = 0.0d0 + end if +end function + +! ------------------------------------------------------------------------------ +pure function td_median(this) result(rst) + !! Computes the median of the distribution. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64) :: rst -! ****************************************************************************** -! NORMAL DISTRIBUTION -! ------------------------------------------------------------------------------ -pure elemental function nd_pdf(this, x) result(rst) - !! Computes the probability density function. - !! - !! The PDF for a normal distribution is given as - !! $$ f(x) = \frac{1}{\sigma \sqrt{2 \pi}} \exp \left(-\frac{1}{2} - !! \left( \frac{x - \mu}{\sigma} \right)^2 \right) $$. - class(normal_distribution), intent(in) :: this - !! The normal_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. + ! Process + rst = 0.0d0 +end function + +! ------------------------------------------------------------------------------ +pure function td_mode(this) result(rst) + !! Computes the mode of the distribution. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64) :: rst + !! The mode. + + ! Process + rst = 0.0d0 +end function - rst = exp(-0.5d0 * ((x - this%mean_value) / this%standard_deviation)**2) / & - (this%standard_deviation * sqrt(2.0d0 * pi)) -end function - -! ------------------------------------------------------------------------------ -pure elemental function nd_cdf(this, x) result(rst) - !! Computes the cumulative distribution function. - !! - !! The CDF for a normal distribution is given as - !! $$ F(x) = \frac{1}{2} \left( 1 + erf \left( \frac{x - \mu} - !! {\sigma \sqrt{2}} \right) \right) $$. - class(normal_distribution), intent(in) :: this - !! The normal_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. +! ------------------------------------------------------------------------------ +pure function td_variance(this) result(rst) + !! Computes the variance of the distribution. + class(t_distribution), intent(in) :: this + !! The t_distribution object. + real(real64) :: rst + !! The variance. + + ! Process + if (this%dof <= 1.0d0) then + rst = ieee_value(rst, IEEE_QUIET_NAN) + else if (this%dof > 1.0d0 .and. this%dof <= 2.0d0) then + rst = ieee_value(rst, IEEE_POSITIVE_INF) + else + rst = this%dof / (this%dof - 2.0d0) + end if +end function - rst = 0.5d0 * (1.0d0 + erf((x - this%mean_value) / & - (this%standard_deviation * sqrt(2.0d0)))) -end function - -! ------------------------------------------------------------------------------ -pure function nd_mean(this) result(rst) - !! Computes the mean of the distribution. - class(normal_distribution), intent(in) :: this - !! The normal_distribution object. - real(real64) :: rst - !! The mean - rst = this%mean_value -end function - -! ------------------------------------------------------------------------------ -pure function nd_median(this) result(rst) - !! Computes the median of the distribution. - class(normal_distribution), intent(in) :: this - !! The normal_distribution object. - real(real64) :: rst - !! The median. - rst = this%mean_value -end function - -! ------------------------------------------------------------------------------ -pure function nd_mode(this) result(rst) - !! Computes the mode of the distribution. +! ****************************************************************************** +! NORMAL DISTRIBUTION +! ------------------------------------------------------------------------------ +pure elemental function nd_pdf(this, x) result(rst) + !! Computes the probability density function. + !! + !! The PDF for a normal distribution is given as + !! $$ f(x) = \frac{1}{\sigma \sqrt{2 \pi}} \exp \left(-\frac{1}{2} + !! \left( \frac{x - \mu}{\sigma} \right)^2 \right) $$. + class(normal_distribution), intent(in) :: this + !! The normal_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + rst = exp(-0.5d0 * ((x - this%mean_value) / this%standard_deviation)**2) / & + (this%standard_deviation * sqrt(2.0d0 * pi)) +end function + +! ------------------------------------------------------------------------------ +pure elemental function nd_cdf(this, x) result(rst) + !! Computes the cumulative distribution function. + !! + !! The CDF for a normal distribution is given as + !! $$ F(x) = \frac{1}{2} \left( 1 + erf \left( \frac{x - \mu} + !! {\sigma \sqrt{2}} \right) \right) $$. class(normal_distribution), intent(in) :: this !! The normal_distribution object. - real(real64) :: rst - !! The mode. - rst = this%mean_value -end function + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. -! ------------------------------------------------------------------------------ -pure function nd_variance(this) result(rst) - !! Computes the variance of the distribution. - class(normal_distribution), intent(in) :: this - !! The normal_distribution object. - real(real64) :: rst - !! The variance. - rst = this%standard_deviation**2 -end function - -! ------------------------------------------------------------------------------ -subroutine nd_standardize(this) - !! Standardizes the normal distribution to a mean of 0 and a - !! standard deviation of 1. - class(normal_distribution), intent(inout) :: this - !! The normal_distribution object. - this%mean_value = 0.0d0 - this%standard_deviation = 1.0d0 -end subroutine - -! ****************************************************************************** -! F DISTRIBUTION -! ------------------------------------------------------------------------------ -pure elemental function fd_pdf(this, x) result(rst) - !! Computes the probability density function. - !! - !! The PDF for a F distribution is given as - !! $$ f(x) = - !! \sqrt{ \frac{ (d_1 x)^{d_1} d_{2}^{d_2} }{ (d_1 x + d_2)^{d_1 + d_2} } } - !! \frac{1}{x \beta \left( \frac{d_1}{2}, \frac{d_2}{2} \right) } $$. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Process - real(real64) :: d1, d2 - d1 = this%d1 - d2 = this%d2 - rst = (1.0d0 / beta(0.5d0 * d1, 0.5d0 * d2)) * (d1 / d2)**(0.5d0 * d1) * & - x**(0.5d0 * d1 - 1.0d0) * (1.0d0 + d1 * x/ d2)**(-0.5d0 * (d1 + d2)) -end function - -! ------------------------------------------------------------------------------ -pure elemental function fd_cdf(this, x) result(rst) - !! Computes the cumulative distribution function. - !! - !! The CDF for a F distribution is given as - !! $$ F(x) = I_{d_1 x/(d_1 x + d_2)} \left( \frac{d_1}{2}, - !! \frac{d_2}{2} \right) $$. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Process - real(real64) :: d1, d2 - d1 = this%d1 - d2 = this%d2 - rst = regularized_beta(0.5d0 * d1, 0.5d0 * d2, d1 * x / (d1 * x + d2)) -end function - -! ------------------------------------------------------------------------------ -pure function fd_mean(this) result(rst) - !! Computes the mean of the distribution. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64) :: rst - !! The mean. - - ! Process - if (this%d2 > 2.0d0) then - rst = this%d2 / (this%d2 - 2.0d0) - else - rst = ieee_value(rst, IEEE_QUIET_NAN) - end if -end function - -! ------------------------------------------------------------------------------ -pure function fd_median(this) result(rst) - !! Computes the median of the distribution. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64) :: rst - !! The median. - rst = ieee_value(rst, IEEE_QUIET_NAN) -end function - -! ------------------------------------------------------------------------------ -pure function fd_mode(this) result(rst) - !! Computes the mode of the distribution. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64) :: rst - !! The mode. + rst = 0.5d0 * (1.0d0 + erf((x - this%mean_value) / & + (this%standard_deviation * sqrt(2.0d0)))) +end function + +! ------------------------------------------------------------------------------ +pure function nd_mean(this) result(rst) + !! Computes the mean of the distribution. + class(normal_distribution), intent(in) :: this + !! The normal_distribution object. + real(real64) :: rst + !! The mean + rst = this%mean_value +end function + +! ------------------------------------------------------------------------------ +pure function nd_median(this) result(rst) + !! Computes the median of the distribution. + class(normal_distribution), intent(in) :: this + !! The normal_distribution object. + real(real64) :: rst + !! The median. + rst = this%mean_value +end function + +! ------------------------------------------------------------------------------ +pure function nd_mode(this) result(rst) + !! Computes the mode of the distribution. + class(normal_distribution), intent(in) :: this + !! The normal_distribution object. + real(real64) :: rst + !! The mode. + rst = this%mean_value +end function + +! ------------------------------------------------------------------------------ +pure function nd_variance(this) result(rst) + !! Computes the variance of the distribution. + class(normal_distribution), intent(in) :: this + !! The normal_distribution object. + real(real64) :: rst + !! The variance. + rst = this%standard_deviation**2 +end function + +! ------------------------------------------------------------------------------ +subroutine nd_standardize(this) + !! Standardizes the normal distribution to a mean of 0 and a + !! standard deviation of 1. + class(normal_distribution), intent(inout) :: this + !! The normal_distribution object. + this%mean_value = 0.0d0 + this%standard_deviation = 1.0d0 +end subroutine + +! ****************************************************************************** +! F DISTRIBUTION +! ------------------------------------------------------------------------------ +pure elemental function fd_pdf(this, x) result(rst) + !! Computes the probability density function. + !! + !! The PDF for a F distribution is given as + !! $$ f(x) = + !! \sqrt{ \frac{ (d_1 x)^{d_1} d_{2}^{d_2} }{ (d_1 x + d_2)^{d_1 + d_2} } } + !! \frac{1}{x \beta \left( \frac{d_1}{2}, \frac{d_2}{2} \right) } $$. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + ! Process + real(real64) :: d1, d2 + d1 = this%d1 + d2 = this%d2 + rst = (1.0d0 / beta(0.5d0 * d1, 0.5d0 * d2)) * (d1 / d2)**(0.5d0 * d1) * & + x**(0.5d0 * d1 - 1.0d0) * (1.0d0 + d1 * x/ d2)**(-0.5d0 * (d1 + d2)) +end function + +! ------------------------------------------------------------------------------ +pure elemental function fd_cdf(this, x) result(rst) + !! Computes the cumulative distribution function. + !! + !! The CDF for a F distribution is given as + !! $$ F(x) = I_{d_1 x/(d_1 x + d_2)} \left( \frac{d_1}{2}, + !! \frac{d_2}{2} \right) $$. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + ! Process + real(real64) :: d1, d2 + d1 = this%d1 + d2 = this%d2 + rst = regularized_beta(0.5d0 * d1, 0.5d0 * d2, d1 * x / (d1 * x + d2)) +end function - ! Process - if (this%d1 > 2.0d0) then - rst = ((this%d1 - 2.0d0) / this%d1) * (this%d2 / (this%d2 + 2.0d0)) - else - rst = ieee_value(rst, IEEE_QUIET_NAN) - end if -end function +! ------------------------------------------------------------------------------ +pure function fd_mean(this) result(rst) + !! Computes the mean of the distribution. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64) :: rst + !! The mean. -! ------------------------------------------------------------------------------ -pure function fd_variance(this) result(rst) - !! Computes the variance of the distribution. - class(f_distribution), intent(in) :: this - !! The f_distribution object. - real(real64) :: rst - !! The variance. + ! Process + if (this%d2 > 2.0d0) then + rst = this%d2 / (this%d2 - 2.0d0) + else + rst = ieee_value(rst, IEEE_QUIET_NAN) + end if +end function - ! Process - real(real64) :: d1, d2 - d1 = this%d1 - d2 = this%d2 - if (d2 > 4.0d0) then - rst = (2.0d0 * d2**2 * (d1 + d2 - 2.0d0)) / & - (d1 * (d2 - 2.0d0)**2 * (d2 - 4.0d0)) - else - rst = ieee_value(rst, IEEE_QUIET_NAN) - end if -end function - -! ****************************************************************************** -! CHI-SQUARED DISTRIBUTION -! ------------------------------------------------------------------------------ -pure elemental function cs_pdf(this, x) result(rst) - !! Computes the probability density function. - !! - !! The PDF for a Chi-squared distribution is given as - !! $$ f(x) = \frac{x^{k/2 - 1} \exp{-x / 2}} {2^{k / 2} - !! \Gamma \left( \frac{k}{2} \right)} $$. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Local Variables - real(real64) :: arg - - ! Process - arg = 0.5d0 * this%dof - rst = 1.0d0 / (2.0d0**arg * gamma(arg)) * x**(arg - 1.0d0) * exp(-0.5d0 * x) -end function - -! ------------------------------------------------------------------------------ -pure elemental function cs_cdf(this, x) result(rst) - !! Computes the cumulative distribution function. - !! - !! The CDF for a Chi-squared distribution is given as - !! $$ F(x) = \frac{ \gamma \left( \frac{k}{2}, \frac{x}{2} \right) } - !! { \Gamma \left( \frac{k}{2} \right)} $$. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. - real(real64) :: rst - !! The value of the function. - - ! Local Variables - real(real64) :: arg - - ! Process - arg = 0.5d0 * this%dof - rst = incomplete_gamma_lower(arg, 0.5d0 * x) / gamma(arg) -end function - -! ------------------------------------------------------------------------------ -pure function cs_mean(this) result(rst) - !! Computes the mean of the distribution. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64) :: rst - !! The mean. - - ! Process - rst = real(this%dof, real64) +! ------------------------------------------------------------------------------ +pure function fd_median(this) result(rst) + !! Computes the median of the distribution. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64) :: rst + !! The median. + rst = ieee_value(rst, IEEE_QUIET_NAN) +end function + +! ------------------------------------------------------------------------------ +pure function fd_mode(this) result(rst) + !! Computes the mode of the distribution. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64) :: rst + !! The mode. + + ! Process + if (this%d1 > 2.0d0) then + rst = ((this%d1 - 2.0d0) / this%d1) * (this%d2 / (this%d2 + 2.0d0)) + else + rst = ieee_value(rst, IEEE_QUIET_NAN) + end if +end function + +! ------------------------------------------------------------------------------ +pure function fd_variance(this) result(rst) + !! Computes the variance of the distribution. + class(f_distribution), intent(in) :: this + !! The f_distribution object. + real(real64) :: rst + !! The variance. + + ! Process + real(real64) :: d1, d2 + d1 = this%d1 + d2 = this%d2 + if (d2 > 4.0d0) then + rst = (2.0d0 * d2**2 * (d1 + d2 - 2.0d0)) / & + (d1 * (d2 - 2.0d0)**2 * (d2 - 4.0d0)) + else + rst = ieee_value(rst, IEEE_QUIET_NAN) + end if +end function + +! ****************************************************************************** +! CHI-SQUARED DISTRIBUTION +! ------------------------------------------------------------------------------ +pure elemental function cs_pdf(this, x) result(rst) + !! Computes the probability density function. + !! + !! The PDF for a Chi-squared distribution is given as + !! $$ f(x) = \frac{x^{k/2 - 1} \exp{-x / 2}} {2^{k / 2} + !! \Gamma \left( \frac{k}{2} \right)} $$. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + ! Local Variables + real(real64) :: arg + + ! Process + arg = 0.5d0 * this%dof + rst = 1.0d0 / (2.0d0**arg * gamma(arg)) * x**(arg - 1.0d0) * exp(-0.5d0 * x) end function ! ------------------------------------------------------------------------------ -pure function cs_median(this) result(rst) - !! Computes the median of the distribution. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64) :: rst - !! The median. - - ! Process - rst = this%dof * (1.0d0 - 2.0d0 / (9.0d0 * this%dof))**3 -end function - -! ------------------------------------------------------------------------------ -pure function cs_mode(this) result(rst) - !! Computes the mode of the distribution. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64) :: rst - !! The mode. - - ! Process - rst = max(this%dof - 2.0d0, 0.0d0) -end function - -! ------------------------------------------------------------------------------ -pure function cs_variance(this) result(rst) - !! Computes the variance of the distribution. - class(chi_squared_distribution), intent(in) :: this - !! The chi_squared_distribution object. - real(real64) :: rst - !! The variance. - - ! Process - rst = 2.0d0 * this%dof -end function - -! ****************************************************************************** -! BINOMIAL DISTRIBUTION -! ------------------------------------------------------------------------------ -pure elemental function bd_pdf(this, x) result(rst) - !! Computes the probability mass function. - !! - !! The PMF for a binomial distribution is given as - !! $$ f(k,n,p) = \frac{n!}{k! \left( n - k! \right)} p^k - !! \left( 1 - p \right)^{n-k} $$. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. This parameter - !! is the number k successes in the n independent trials. As - !! such, this parameter must exist on the set [0, n]. +pure elemental function cs_cdf(this, x) result(rst) + !! Computes the cumulative distribution function. + !! + !! The CDF for a Chi-squared distribution is given as + !! $$ F(x) = \frac{ \gamma \left( \frac{k}{2}, \frac{x}{2} \right) } + !! { \Gamma \left( \frac{k}{2} \right)} $$. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. + real(real64) :: rst + !! The value of the function. + + ! Local Variables + real(real64) :: arg + + ! Process + arg = 0.5d0 * this%dof + rst = incomplete_gamma_lower(arg, 0.5d0 * x) / gamma(arg) +end function + +! ------------------------------------------------------------------------------ +pure function cs_mean(this) result(rst) + !! Computes the mean of the distribution. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. + real(real64) :: rst + !! The mean. + + ! Process + rst = real(this%dof, real64) +end function + +! ------------------------------------------------------------------------------ +pure function cs_median(this) result(rst) + !! Computes the median of the distribution. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. + real(real64) :: rst + !! The median. + + ! Process + rst = this%dof * (1.0d0 - 2.0d0 / (9.0d0 * this%dof))**3 +end function + +! ------------------------------------------------------------------------------ +pure function cs_mode(this) result(rst) + !! Computes the mode of the distribution. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. real(real64) :: rst - !! The value of the function. + !! The mode. - ! Local Variables - real(real64) :: dn - - ! Process - dn = real(this%n, real64) - rst = (factorial(dn) / (factorial(x) * factorial(dn - x))) * (this%p**x) * (1.0d0 - this%p)**(dn - x) -end function - -! ------------------------------------------------------------------------------ -pure elemental function bd_cdf(this, x) result(rst) - !! Computes the cumulative distribution funtion. - !! - !! The CDF for a binomial distribution is given as - !! $$ F(k,n,p) = I_{1-p} \left( n - k, 1 + k \right) $$, which is simply - !! the regularized incomplete beta function. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64), intent(in) :: x - !! The value at which to evaluate the function. This parameter - !! is the number k successes in the n independent trials. As - !! such, this parameter must exist on the set [0, n]. - real(real64) :: rst - !! The value of the function. - - ! Local Variables - real(real64) :: dn - - ! Process - dn = real(this%n, real64) - rst = regularized_beta(dn - x, x + 1.0d0, 1.0d0 - this%p) -end function - -! ------------------------------------------------------------------------------ -pure function bd_mean(this) result(rst) - !! Computes the mean of the distribution. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64) :: rst - !! The mean. - - rst = real(this%n * this%p, real64) -end function - -! ------------------------------------------------------------------------------ -pure function bd_median(this) result(rst) - !! Computes the median of the distribution. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64) :: rst - !! The median. - - rst = real(this%n * this%p, real64) -end function - -! ------------------------------------------------------------------------------ -pure function bd_mode(this) result(rst) - !! Computes the mode of the distribution. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64) :: rst - !! The mode. - - rst = (this%n + 1.0d0) * this%p -end function - -! ------------------------------------------------------------------------------ -pure function bd_variance(this) result(rst) - !! Computes the variance of the distribution. - class(binomial_distribution), intent(in) :: this - !! The binomial_distribution object. - real(real64) :: rst - !! The variance. - - rst = this%n * this%p * (1.0d0 - this%p) -end function - -! ------------------------------------------------------------------------------ -end module + ! Process + rst = max(this%dof - 2.0d0, 0.0d0) +end function + +! ------------------------------------------------------------------------------ +pure function cs_variance(this) result(rst) + !! Computes the variance of the distribution. + class(chi_squared_distribution), intent(in) :: this + !! The chi_squared_distribution object. + real(real64) :: rst + !! The variance. + + ! Process + rst = 2.0d0 * this%dof +end function + +! ****************************************************************************** +! BINOMIAL DISTRIBUTION +! ------------------------------------------------------------------------------ +pure elemental function bd_pdf(this, x) result(rst) + !! Computes the probability mass function. + !! + !! The PMF for a binomial distribution is given as + !! $$ f(k,n,p) = \frac{n!}{k! \left( n - k! \right)} p^k + !! \left( 1 - p \right)^{n-k} $$. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. This parameter + !! is the number k successes in the n independent trials. As + !! such, this parameter must exist on the set [0, n]. + real(real64) :: rst + !! The value of the function. + + ! Local Variables + real(real64) :: dn + + ! Process + dn = real(this%n, real64) + rst = (factorial(dn) / (factorial(x) * factorial(dn - x))) * (this%p**x) * (1.0d0 - this%p)**(dn - x) +end function + +! ------------------------------------------------------------------------------ +pure elemental function bd_cdf(this, x) result(rst) + !! Computes the cumulative distribution funtion. + !! + !! The CDF for a binomial distribution is given as + !! $$ F(k,n,p) = I_{1-p} \left( n - k, 1 + k \right) $$, which is simply + !! the regularized incomplete beta function. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64), intent(in) :: x + !! The value at which to evaluate the function. This parameter + !! is the number k successes in the n independent trials. As + !! such, this parameter must exist on the set [0, n]. + real(real64) :: rst + !! The value of the function. + + ! Local Variables + real(real64) :: dn + + ! Process + dn = real(this%n, real64) + rst = regularized_beta(dn - x, x + 1.0d0, 1.0d0 - this%p) +end function + +! ------------------------------------------------------------------------------ +pure function bd_mean(this) result(rst) + !! Computes the mean of the distribution. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64) :: rst + !! The mean. + + rst = real(this%n * this%p, real64) +end function + +! ------------------------------------------------------------------------------ +pure function bd_median(this) result(rst) + !! Computes the median of the distribution. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64) :: rst + !! The median. + + rst = real(this%n * this%p, real64) +end function + +! ------------------------------------------------------------------------------ +pure function bd_mode(this) result(rst) + !! Computes the mode of the distribution. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64) :: rst + !! The mode. + + rst = (this%n + 1.0d0) * this%p +end function + +! ------------------------------------------------------------------------------ +pure function bd_variance(this) result(rst) + !! Computes the variance of the distribution. + class(binomial_distribution), intent(in) :: this + !! The binomial_distribution object. + real(real64) :: rst + !! The variance. + + rst = this%n * this%p * (1.0d0 - this%p) +end function + +! ------------------------------------------------------------------------------ +end module @@ -797,7 +831,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_errors.f90.html b/doc/sourcefile/fstats_errors.f90.html index 6fe63fa..864c926 100644 --- a/doc/sourcefile/fstats_errors.f90.html +++ b/doc/sourcefile/fstats_errors.f90.html @@ -74,7 +74,7 @@

            fstats_errors.f90
          • 80 statements + title=" 2.7% of total for source files.">80 statements
          • @@ -353,7 +353,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_experimental_design.f90.html b/doc/sourcefile/fstats_experimental_design.f90.html index 3ef3ca7..9025cfa 100644 --- a/doc/sourcefile/fstats_experimental_design.f90.html +++ b/doc/sourcefile/fstats_experimental_design.f90.html @@ -74,7 +74,7 @@

            fstats_experimental_design.f90
          • 66 statements + title=" 2.2% of total for source files.">66 statements
          • @@ -338,7 +338,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_helper_routines.f90.html b/doc/sourcefile/fstats_helper_routines.f90.html index 8aa5f93..bd696aa 100644 --- a/doc/sourcefile/fstats_helper_routines.f90.html +++ b/doc/sourcefile/fstats_helper_routines.f90.html @@ -209,7 +209,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_hypothesis.f90.html b/doc/sourcefile/fstats_hypothesis.f90.html index 0d23f32..0529f89 100644 --- a/doc/sourcefile/fstats_hypothesis.f90.html +++ b/doc/sourcefile/fstats_hypothesis.f90.html @@ -74,7 +74,7 @@

            fstats_hypothesis.f90
          • 175 statements + title=" 9.1% of total for source files.">268 statements
          • @@ -158,315 +158,499 @@

            Source Code

            use fstats_special_functions use fstats_distributions use fstats_descriptive_statistics - private - public :: confidence_interval - public :: t_test_equal_variance - public :: t_test_unequal_variance - public :: t_test_paired - public :: f_test - - interface confidence_interval - !! Computes the confidence interval for the specified distribution. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Confidence_interval) - module procedure :: confidence_interval_scalar - module procedure :: confidence_interval_array - end interface -contains -! ------------------------------------------------------------------------------ -pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) - !! Computes the confidence interval for the specified distribution. - class(distribution), intent(in) :: dist - !! The distribution object defining the probability distribution - !! to establish the confidence level. - real(real64), intent(in) :: alpha - !! The probability value of interest. For instance, use a value of 0.05 - !! for a confidence level of 95%. - real(real64), intent(in) :: s - !! The sample standard deviation. - integer(int32), intent(in) :: n - !! The number of samples in the data set. - real(real64) :: rst - !! The result. - - ! Local Variables - integer(int32), parameter :: maxiter = 100 - real(real64), parameter :: tol = 1.0d-6 - integer(int32) :: i - real(real64) :: x, f, df, h, twoh, dy - - ! Process - ! - ! We use a simplified Newton's method to solve for the independent variable - ! of the CDF function where it equals 1 - alpha / 2. - h = 1.0d-6 - twoh = 2.0d0 * h - x = 1.0d0 - alpha / 2.0d0 - rst = 0.5d0 - do i = 1, maxiter - ! Compute the CDF and its derivative at y - f = dist%cdf(rst) - x - df = (dist%cdf(rst + h) - dist%cdf(rst - h)) / twoh - dy = f / df - rst = rst - dy - if (abs(dy) < tol) exit - end do - - ! Determine the actual interval - rst = rst * s / sqrt(real(n, real64)) -end function + use fstats_types + private + public :: confidence_interval + public :: t_test_equal_variance + public :: t_test_unequal_variance + public :: t_test_paired + public :: f_test + public :: bartletts_test + public :: levenes_test + public :: sample_size + + interface confidence_interval + !! Computes the confidence interval for the specified distribution. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Confidence_interval) + module procedure :: confidence_interval_scalar + module procedure :: confidence_interval_array + end interface +contains +! ------------------------------------------------------------------------------ +pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) + !! Computes the confidence interval for the specified distribution. + class(distribution), intent(in) :: dist + !! The distribution object defining the probability distribution + !! to establish the confidence level. + real(real64), intent(in) :: alpha + !! The probability value of interest. For instance, use a value of 0.05 + !! for a confidence level of 95%. + real(real64), intent(in) :: s + !! The sample standard deviation. + integer(int32), intent(in) :: n + !! The number of samples in the data set. + real(real64) :: rst + !! The result. + + ! Local Variables + real(real64) :: x + + ! Process + x = 1.0d0 - alpha / 2.0d0 + rst = dist%standardized_variable(x) + rst = rst * s / sqrt(real(n, real64)) +end function + +! ------------------------------------------------------------------------------ +pure function confidence_interval_array(dist, alpha, x) result(rst) + !! Computes the confidence interval for the specified distribution. + class(distribution), intent(in) :: dist + !! The distribution object defining the probability distribution + !! to establish the confidence level. + real(real64), intent(in) :: alpha + !! The probability value of interest. For instance, use a value of 0.05 + !! for a confidence level of 95%. + real(real64), intent(in) :: x(:) + !! An N-element array containing the data to analyze. + real(real64) :: rst + !! The result. -! ------------------------------------------------------------------------------ -pure function confidence_interval_array(dist, alpha, x) result(rst) - !! Computes the confidence interval for the specified distribution. - class(distribution), intent(in) :: dist - !! The distribution object defining the probability distribution - !! to establish the confidence level. - real(real64), intent(in) :: alpha - !! The probability value of interest. For instance, use a value of 0.05 - !! for a confidence level of 95%. - real(real64), intent(in) :: x(:) - !! An N-element array containing the data to analyze. - real(real64) :: rst - !! The result. - - ! Process - rst = confidence_interval(dist, alpha, standard_deviation(x), size(x)) -end function - -! ------------------------------------------------------------------------------ -subroutine t_test_equal_variance(x1, x2, stat, p, dof) - !! Computes the 2-tailed Student's T-Test for two data sets of - !! assumed equivalent variances. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) - real(real64), intent(in) :: x1(:) - !! An N-element array containing the first data set. - real(real64), intent(in) :: x2(:) - !! An M-element array containing the second data set. - real(real64), intent(out) :: stat - !! The Student-'s T-Test statistic. - real(real64), intent(out) :: p - !! The probability value that the two samples are likely to - !! have come from two underlying populations that - !! have the same mean. - real(real64), intent(out) :: dof - !! The degrees of freedom. - - ! Parameters - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - real(real64), parameter :: two = 2.0d0 - - ! Local Variables - real(real64) :: v1, v2, m1, m2, sv, a, b, x - integer(int32) :: n1, n2 - - ! Compute the T-statistic - n1 = size(x1) - n2 = size(x2) - m1 = mean(x1) - m2 = mean(x2) - v1 = variance(x1) - v2 = variance(x2) - dof = n1 + n2 - two - sv = ((n1 - one) * v1 + (n2 - one) * v2) / dof - stat = abs(m1 - m2) / sqrt(sv * (one / real(n1) + one / real(n2))) - - ! Compute the probability - a = half * dof - b = half - x = dof / (dof + stat**2) - p = regularized_beta(a, b, x) -end subroutine - -! ------------------------------------------------------------------------------ -subroutine t_test_unequal_variance(x1, x2, stat, p, dof) - !! Computes the 2-tailed Student's T-Test for two data sets of - !! assumed non-equivalent variances. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) - real(real64), intent(in) :: x1(:) - !! An N-element array containing the first data set. - real(real64), intent(in) :: x2(:) - !! An M-element array containing the second data set. - real(real64), intent(out) :: stat - !! The Student-'s T-Test statistic. - real(real64), intent(out) :: p - !! The probability value that the two samples are likely to - !! have come from two underlying populations that - !! have the same mean. - real(real64), intent(out) :: dof - !! The degrees of freedom. - - ! Parameters - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - real(real64) :: v1, v2, m1, m2, sv, a, b, x - integer(int32) :: n1, n2 - - ! Compute the T-statistic - n1 = size(x1) - n2 = size(x2) - m1 = mean(x1) - m2 = mean(x2) - v1 = variance(x1) - v2 = variance(x2) - dof = (v1 / real(n1) + v2 / real(n2))**2 / ((v1 / n1)**2 / (n1 - one) + & - (v2 / n2)**2 / (n2 - one)) - sv = sqrt(v1 / n1 + v2 / n2) - stat = (m1 - m2) / sv - - ! Compute the probability - a = half * dof - b = half - x = dof / (dof + stat**2) - p = regularized_beta(a, b, x) -end subroutine - -! ------------------------------------------------------------------------------ -subroutine t_test_paired(x1, x2, stat, p, dof, err) - !! Computes the 2-tailed Student's T-Test for two paired data sets. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) - real(real64), intent(in) :: x1(:) - !! An N-element array containing the first data set. - real(real64), intent(in) :: x2(:) - !! An N-element array containing the second data set. - real(real64), intent(out) :: stat - !! The Student-'s T-Test statistic. - real(real64), intent(out) :: p - !! The probability value that the two samples are likely to - !! have come from two underlying populations that - !! have the same mean. - real(real64), intent(out) :: dof - !! The degrees of freedom. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same - !! length. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - real(real64), parameter :: two = 2.0d0 - - ! Local Variables - class(errors), pointer :: errmgr - type(errors), target :: deferr - real(real64) :: v1, v2, m1, m2, sd, cov, a, b, x - integer(int32) :: i, n1, n2, n - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - n1 = size(x1) - n2 = size(x2) - n = min(n1, n2) - - ! Input Checking - if (n1 /= n2) then - call report_arrays_not_same_size_error(errmgr, "t_test_paired_real64", & - "X1", "X2", n1, n2) - return - end if + ! Process + rst = confidence_interval(dist, alpha, standard_deviation(x), size(x)) +end function + +! ------------------------------------------------------------------------------ +subroutine t_test_equal_variance(x1, x2, stat, p, dof) + !! Computes the 2-tailed Student's T-Test for two data sets of + !! assumed equivalent variances. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) + real(real64), intent(in) :: x1(:) + !! An N-element array containing the first data set. + real(real64), intent(in) :: x2(:) + !! An M-element array containing the second data set. + real(real64), intent(out) :: stat + !! The Student-'s T-Test statistic. + real(real64), intent(out) :: p + !! The probability value that the two samples are likely to + !! have come from two underlying populations that + !! have the same mean. + real(real64), intent(out) :: dof + !! The degrees of freedom. + + ! Parameters + real(real64), parameter :: half = 0.5d0 + real(real64), parameter :: one = 1.0d0 + real(real64), parameter :: two = 2.0d0 + + ! Local Variables + real(real64) :: v1, v2, m1, m2, sv, a, b, x + integer(int32) :: n1, n2 + + ! Compute the T-statistic + n1 = size(x1) + n2 = size(x2) + m1 = mean(x1) + m2 = mean(x2) + v1 = variance(x1) + v2 = variance(x2) + dof = n1 + n2 - two + sv = ((n1 - one) * v1 + (n2 - one) * v2) / dof + stat = abs(m1 - m2) / sqrt(sv * (one / real(n1) + one / real(n2))) + + ! Compute the probability + a = half * dof + b = half + x = dof / (dof + stat**2) + p = regularized_beta(a, b, x) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine t_test_unequal_variance(x1, x2, stat, p, dof) + !! Computes the 2-tailed Student's T-Test for two data sets of + !! assumed non-equivalent variances. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) + real(real64), intent(in) :: x1(:) + !! An N-element array containing the first data set. + real(real64), intent(in) :: x2(:) + !! An M-element array containing the second data set. + real(real64), intent(out) :: stat + !! The Student-'s T-Test statistic. + real(real64), intent(out) :: p + !! The probability value that the two samples are likely to + !! have come from two underlying populations that + !! have the same mean. + real(real64), intent(out) :: dof + !! The degrees of freedom. + + ! Parameters + real(real64), parameter :: half = 0.5d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + real(real64) :: v1, v2, m1, m2, sv, a, b, x + integer(int32) :: n1, n2 + + ! Compute the T-statistic + n1 = size(x1) + n2 = size(x2) + m1 = mean(x1) + m2 = mean(x2) + v1 = variance(x1) + v2 = variance(x2) + dof = (v1 / real(n1) + v2 / real(n2))**2 / ((v1 / n1)**2 / (n1 - one) + & + (v2 / n2)**2 / (n2 - one)) + sv = sqrt(v1 / n1 + v2 / n2) + stat = (m1 - m2) / sv + + ! Compute the probability + a = half * dof + b = half + x = dof / (dof + stat**2) + p = regularized_beta(a, b, x) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine t_test_paired(x1, x2, stat, p, dof, err) + !! Computes the 2-tailed Student's T-Test for two paired data sets. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) + real(real64), intent(in) :: x1(:) + !! An N-element array containing the first data set. + real(real64), intent(in) :: x2(:) + !! An N-element array containing the second data set. + real(real64), intent(out) :: stat + !! The Student-'s T-Test statistic. + real(real64), intent(out) :: p + !! The probability value that the two samples are likely to + !! have come from two underlying populations that + !! have the same mean. + real(real64), intent(out) :: dof + !! The degrees of freedom. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same + !! length. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: half = 0.5d0 + real(real64), parameter :: one = 1.0d0 + real(real64), parameter :: two = 2.0d0 + + ! Local Variables + class(errors), pointer :: errmgr + type(errors), target :: deferr + real(real64) :: v1, v2, m1, m2, sd, cov, a, b, x + integer(int32) :: i, n1, n2, n + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + n1 = size(x1) + n2 = size(x2) + n = min(n1, n2) + + ! Input Checking + if (n1 /= n2) then + call report_arrays_not_same_size_error(errmgr, "t_test_paired_real64", & + "X1", "X2", n1, n2) + return + end if + + ! Compute the T-statistic + m1 = mean(x1) + m2 = mean(x2) + v1 = variance(x1) + v2 = variance(x2) + dof = real(n1) - one + cov = zero + do i = 1, n + cov = cov + (x1(i) - m1) * (x2(i) - m2) + end do + cov = cov / dof + sd = sqrt((v1 + v2 - two * cov) / n) + stat = (m1 - m2) / sd - ! Compute the T-statistic - m1 = mean(x1) - m2 = mean(x2) - v1 = variance(x1) - v2 = variance(x2) - dof = real(n1) - one - cov = zero - do i = 1, n - cov = cov + (x1(i) - m1) * (x2(i) - m2) - end do - cov = cov / dof - sd = sqrt((v1 + v2 - two * cov) / n) - stat = (m1 - m2) / sd - - ! Compute the probability - a = half * dof - b = half - x = dof / (dof + stat**2) - p = regularized_beta(a, b, x) -end subroutine - -! ------------------------------------------------------------------------------ -subroutine f_test(x1, x2, stat, p, dof1, dof2) - !! Computes the F-test and returns the probability (two-tailed) that - !! the variances of two data sets are not significantly different. - !! - !! See Also - !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/F-test) - real(real64), intent(in) :: x1(:) - !! An N-element array containing the first data set. - real(real64), intent(in) :: x2(:) - !! An M-element array containing the second data set. - real(real64), intent(out) :: stat - !! The F-statistic. - real(real64), intent(out) :: p - !! The probability value that the two samples are likely to - !! have come from the two underlying populations that - !! have the same variance. - real(real64), intent(out) :: dof1 - !! A measure of the degrees of freedom. - real(real64), intent(out) :: dof2 - !! A measure of the degrees of freedom. - - ! Parameters - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - real(real64), parameter :: two = 2.0d0 - - ! Local Variables - integer(int32) :: n1, n2 - real(real64) :: v1, v2, m1, m2, a, b, x - - ! Compute the F-statistic - n1 = size(x1) - n2 = size(x2) - m1 = mean(x1) - m2 = mean(x2) - v1 = variance(x1) - v2 = variance(x2) - if (v1 > v2) then - stat = v1 / v2 - dof1 = n1 - one - dof2 = n2 - one - else - stat = v2 / v1 - dof1 = n2 - one - dof2 = n1 - one - end if - - ! Compute the probability - a = half * dof2 - b = half * dof1 - x = dof2 / (dof2 + dof1 * stat) - p = two * regularized_beta(a, b, x) - if (p > one) p = two - p -end subroutine - -! ------------------------------------------------------------------------------ -end module + ! Compute the probability + a = half * dof + b = half + x = dof / (dof + stat**2) + p = regularized_beta(a, b, x) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine f_test(x1, x2, stat, p, dof1, dof2) + !! Computes the F-test and returns the probability (two-tailed) that + !! the variances of two data sets are not significantly different. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/F-test) + real(real64), intent(in) :: x1(:) + !! An N-element array containing the first data set. + real(real64), intent(in) :: x2(:) + !! An M-element array containing the second data set. + real(real64), intent(out) :: stat + !! The F-statistic. + real(real64), intent(out) :: p + !! The probability value that the two samples are likely to + !! have come from the two underlying populations that + !! have the same variance. + real(real64), intent(out) :: dof1 + !! A measure of the degrees of freedom. + real(real64), intent(out) :: dof2 + !! A measure of the degrees of freedom. + + ! Parameters + real(real64), parameter :: one = 1.0d0 + real(real64), parameter :: two = 2.0d0 + + ! Local Variables + integer(int32) :: n1, n2 + real(real64) :: v1, v2, m1, m2 + type(f_distribution) :: dist + + ! Compute the F-statistic + n1 = size(x1) + n2 = size(x2) + m1 = mean(x1) + m2 = mean(x2) + v1 = variance(x1) + v2 = variance(x2) + if (v1 > v2) then + stat = v1 / v2 + dof1 = n1 - one + dof2 = n2 - one + else + stat = v2 / v1 + dof1 = n2 - one + dof2 = n1 - one + end if + + dist%d1 = dof1 + dist%d2 = dof2 + p = two * (one - dist%cdf(stat))! 2x because this is a two-tailed estimate + if (p > one) p = two - p +end subroutine + +! ------------------------------------------------------------------------------ +subroutine bartletts_test(x, stat, p) + !! Computes Bartlett's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! + !! $$ \chi^{2} = \frac{(N - k) \ln(S_{p}^{2}) \sum_{i = 1}^{k} + !! \left(n_{i} - 1 \right) \ln(S_{i}^{2})}{1 + + !! \frac{1}{3 \left( k - 1 \right)} \left( \sum_{i = 1}^{k} + !! \left( \frac{1}{n_{i} - 1} \right) - \frac{1}{N - k} \right)} $$ + !! + !! Where \( N = \sum_{i = 1}^{k} n_{i} \) and \( S_{p}^{2} \) is the pooled + !! variance. + !! + !! The probability is calculated as the right-tail probability of the + !! chi-squared distribution. + !! + !! Bartlett's test is most relevant for distributions showing strong + !! normality. For distributions lacking strong normality, consider + !! Levene's test instead. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Bartlett%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + + ! Local Variables + integer(int32) :: i, n, k, ni + real(real64) :: si, sp, numer, denom + type(chi_squared_distribution) :: dist + + ! Initialization + k = size(x) + n = 0 + do i = 1, k + n = n + size(x(i)%x) + end do + + ! Compute the statistic + n = 0 + sp = 0.0d0 + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + si = variance(x(i)%x) + sp = sp + (ni - 1.0d0) * si + numer = numer + (ni - 1.0d0) * log(variance(x(i)%x)) + denom = denom + 1.0d0 / (ni - 1.0d0) + end do + sp = sp / real(n - k, real64) + stat = ((n - k) * log(sp) - numer) / & + (1.0d0 + (1.0d0 / (3.0d0 * k - 3.0d0)) * & + (denom - 1.0d0 / real(n - k, real64))) + + ! Compute the p-value + dist%dof = k - 1 + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine levenes_test(x, stat, p, err) + !! Computes Levene's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! $$ W = \frac{N - k}{k - 1} \frac{ \sum_{i = 1}^{k} N_{i} \left( Z_{i.} - + !! Z{..} \right)^{2}}{ \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} \left( Z_{ij} - + !! Z_{i.} \right)^{2} } $$ + !! + !! Where: + !! $$ Z_{ij} = |X_{ij} - \overline{X_{i.}}| $$ + !! $$ Z_{i.} = \frac{1}{n_{i}} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! $$ Z_{..} = \frac{1}{N} \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! + !! As the test statistic is approximately F-distributed, the F-distribution + !! is used to calculate the probability term. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Levene%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + class(errors), intent(inout), optional, target :: err + + ! Local Variables + integer(int32) :: i, j, k, n, ni, flag + real(real64) :: numer, denom, inner, yi, z, zij + real(real64), allocatable, dimension(:) :: y, zt, zi + type(f_distribution) :: dist + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + k = size(x) + + ! Local Memory Allocations + allocate(y(k), zi(k), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "levenes_test", flag) + return + end if + + ! Compute the total mean + z = 0.0d0 + n = 0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + y(i) = mean(x(i)%x) + zt = abs(x(i)%x - y(i)) + zi(i) = mean(zt) + z = z + zi(i) * ni + end do + z = z / n + + ! Process + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + yi = y(i) + numer = numer + ni * (zi(i) - z)**2 + + inner = 0.0d0 + do j = 1, ni + zij = abs(x(i)%x(j) - yi) + inner = inner + (zij - zi(i))**2 + end do + denom = denom + inner + end do + stat = real((N - k) / (k - 1), real64) * (numer / denom) + dist%d1 = k - 1.0d0 + dist%d2 = real(n - k, real64) + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +pure function sample_size(dist, var, delta, bet, alpha) result(rst) + !! Estimates the sample size required to achieve an experiment with the + !! desired power and significance levels to ascertain the desired + !! difference in parameter. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Power_of_a_test) + class(distribution), intent(in) :: dist + !! The distribution to utilize as a measure. + real(real64), intent(in) :: var + !! An estimate of the population variance. + real(real64), intent(in) :: delta + !! The parameter difference that is desired. + real(real64), intent(in), optional :: bet + !! The desired power level. The default for this value is 0.2, for a + !! power of 80%. + real(real64), intent(in), optional :: alpha + !! The desired significance level. The default for this value is 0.05 + !! for a confidence level of 95%. + real(real64) :: rst + !! The minimum sample size requried to achieve the desired experimental + !! outcome. + + ! Local Variables + real(real64) :: a, b, za, zb + + ! Initialization + if (present(bet)) then + b = bet + else + b = 0.8d0 + end if + if (present(alpha)) then + a = alpha + else + a = 0.05d0 + end if + + za = dist%standardized_variable(1.0d0 - a / 2.0d0) + zb = dist%standardized_variable(b) + rst = 2.0d0 * (za + zb)**2 * var / (delta**2) +end function + +! ------------------------------------------------------------------------------ +end module @@ -485,7 +669,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_regression.f90.html b/doc/sourcefile/fstats_regression.f90.html index 9e4e881..797ca00 100644 --- a/doc/sourcefile/fstats_regression.f90.html +++ b/doc/sourcefile/fstats_regression.f90.html @@ -74,7 +74,7 @@

            fstats_regression.f90
          • 861 statements + title="29.3% of total for source files.">861 statements
          • @@ -172,7 +172,7 @@

            Source Code

            public :: r_squared public :: adjusted_r_squared public :: correlation - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: calculate_regression_statistics @@ -446,1368 +446,1370 @@

            Source Code

            end function ! ------------------------------------------------------------------------------ -subroutine coefficient_matrix(order, intercept, x, c, err) - !! Computes the coefficient matrix \( X \) to the linear +subroutine design_matrix(order, intercept, x, c, err) + !! Computes the design matrix \( X \) for the linear !! least-squares regression problem of \( X \beta = y \), where - !! \( X \) is the coefficient matrix computed here, \( \beta \) is + !! \( X \) is the matrix computed here, \( \beta \) is !! the vector of coefficients to be determined, and \( y \) is the !! vector of measured dependent variables. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) - integer(int32), intent(in) :: order - !! The order of the equation to fit. This value must be - !! at least one (linear equation), but can be higher as desired. - logical, intent(in) :: intercept - !! Set to true if the intercept is being computed - !! as part of the regression; else, false. - real(real64), intent(in) :: x(:) - !! An N-element array containing the independent variable - !! measurement points. - real(real64), intent(out) :: c(:,:) - !! An N-by-K matrix where the results will be written. K - !! must equal order + 1 in the event intercept is true; - !! however, if intercept is false, K must equal order. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. - !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. - - ! Parameters - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, start, npts, ncols - class(errors), pointer :: errmgr - type(errors), target :: deferr - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - npts = size(x) - ncols = order - if (intercept) ncols = ncols + 1 - - ! Input Check - if (order < 1) then - call errmgr%report_error("coefficient_matrix", & - "The model order must be at least one.", FS_INVALID_INPUT_ERROR) - return - end if - if (size(c, 1) /= npts .or. size(c, 2) /= ncols) then - call report_matrix_size_error(errmgr, "coefficient_matrix", & - "c", npts, ncols, size(c, 1), size(c, 2)) - return - end if - - ! Process - if (intercept) then - c(:,1) = one - c(:,2) = x - start = 3 - else - c(:,1) = x - start = 2 - end if - if (start >= ncols) return - do i = start, ncols - c(:,i) = c(:,i-1) * x - end do -end subroutine - -! ------------------------------------------------------------------------------ -subroutine covariance_matrix(x, c, err) - !! Computes the covariance matrix \( C \) where - !! \( C = \left( X^{T} X \right)^{-1} \) and \( X \) is computed - !! by coefficient_matrix. - !! - !! See Also + !! - [Wikipedia](https://en.wikipedia.org/wiki/Vandermonde_matrix) + !! - [Wikipedia](https://en.wikipedia.org/wiki/Design_matrix) + integer(int32), intent(in) :: order + !! The order of the equation to fit. This value must be + !! at least one (linear equation), but can be higher as desired. + logical, intent(in) :: intercept + !! Set to true if the intercept is being computed + !! as part of the regression; else, false. + real(real64), intent(in) :: x(:) + !! An N-element array containing the independent variable + !! measurement points. + real(real64), intent(out) :: c(:,:) + !! An N-by-K matrix where the results will be written. K + !! must equal order + 1 in the event intercept is true; + !! however, if intercept is false, K must equal order. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. + !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. + + ! Parameters + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, start, npts, ncols + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + npts = size(x) + ncols = order + if (intercept) ncols = ncols + 1 + + ! Input Check + if (order < 1) then + call errmgr%report_error("design_matrix", & + "The model order must be at least one.", FS_INVALID_INPUT_ERROR) + return + end if + if (size(c, 1) /= npts .or. size(c, 2) /= ncols) then + call report_matrix_size_error(errmgr, "design_matrix", & + "c", npts, ncols, size(c, 1), size(c, 2)) + return + end if + + ! Process + if (intercept) then + c(:,1) = one + c(:,2) = x + start = 3 + else + c(:,1) = x + start = 2 + end if + if (start >= ncols) return + do i = start, ncols + c(:,i) = c(:,i-1) * x + end do +end subroutine + +! ------------------------------------------------------------------------------ +subroutine covariance_matrix(x, c, err) + !! Computes the covariance matrix \( C \) where + !! \( C = \left( X^{T} X \right)^{-1} \) and \( X \) is computed + !! by design_matrix. !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Covariance_matrix) - !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) - real(real64), intent(in) :: x(:,:) - !! An M-by-N matrix containing the formatted independent data - !! matrix \( X \) as computed by coefficient_matrix. - real(real64), intent(out) :: c(:,:) - !! The N-by-N covariance matrix. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not - !! sized correctly. - !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation - !! error. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - class(errors), pointer :: errmgr - type(errors), target :: deferr - integer(int32) :: npts, ncoeffs, flag - real(real64), allocatable :: xtx(:,:) - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - npts = size(x, 1) - ncoeffs = size(x, 2) - - ! Input Checking - if (size(c, 1) /= ncoeffs .or. size(c, 2) /= ncoeffs) then - call report_matrix_size_error(errmgr, "covariance_matrix", & - "c", ncoeffs, ncoeffs, size(c, 1), size(c, 2)) - return - end if - - ! Local Memory Allocation - allocate(xtx(ncoeffs, ncoeffs), stat = flag) - if (flag /= 0) then - call report_memory_error(errmgr, "covariance_matrix", flag) - return - end if - - ! Compute X**T * X - call DGEMM("T", "N", ncoeffs, ncoeffs, npts, one, x, npts, x, npts, & - zero, xtx, ncoeffs) - - ! Compute the inverse of X**T * X to obtain the covariance matrix - call mtx_pinverse(xtx, c, err = errmgr) - if (errmgr%has_error_occurred()) return -end subroutine - -! ------------------------------------------------------------------------------ -subroutine linear_least_squares(order, intercept, x, y, coeffs, & - ymod, resid, stats, alpha, err) - !! Computes a linear least-squares regression to fit a set of data. - !! - !! See Also + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Covariance_matrix) + !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) + real(real64), intent(in) :: x(:,:) + !! An M-by-N matrix containing the formatted independent data + !! matrix \( X \) as computed by design_matrix. + real(real64), intent(out) :: c(:,:) + !! The N-by-N covariance matrix. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not + !! sized correctly. + !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation + !! error. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + class(errors), pointer :: errmgr + type(errors), target :: deferr + integer(int32) :: npts, ncoeffs, flag + real(real64), allocatable :: xtx(:,:) + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + npts = size(x, 1) + ncoeffs = size(x, 2) + + ! Input Checking + if (size(c, 1) /= ncoeffs .or. size(c, 2) /= ncoeffs) then + call report_matrix_size_error(errmgr, "covariance_matrix", & + "c", ncoeffs, ncoeffs, size(c, 1), size(c, 2)) + return + end if + + ! Local Memory Allocation + allocate(xtx(ncoeffs, ncoeffs), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "covariance_matrix", flag) + return + end if + + ! Compute X**T * X + call DGEMM("T", "N", ncoeffs, ncoeffs, npts, one, x, npts, x, npts, & + zero, xtx, ncoeffs) + + ! Compute the inverse of X**T * X to obtain the covariance matrix + call mtx_pinverse(xtx, c, err = errmgr) + if (errmgr%has_error_occurred()) return +end subroutine + +! ------------------------------------------------------------------------------ +subroutine linear_least_squares(order, intercept, x, y, coeffs, & + ymod, resid, stats, alpha, err) + !! Computes a linear least-squares regression to fit a set of data. !! - !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) - !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) - integer(int32), intent(in) :: order - !! The order of the equation to fit. This value must be at - !! least one (linear equation), but can be higher as desired, - !! as long as there is sufficient data. - logical, intent(in) :: intercept - !! Set to true if the intercept is being computed as part of - !! the regression; else, false. - real(real64), intent(in) :: x(:) - !! An N-element array containing the independent variable - !! measurement points. - real(real64), intent(in) :: y(:) - !! An N-element array containing the dependent variable - !! measurement points. - real(real64), intent(out) :: coeffs(:) - !! An ORDER+1 element array where the coefficients will be written. - real(real64), intent(out) :: ymod(:) - !! An N-element array where the modeled data will be written. - real(real64), intent(out) :: resid(:) - !! An N-element array where the residual error data will be - !! written (modeled - actual). - type(regression_statistics), intent(out), optional :: stats(:) - !! An M-element array of regression_statistics items where - !! M = ORDER + 1 when intercept is set to true; however, if - !! intercept is set to false, M = ORDER. - real(real64), intent(in), optional :: alpha - !! The significance level at which to evaluate the confidence - !! intervals. The default value is 0.05 such that a 95% - !! confidence interval is calculated. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not - !! approriately sized. - !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. - !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation - !! error. - - ! Parameters - real(real64), parameter :: zero = 0.0d0 - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, npts, ncols, ncoeffs, flag - real(real64) :: alph, var, df, ssr, talpha - real(real64), allocatable :: a(:,:), c(:,:), cxt(:,:) - type(t_distribution) :: dist - class(errors), pointer :: errmgr - type(errors), target :: deferr - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - npts = size(x) - ncoeffs = order + 1 - ncols = order - if (intercept) ncols = ncols + 1 - alph = 0.05d0 - if (present(alpha)) alph = alpha - - ! Input Check - if (order < 1) then - call errmgr%report_error("linear_least_squares", & - "The model order must be at least one.", FS_INVALID_INPUT_ERROR) - return - end if - if (size(y) /= npts) then - call report_array_size_error(errmgr, "linear_least_squares", & - "y", npts, size(y)) - return - end if - if (size(coeffs) /= ncoeffs) then - call report_array_size_error(errmgr, "linear_least_squares", & - "coeffs", ncoeffs, size(coeffs)) - return - end if - if (size(ymod) /= npts) then - call report_array_size_error(errmgr, "linear_least_squares", & - "ymod", npts, size(ymod)) - return - end if - if (size(resid) /= npts) then - call report_array_size_error(errmgr, "linear_least_squares", & - "resid", npts, size(resid)) - return - end if - if (present(stats)) then - if (size(stats) /= ncols) then - call report_array_size_error(errmgr, & - "linear_least_squares", "stats", ncols, size(stats)) - return - end if - end if - - ! Memory Allocation - allocate(a(npts, ncols), stat = flag) - if (flag == 0) allocate(c(ncols, ncols), stat = flag) - if (flag == 0) allocate(cxt(ncols, npts), stat = flag) - if (flag /= 0) then - call report_memory_error(errmgr, "linear_least_squares", flag) - return - end if - - ! Compute the coefficient matrix - call coefficient_matrix(order, intercept, x, a, errmgr) - if (errmgr%has_error_occurred()) return - - ! Compute the covariance matrix - call covariance_matrix(a, c, errmgr) - if (errmgr%has_error_occurred()) return - - ! Compute the coefficients (NCOLS-by-1) - call DGEMM("N", "T", ncols, npts, ncols, one, c, ncols, a, npts, zero, & - cxt, ncols) ! C * X**T - - i = 2 - coeffs(1) = zero - if (intercept) i = 1 - call DGEMM("N", "N", ncols, 1, npts, one, cxt, ncols, y, npts, zero, & - coeffs(i:), ncols) ! (C * X**T) * Y - - ! Evaluate the model and compute the residuals - call DGEMM("N", "N", npts, 1, ncols, one, a, npts, coeffs(i:), & - ncols, zero, ymod, npts) - resid = ymod - y - - ! If the user doesn't want the statistics calculations we can stop now - if (.not.present(stats)) return - - ! Start the process of computing statistics - stats = calculate_regression_statistics(resid, coeffs(i:), c, alph, & - errmgr) -end subroutine - -! ------------------------------------------------------------------------------ -function calculate_regression_statistics(resid, params, c, alpha, err) & - result(rst) - !! Computes statistics for the quality of fit for a regression - !! model. - real(real64), intent(in) :: resid(:) - !! An M-element array containing the model residual errors. - real(real64), intent(in) :: params(:) - !! An N-element array containing the model parameters. - real(real64), intent(in) :: c(:,:) - !! The N-by-N covariance matrix. - real(real64), intent(in), optional :: alpha - !! The significance level at which to evaluate the confidence - !! intervals. The default value is 0.05 such that a 95% - !! confidence interval is calculated. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly. - !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. - !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation - !! error. - type(regression_statistics), allocatable :: rst(:) - !! A regression_statistics object containing the analysis results. - - ! Parameters - real(real64), parameter :: p05 = 0.05d0 - real(real64), parameter :: half = 0.5d0 - real(real64), parameter :: one = 1.0d0 - - ! Local Variables - integer(int32) :: i, m, n, dof, flag - real(real64) :: a, ssr, var, talpha - type(t_distribution) :: dist - class(errors), pointer :: errmgr - type(errors), target :: deferr - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - - ! Initialization - m = size(resid) - n = size(params) - dof = m - n - if (present(alpha)) then - a = alpha - else - a = p05 - end if - allocate(rst(n), stat = flag) - if (flag /= 0) then - end if - - ! Input Checking - if (size(c, 1) /= n .or. size(c, 2) /= n) then - end if - - ! Process - ssr = norm2(resid)**2 ! sum of the squares of the residual - var = ssr / dof - dist%dof = real(dof, real64) - talpha = confidence_interval(dist, a, one, 1) - do i = 1, n - rst(i)%standard_error = sqrt(var * c(i,i)) - rst(i)%t_statistic = params(i) / rst(i)%standard_error - rst(i)%probability = regularized_beta( & - half * dof, & - half, & - real(dof, real64) / (dof + (rst(i)%t_statistic)**2) & - ) - rst(i)%confidence_interval = talpha * rst(i)%standard_error - end do -end function - -! ------------------------------------------------------------------------------ -subroutine jacobian(fun, xdata, params, & - jac, stop, f0, f1, step, err) - !! Computes the Jacobian matrix for a nonlinear regression problem. - procedure(regression_function), intent(in), pointer :: fun - !! A pointer to the regression_function to evaluate. - real(real64), intent(in) :: xdata(:) - !! The M-element array containing x-coordinate data. - real(real64), intent(in) :: params(:) - !! The N-element array containing the model parameters. - real(real64), intent(out) :: jac(:,:) - !! The M-by-N matrix where the Jacobian will be written. - logical, intent(out) :: stop - !! A value that the user can set in fun forcing the - !! evaluation process to stop prior to completion. - real(real64), intent(in), optional, target :: f0(:) - !! An optional M-element array containing the model values - !! using the current parameters as defined in m. This input - !! can be used to prevent the routine from performing a - !! function evaluation at the model parameter state defined in - !! params. - real(real64), intent(out), optional, target :: f1(:) - !! An optional M-element workspace array used for function - !! evaluations. - real(real64), intent(in), optional :: step - !! The differentiation step size. The default is the square - !! root of machine precision. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not - !! properly sized. - !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation - !! error. - - ! Local Variables - real(real64) :: h - integer(int32) :: m, n, flag, expected, actual - real(real64), pointer :: f1p(:), f0p(:) - real(real64), allocatable, target :: f1a(:), f0a(:), work(:) - class(errors), pointer :: errmgr - type(errors), target :: deferr - - ! Initialization - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - if (present(step)) then - h = step - else - h = sqrt(epsilon(h)) - end if - m = size(xdata) - n = size(params) - - ! Input Size Checking - if (size(jac, 1) /= m .or. size(jac, 2) /= n) then - call report_matrix_size_error(errmgr, "jacobian", & - "JAC", m, n, size(jac, 1), size(jac, 2)) - return - end if - if (present(f0)) then - ! Check Size - if (size(f0) /= m) then - call report_array_size_error(errmgr, "jacobian", & - "F0", m, size(f0)) - return - end if - f0p(1:m) => f0 - else - ! Allocate space, and fill the array with the current function - ! results - allocate(f0a(m), stat = flag) - if (flag /= 0) go to 20 - f0p(1:m) => f0a - call fun(xdata, params, f0p, stop) - if (stop) return - end if - if (present(f1)) then - ! Check Size - if (size(f1) /= m) then - call report_array_size_error(errmgr, "jacobian", & - "F1", m, size(f1)) - return - end if - f1p(1:m) => f1 - else - ! Allocate space - allocate(f1a(m), stat = flag) - if (flag /= 0) go to 20 - f1p(1:m) => f1a - end if - - ! Allocate a workspace array the same size as params - allocate(work(n), stat = flag) - if (flag /= 0) go to 20 - - ! Compute the Jacobian - call jacobian_finite_diff(fun, xdata, params, f0p, jac, f1p, & - stop, h, work) - - ! End - return - - ! Memroy Allocation Error Handling -20 continue - call report_memory_error(errmgr, "jacobian", flag) - return -end subroutine - -! ------------------------------------------------------------------------------ -subroutine nonlinear_least_squares(fun, x, y, params, ymod, & - resid, weights, maxp, minp, stats, alpha, controls, settings, info, & - status, err) - !! Performs a nonlinear regression to fit a model using a version - !! of the Levenberg-Marquardt algorithm. - procedure(regression_function), intent(in), pointer :: fun - !! A pointer to the regression_function to evaluate. - real(real64), intent(in) :: x(:) - !! The M-element array containing independent data. - real(real64), intent(in) :: y(:) - !! The M-element array containing dependent data. - real(real64), intent(inout) :: params(:) - !! On input, the N-element array containing the initial estimate - !! of the model parameters. On output, the computed model - !! parameters. - real(real64), intent(out) :: ymod(:) - !! An M-element array where the modeled dependent data will - !! be written. - real(real64), intent(out) :: resid(:) - !! An M-element array where the model residuals will be - !! written. - real(real64), intent(in), optional, target :: weights(:) - !! An optional M-element array allowing the weighting of - !! individual points. - real(real64), intent(in), optional, target :: maxp(:) - !! An optional N-element array that can be used as upper limits - !! on the parameter values. If no upper limit is requested for - !! a particular parameter, utilize a very large value. The - !! internal default is to utilize huge() as a value. - real(real64), intent(in), optional, target :: minp(:) - !! An optional N-element array that can be used as lower limits - !! on the parameter values. If no lower limit is requested for - !! a particalar parameter, utilize a very large magnitude, but - !! negative, value. The internal default is to utilize -huge() - !! as a value. - type(regression_statistics), intent(out), optional :: stats(:) - !! An optional N-element array that, if supplied, will be used - !! to return statistics about the fit for each parameter. - real(real64), intent(in), optional :: alpha - !! The significance level at which to evaluate the confidence - !! intervals. The default value is 0.05 such that a 95% - !! confidence interval is calculated. - type(iteration_controls), intent(in), optional :: controls - !! An optional input providing custom iteration controls. - type(lm_solver_options), intent(in), optional :: settings - !! An optional input providing custom settings for the solver. - type(convergence_info), intent(out), optional, target :: info - !! An optional output that can be used to gain information about - !! the iterative solution and the nature of the convergence. - procedure(iteration_update), intent(in), pointer, optional :: status - !! An optional pointer to a routine that can be used to extract - !! iteration information. - class(errors), intent(inout), optional, target :: err - !! A mechanism for communicating errors and warnings to the - !! caller. Possible warning and error codes are as follows. - !! - FS_NO_ERROR: No errors encountered. - !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not - !! properly sized. - !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation - !! error. - !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed - !! is underdetetermined (M < N). - !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied - !! tolerances are too small to be practical. - !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations - !! are allowed. - - ! Parameters - real(real64), parameter :: too_small = 1.0d-14 - integer(int32), parameter :: min_iter_count = 2 - integer(int32), parameter :: min_fun_count = 10 - integer(int32), parameter :: min_update_count = 1 - - ! Local Variables - logical :: stop - integer(int32) :: m, n, actual, expected, flag - real(real64), pointer :: w(:), pmax(:), pmin(:) - real(real64), allocatable, target :: defaultWeights(:), maxparam(:), & - minparam(:), JtWJ(:,:) - type(iteration_controls) :: tol - type(lm_solver_options) :: opt - type(convergence_info) :: cInfo - class(errors), pointer :: errmgr - type(errors), target :: deferr - type(convergence_info), target :: defaultinfo - type(convergence_info), pointer :: inf - - ! Initialization - stop = .false. - m = size(x) - n = size(params) - if (present(info)) then - inf => info - else - inf => defaultinfo - end if - if (present(err)) then - errmgr => err - else - errmgr => deferr - end if - if (present(controls)) then - tol = controls - else - call tol%set_to_default() - end if - if (present(settings)) then - opt = settings - else - call opt%set_to_default() - end if - - ! Input Checking - if (size(y) /= m) then - call report_array_size_error(errmgr, "nonlinear_least_squares", & - "y", m, size(y)) - return - end if - if (size(ymod) /= m) then - call report_array_size_error(errmgr, "nonlinear_least_squares", & - "ymod", m, size(ymod)) - return - end if - if (size(resid) /= m) then - call report_array_size_error(errmgr, "nonlinear_least_squares", & - "resid", m, size(resid)) - return - end if - if (m < n) then - call report_underdefined_error(errmgr, & - "nonlinear_least_squares", n, m) - return - end if - - ! Tolerance Checking - if (tol%gradient_tolerance < too_small) then - call errmgr%report_error("nonlinear_least_squares", & - "The gradient tolerance was found to be too small.", & - FS_TOLERANCE_TOO_SMALL_ERROR) - return - end if - if (tol%change_in_solution_tolerance < too_small) then - call errmgr%report_error("nonlinear_least_squares", & - "The change in solution tolerance was found to be too small.", & - FS_TOLERANCE_TOO_SMALL_ERROR) - return - end if - if (tol%residual_tolerance < too_small) then - call errmgr%report_error("nonlinear_least_squares", & - "The residual error tolerance was found to be too small.", & - FS_TOLERANCE_TOO_SMALL_ERROR) - return - end if - if (tol%iteration_improvement_tolerance < too_small) then - call errmgr%report_error("nonlinear_least_squares", & - "The iteration improvement tolerance was found to be too small.", & - FS_TOLERANCE_TOO_SMALL_ERROR) - return - end if - - ! Iteration Count Checking - if (tol%max_iteration_count < min_iter_count) then - call report_iteration_count_error(errmgr, & - "nonlinear_least_squares", & - "Too few iterations were specified.", & - min_iter_count) - return - end if - if (tol%max_function_evaluations < min_fun_count) then - call report_iteration_count_error(errmgr, & - "nonlinear_least_squares", & - "Too few function evaluations were specified.", & - min_fun_count) - return - end if - if (tol%max_iteration_between_updates < min_update_count) then - call report_iteration_count_error(errmgr, & - "nonlinear_least_squares", & - "Too few iterations between updates were specified.", & - min_update_count) - return - end if - - ! Optional Array Arguments (weights, parameter limits, etc.) - if (present(weights)) then - if (size(weights) < m) then - call report_array_size_error(errmgr, & - "nonlinear_least_squares", "weights", m, size(weights)) - return - end if - w(1:m) => weights(1:m) - else - allocate(defaultWeights(m), source = 1.0d0, stat = flag) - if (flag /= 0) go to 50 - w(1:m) => defaultWeights(1:m) - end if - - if (present(maxp)) then - if (size(maxp) /= n) then - call report_array_size_error(errmgr, & - "nonlinear_least_squares", "maxp", n, size(maxp)) - return - end if - pmax(1:n) => maxp(1:n) - else - allocate(maxparam(n), source = huge(1.0d0), stat = flag) - if (flag /= 0) go to 50 - pmax(1:n) => maxparam(1:n) - end if - - if (present(minp)) then - if (size(minp) /= n) then - call report_array_size_error(errmgr, & - "nonlinear_least_squares", "minp", n, size(minp)) - return - end if - pmin(1:n) => minp(1:n) - else - allocate(minparam(n), source = -huge(1.0d0), stat = flag) - if (flag /= 0) go to 50 - pmin(1:n) => minparam(1:n) - end if - - ! Local Memory Allocations - allocate(JtWJ(n, n), stat = flag) - if (flag /= 0) go to 50 - - ! Process - call lm_solve(fun, x, y, params, w, pmax, pmin, tol, opt, ymod, & - resid, JtWJ, inf, stop, errmgr, status) - - ! Statistical Parameters - if (present(stats)) then - if (size(stats) /= n) then - call report_array_size_error(errmgr, & - "nonlinear_least_squares", "stats", n, size(stats)) - return - end if - - ! Compute the covariance matrix - call mtx_inverse(JtWJ, err = errmgr) - if (errmgr%has_error_occurred()) return - - ! Compute the statistics - stats = calculate_regression_statistics(resid, params, JtWJ, & - alpha, errmgr) - end if - - ! End - return - - ! Memory Error Handler -50 continue - call report_memory_error(errmgr, "nonlinear_least_squares", flag) - return -end subroutine - -! ****************************************************************************** -! SETTINGS DEFAULTS -! ------------------------------------------------------------------------------ -! Sets up default tolerances. -subroutine lm_set_default_tolerances(x) - ! Arguments - class(iteration_controls), intent(inout) :: x - - ! Set defaults - x%max_iteration_count = 500 - x%max_function_evaluations = 5000 - x%max_iteration_between_updates = 10 - x%gradient_tolerance = 1.0d-8 - x%residual_tolerance = 0.5d-2 - x%change_in_solution_tolerance = 1.0d-6 - x%iteration_improvement_tolerance = 1.0d-1 -end subroutine - -! ------------------------------------------------------------------------------ -! Sets up default solver settings. -subroutine lm_set_default_settings(x) - ! Arguments - class(lm_solver_options), intent(inout) :: x - - ! Set defaults - x%method = FS_LEVENBERG_MARQUARDT_UPDATE - x%finite_difference_step_size = sqrt(epsilon(1.0d0)) - x%damping_increase_factor = 11.0d0 - x%damping_decrease_factor = 9.0d0 -end subroutine - -! ****************************************************************************** -! PRIVATE ROUTINES -! ------------------------------------------------------------------------------ -! Computes the Jacobian matrix via a forward difference. -! -! Inputs: -! - fun: The function to evaluate -! - xdata: The independent coordinate data to fit (M-by-1) -! - params: The model parameters (N-by-1) -! - f0: The current model estimate (M-by-1) -! - step: The differentiation step size -! -! Outputs: -! - jac: The Jacobian matrix (M-by-N) -! - f1: A workspace array for the model output (M-by-1) -! - stop: A flag allowing the user to terminate model execution -! - work: A workspace array for the model parameters (N-by-1) -subroutine jacobian_finite_diff(fun, xdata, params, f0, jac, f1, & - stop, step, work) - ! Arguments - procedure(regression_function), intent(in), pointer :: fun - real(real64), intent(in) :: xdata(:), params(:) - real(real64), intent(in) :: f0(:) - real(real64), intent(out) :: jac(:,:) - real(real64), intent(out) :: f1(:), work(:) - logical, intent(out) :: stop - real(real64), intent(in) :: step - - ! Local Variables - integer(int32) :: i, n - - ! Initialization - n = size(params) - - ! Cycle over each column of the Jacobian and calculate the derivative - ! via a forward difference scheme - ! - ! J(i,j) = df(i) / dx(j) - work = params - do i = 1, n - work(i) = work(i) + step - call fun(xdata, work, f1, stop) - if (stop) return - - jac(:,i) = (f1 - f0) / step - work(i) = params(i) - end do -end subroutine - -! ------------------------------------------------------------------------------ -! Computes a rank-1 update to the Jacobian matrix -! -! Inputs: -! - pOld: previous set of parameters (N-by-1) -! - yOld: model evaluation at previous set of parameters (M-by-1) -! - jac: current Jacobian estimate (M-by-N) -! - p: current set of parameters (N-by-1) -! - y: model evaluation at current set of parameters (M-by-1) -! -! Outputs: -! - jac: updated Jacobian matrix (M-by-N) (dy * dp**T + J) -! - dp: p - pOld (N-by-1) -! - dy: (y - yOld - J * dp) / (dp' * dp) (M-by-1) -subroutine broyden_update(pOld, yOld, jac, p, y, dp, dy) - ! Arguments - real(real64), intent(in) :: pOld(:), yOld(:), p(:), y(:) - real(real64), intent(inout) :: jac(:,:) - real(real64), intent(out) :: dp(:), dy(:) - - ! Local Variables - real(real64) :: h2 - - ! Process - dp = p - pOld - h2 = dot_product(dp, dp) - dy = y - yOld - matmul(jac, dp) - dy = dy / h2 - call rank1_update(1.0d0, dy, dp, jac) -end subroutine - -! ------------------------------------------------------------------------------ -! Updates the Levenberg-Marquardt matrix by either computing a new Jacobian -! matrix or performing a rank-1 update to the existing Jacobian matrix. -! -! Inputs: -! - fun: The function to evaluate -! - xdata: The independent coordinate data to fit (M-by-1) -! - ydata: The dependent coordinate data to fit (M-by-1) -! - pOld: previous set of parameters (N-by-1) -! - yOld: model evaluation at previous set of parameters (M-by-1) -! - dX2: The previous change in the Chi-squared criteria -! - jac: current Jacobian estimate (M-by-N) -! - p: current set of parameters (N-by-1) -! - weights: A weighting vector (M-by-1) -! - neval: Current number of function evaluations -! - update: Set to true to force an update of the Jacobian; else, set to -! false to let the program choose based upon the change in the -! Chi-squared parameter. -! - step: The differentiation step size -! -! Outputs: -! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) -! - JtWdy: linearized fitting vector (N-by-1) -! - X2: Updated Chi-squared criteria -! - yNew: model evaluated with parameters of p (M-by-1) -! - jac: updated Jacobian matrix (M-by-N) -! - neval: updated count of function evaluations -! - stop: A flag allowing the user to terminate model execution -! - work: A workspace array (N+M-by-1) -! - mwork: A workspace matrix (N-by-M) -! - update: Reset to false if a Jacobian evaluation was performed. -subroutine lm_matrix(fun, xdata, ydata, pOld, yOld, dX2, jac, p, weights, & - neval, update, step, JtWJ, JtWdy, X2, yNew, stop, work, mwork) - ! Arguments - procedure(regression_function), pointer :: fun - real(real64), intent(in) :: xdata(:), ydata(:), pOld(:), yOld(:), & - p(:), weights(:) - real(real64), intent(in) :: dX2, step - real(real64), intent(inout) :: jac(:,:) - integer(int32), intent(inout) :: neval - logical, intent(inout) :: update - real(real64), intent(out) :: JtWJ(:,:), JtWdy(:) - real(real64), intent(out) :: X2, mwork(:,:), yNew(:) - logical, intent(out) :: stop - real(real64), intent(out), target :: work(:) - - ! Local Variables - integer(int32) :: m, n - real(real64), pointer :: w1(:), w2(:) - - ! Initialization - m = size(xdata) - n = size(p) - w1(1:m) => work(1:m) - w2(1:n) => work(m+1:n+m) - - ! Perform the next function evaluation - call fun(xdata, p, yNew, stop) - neval = neval + 1 - if (stop) return - - ! Update or recompute the Jacobian matrix - if (dX2 > 0 .or. update) then - ! Recompute the Jacobian - call jacobian_finite_diff(fun, xdata, p, yNew, jac, w1, & - stop, step, w2) - neval = neval + n - if (stop) return - update = .false. - else - ! Simply perform a rank-1 update to the Jacobian - call broyden_update(pOld, yOld, jac, p, yNew, w2, w1) - end if - - ! Update the Chi-squared estimate - w1 = ydata - yNew - X2 = dot_product(w1, w1 * weights) - - ! Compute J**T * (W .* dY) - w1 = w1 * weights - call mtx_mult(.true., 1.0d0, jac, w1, 0.0d0, JtWdy) - - ! Update the Hessian - ! First: J**T * W = MWORK - ! Second: (J**T * W) * J - call diag_mtx_mult(.false., .true., 1.0d0, weights, jac, 0.0d0, mwork) - call mtx_mult(.false., .false., 1.0d0, mwork, jac, 0.0d0, JtWJ) -end subroutine - -! ------------------------------------------------------------------------------ -! Performs a single iteration of the Levenberg-Marquardt algorithm. -! -! Inputs: -! - fun: The function to evaluate -! - xdata: The independent coordinate data to fit (M-by-1) -! - ydata: The dependent coordinate data to fit (M-by-1) -! - p: current set of parameters (N-by-1) -! - neval: current number of function evaluations -! - niter: current iteration number -! - update: set to 1 to use Marquardt's modification; else, -! - step: the differentiation step size -! - lambda: LM damping parameter -! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) -! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) -! - weights: a weighting vector (M-by-1) -! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) -! - JtWdy: linearized fitting vector (N-by-1) -! -! Outputs: -! - JtWJ: overwritten LU factorization of the original matrix (N-by-N) -! - h: The new estimate of the change in parameter (N-by-1) -! - pNew: The new parameter estimates (N-by-1) -! - deltaY: The new difference between data and model (M-by-1) -! - yNew: model evaluated with parameters of pNew (M-by-1) -! - neval: updated count of function evaluations -! - niter: updated current iteration number -! - X2: updated Chi-squared criteria -! - stop: A flag allowing the user to terminate model execution -! - iwork: A workspace array (N-by-1) -! - err: An error handling mechanism -subroutine lm_iter(fun, xdata, ydata, p, neval, niter, update, lambda, & - maxP, minP, weights, JtWJ, JtWdy, h, pNew, deltaY, yNew, X2, X2Old, & - alpha, stop, iwork, err, status) - ! Arguments - procedure(regression_function), pointer :: fun - real(real64), intent(in) :: xdata(:), ydata(:), p(:), maxP(:), & - minP(:), weights(:), JtWdy(:) - real(real64), intent(in) :: lambda, X2Old - integer(int32), intent(inout) :: neval, niter - integer(int32), intent(in) :: update - real(real64), intent(inout) :: JtWJ(:,:) - real(real64), intent(out) :: h(:), pNew(:), deltaY(:), yNew(:) - real(real64), intent(out) :: X2, alpha - logical, intent(out) :: stop - integer(int32), intent(out) :: iwork(:) - class(errors), intent(inout) :: err - procedure(iteration_update), intent(in), pointer, optional :: status - - ! Local Variables - integer(int32) :: i, n - real(real64) :: dpJh - - ! Initialization - n = size(p) - - ! Increment the iteration counter - niter = niter + 1 - - ! Solve the linear system to determine the change in parameters - ! A is N-by-N and is stored in JtWJ - ! b is N-by-1 - if (update == FS_LEVENBERG_MARQUARDT_UPDATE) then - ! Compute: h = A \ b - ! A = J**T * W * J + lambda * diag(J**T * W * J) - ! b = J**T * W * dy - do i = 1, n - JtWJ(i,i) = JtWJ(i,i) * (1.0d0 + lambda) - h(i) = JtWdy(i) - end do - else - ! Compute: h = A \ b - ! A = J**T * W * J + lambda * I - ! b = J**T * W * dy - do i = 1, n - JtWJ(i,i) = JtWJ(i,i) + lambda - h(i) = JtWdy(i) - end do - end if - call lu_factor(JtWJ, iwork, err) ! overwrites JtWJ with [L\U] - if (err%has_error_occurred()) return ! if JtWJ is singular - call solve_lu(JtWJ, iwork, h) ! solution stored in h - - ! Compute the new attempted solution, and apply any constraints - do i = 1, n - pNew(i) = min(max(minP(i), h(i) + p(i)), maxP(i)) - end do - - ! Update the residual error - call fun(xdata, pNew, yNew, stop) - neval = neval + 1 - deltaY = ydata - yNew - if (stop) return - - ! Update the Chi-squared estimate - X2 = dot_product(deltaY, deltaY * weights) - - ! Perform a quadratic line update in the H direction, if necessary - if (update == FS_QUADRATIC_UPDATE) then - dpJh = dot_product(JtWdy, h) - alpha = abs(dpJh / (0.5d0 * (X2 - X2Old) + 2.0d0 * dpJh)) - h = alpha * h - - do i = 1, n - pNew(i) = min(max(minP(i), p(i) + h(i)), maxP(i)) - end do - - call fun(xdata, pNew, yNew, stop) - if (stop) return - neval = neval + 1 - deltaY = ydata - yNew - X2 = dot_product(deltaY, deltaY * weights) - end if - - ! Update the status of the iteration, if needed - if (present(status)) then - call status(niter, yNew, deltaY, pNew, h) - end if -end subroutine - -! ------------------------------------------------------------------------------ -! A Levenberg-Marquardt solver. -! -! Inputs: -! - fun: The function to evaluate -! - xdata: The independent coordinate data to fit (M-by-1) -! - ydata: The dependent coordinate data to fit (M-by-1) -! - p: current set of parameters (N-by-1) -! - weights: a weighting vector (M-by-1) -! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) -! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) -! - controls: an iteration_controls instance containing solution tolerances -! -! Outputs: -! - p: solution (N-by-1) -! - y: model results at p (M-by-1) -! - resid: residual (ydata - y) (M-by-1) -! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) -! - opt: a convergence_info object containing information regarding -! convergence of the iteration -! - stop: A flag allowing the user to terminate model execution -! - err: An error handling object -subroutine lm_solve(fun, xdata, ydata, p, weights, maxP, minP, controls, & - opt, y, resid, JtWJ, info, stop, err, status) - ! Arguments - procedure(regression_function), intent(in), pointer :: fun - real(real64), intent(in) :: xdata(:), ydata(:), weights(:), maxP(:), & - minP(:) - real(real64), intent(inout) :: p(:) - class(iteration_controls), intent(in) :: controls - class(lm_solver_options), intent(in) :: opt - real(real64), intent(out) :: y(:), resid(:), JtWJ(:,:) - class(convergence_info), intent(out) :: info - logical, intent(out) :: stop - class(errors), intent(inout) :: err - procedure(iteration_update), intent(in), pointer, optional :: status - - ! Local Variables - logical :: update - integer(int32) :: i, m, n, dof, flag, neval, niter, nupdate - real(real64) :: dX2, X2, X2Old, X2Try, lambda, alpha, nu, step - real(real64), allocatable :: pOld(:), yOld(:), J(:,:), JtWdy(:), & - work(:), mwork(:,:), pTry(:), yTemp(:), JtWJc(:,:), h(:) - integer(int32), allocatable :: iwork(:) - character(len = :), allocatable :: errmsg - - ! Initialization - update = .true. - m = size(xdata) - n = size(p) - dof = m - n - niter = 0 - step = opt%finite_difference_step_size - stop = .false. - info%user_requested_stop = .false. - nupdate = 0 - - ! Local Memory Allocation - allocate(pOld(n), source = 0.0d0, stat = flag) - if (flag == 0) allocate(yOld(m), source = 0.0d0, stat = flag) - if (flag == 0) allocate(J(m, n), stat = flag) - if (flag == 0) allocate(JtWdy(n), stat = flag) - if (flag == 0) allocate(work(m + n), stat = flag) - if (flag == 0) allocate(mwork(n, m), stat = flag) - if (flag == 0) allocate(pTry(n), stat = flag) - if (flag == 0) allocate(h(n), stat = flag) - if (flag == 0) allocate(yTemp(m), stat = flag) - if (flag == 0) allocate(JtWJc(n, n), stat = flag) - if (flag == 0) allocate(iwork(n), stat = flag) - if (flag /= 0) go to 10 - - ! Perform an initial function evaluation - call fun(xdata, p, y, stop) - neval = 1 - - ! Evaluate the problem matrices - call lm_matrix(fun, xdata, ydata, pOld, yOld, 1.0d0, J, p, weights, & - neval, update, step, JtWJ, JtWdy, X2, y, stop, work, mwork) - if (stop) go to 5 - X2Old = X2 - JtWJc = JtWJ - - ! Determine an initial value for lambda - if (opt%method == FS_LEVENBERG_MARQUARDT_UPDATE) then - lambda = 1.0d-2 - else - call extract_diagonal(JtWJ, work(1:n)) - lambda = 1.0d-2 * maxval(work(1:n)) - nu = 2.0d0 - end if - - ! Main Loop - main : do while (niter < controls%max_iteration_count) - ! Compute the linear solution at the current solution estimate and - ! update the new parameter estimates - call lm_iter(fun, xdata, ydata, p, neval, niter, opt%method, & - lambda, maxP, minP, weights, JtWJc, JtWdy, h, pTry, resid, & - yTemp, X2Try, X2Old, alpha, stop, iwork, err, status) - if (stop) go to 5 - if (err%has_error_occurred()) return - - ! Update the Chi-squared estimate, update the damping parameter - ! lambda, and, if necessary, update the matrices - call lm_update(fun, xdata, ydata, pOld, p, pTry, yOld, y, h, dX2, & - X2Old, X2, X2Try, lambda, alpha, nu, JtWdy, JtWJ, J, weights, & - niter, neval, update, step, work, mwork, controls, opt, stop) - if (stop) go to 5 - JtWJc = JtWJ - - ! Determine the matrix update scheme - nupdate = nupdate + 1 - if (opt%method == FS_QUADRATIC_UPDATE) then - update = mod(niter, 2 * n) > 0 - else if (nupdate >= controls%max_iteration_between_updates) then - update = .true. - nupdate = 0 - end if - - ! Test for convergence - if (lm_check_convergence(controls, dof, resid, niter, neval, & - JtWdy, h, p, X2, info)) & - then - exit main - end if - end do main - - ! End - return - - ! User Requested End -5 continue - info%user_requested_stop = .true. - return - - ! Memory Error Handling -10 continue - allocate(character(len = 512) :: errmsg) - write(errmsg, 100) "Memory allocation error code ", flag, "." - call err%report_error("lm_solve", & - trim(errmsg), FS_MEMORY_ERROR) - return - - ! Formatting -100 format(A, I0, A) -end subroutine - -! ------------------------------------------------------------------------------ -! -subroutine lm_update(fun, xdata, ydata, pOld, p, pTry, yOld, y, h, dX2, & - X2old, X2, X2try, lambda, alpha, nu, JtWdy, JtWJ, J, weights, niter, & - neval, update, step, work, mwork, controls, opt, stop) - ! Arguments - procedure(regression_function), intent(in), pointer :: fun - real(real64), intent(in) :: xdata(:), ydata(:), X2try, h(:), step, & - pTry(:), weights(:), alpha - real(real64), intent(inout) :: pOld(:), p(:), yOld(:), y(:), lambda, & - JtWdy(:), dX2, X2, X2old, JtWJ(:,:), J(:,:), nu - real(real64), intent(out) :: work(:), mwork(:,:) - integer(int32), intent(in) :: niter - integer(int32), intent(inout) :: neval - logical, intent(inout) :: update - class(iteration_controls), intent(in) :: controls - class(lm_solver_options), intent(in) :: opt - logical, intent(out) :: stop - - ! Local Variables - integer(int32) :: n - real(real64) :: rho - - ! Initialization - n = size(p) - - ! Process - if (opt%method == FS_LEVENBERG_MARQUARDT_UPDATE) then - call extract_diagonal(JtWJ, work(1:n)) - work(1:n) = lambda * work(1:n) * h + JtWdy - else - work(1:n) = lambda * h + JtWdy - end if - rho = (X2 - X2try) / abs(dot_product(h, work(1:n))) - if (rho > controls%iteration_improvement_tolerance) then - ! Things are getting better at an acceptable rate - dX2 = X2 - X2old - X2old = X2 - pOld = p - yOld = y - p = pTry - - ! Recompute the matrices - call lm_matrix(fun, xdata, ydata, pOld, yOld, dX2, J, p, weights, & - neval, update, step, JtWJ, JtWdy, X2, y, stop, work, mwork) - if (stop) return - - ! Decrease lambda - select case (opt%method) - case (FS_LEVENBERG_MARQUARDT_UPDATE) - lambda = max(lambda / opt%damping_decrease_factor, 1.0d-7) - case (FS_QUADRATIC_UPDATE) - lambda = max(lambda / (1.0d0 + alpha), 1.0d-7) - case (FS_NIELSEN_UPDATE) - lambda = lambda * max(1.0d0 / 3.0d0, & - 1.0d0 - (2.0d0 * rho - 1.0d0**3)) - nu = 2.0d0 - end select - else - ! The iteration is not improving in a satisfactory manner - X2 = X2old - if (mod(niter, 2 * n) /= 0) then - call lm_matrix(fun, xdata, ydata, pOld, yOld, -1.0d0, J, p, & - weights, neval, update, step, JtWJ, JtWdy, dX2, y, stop, & - work, mwork) - if (stop) return - end if - - ! Increase lambda - select case (opt%method) - case (FS_LEVENBERG_MARQUARDT_UPDATE) - lambda = min(lambda * opt%damping_increase_factor, 1.0d7) - case (FS_QUADRATIC_UPDATE) - lambda = lambda + abs((X2try - X2) / 2.0d0 / alpha) - case (FS_NIELSEN_UPDATE) - lambda = lambda * nu - nu = 2.0d0 * nu - end select - end if -end subroutine - -! ------------------------------------------------------------------------------ -! Checks the Levenberg-Marquardt solution against the convergence criteria. -! -! Inputs: -! - controls: the solution controls and convergence criteria -! - dof: the statistical degrees of freedom of the system (M - N) -! - resid: the residual error (M-by-1) -! - niter: the number of iterations -! - neval: the number of function evaluations -! - JtWdy: linearized fitting vector (N-by-1) -! - h: the change in parameter (solution) values (N-by-1) -! - p: the parameter (solution) values (N-by-1) -! - X2: the Chi-squared estimate -! -! Outputs: -! - info: The convergence information. -! - rst: True if convergence was achieved; else, false. -function lm_check_convergence(controls, dof, resid, niter, neval, & - JtWdy, h, p, X2, info) result(rst) - ! Arguments - class(iteration_controls), intent(in) :: controls - real(real64), intent(in) :: resid(:), JtWdy(:), h(:), p(:), X2 - integer(int32), intent(in) :: dof, niter, neval - class(convergence_info), intent(out) :: info - logical :: rst - - ! Initialization - rst = .false. - - ! Iteration Checks - info%iteration_count = niter - if (niter >= controls%max_iteration_count) then - info%reach_iteration_limit = .true. - rst = .true. - else - info%reach_iteration_limit = .false. - end if - - info%function_evaluation_count = neval - if (neval >= controls%max_function_evaluations) then - info%reach_function_evaluation_limit = .true. - rst = .true. - else - info%reach_function_evaluation_limit = .false. - end if - - info%gradient_value = maxval(abs(JtWdy)) - if (info%gradient_value < controls%gradient_tolerance .and. niter > 2) & - then - info%converge_on_gradient = .true. - rst = .true. - else - info%converge_on_gradient = .false. - end if - - info%solution_change_value = maxval(abs(h) / (abs(p) + 1.0d-12)) - if (info%solution_change_value < & - controls%change_in_solution_tolerance .and. niter > 2) & - then - info%converge_on_solution_change = .true. - rst = .true. - else - info%converge_on_solution_change = .false. - end if - - info%residual_value = X2 / dof - if (info%residual_value < controls%residual_tolerance .and. niter > 2) & - then - info%converge_on_residual_parameter = .true. - rst = .true. - else - info%converge_on_residual_parameter = .false. - end if -end function - -! ------------------------------------------------------------------------------ -end module + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) + !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) + integer(int32), intent(in) :: order + !! The order of the equation to fit. This value must be at + !! least one (linear equation), but can be higher as desired, + !! as long as there is sufficient data. + logical, intent(in) :: intercept + !! Set to true if the intercept is being computed as part of + !! the regression; else, false. + real(real64), intent(in) :: x(:) + !! An N-element array containing the independent variable + !! measurement points. + real(real64), intent(in) :: y(:) + !! An N-element array containing the dependent variable + !! measurement points. + real(real64), intent(out) :: coeffs(:) + !! An ORDER+1 element array where the coefficients will be written. + real(real64), intent(out) :: ymod(:) + !! An N-element array where the modeled data will be written. + real(real64), intent(out) :: resid(:) + !! An N-element array where the residual error data will be + !! written (modeled - actual). + type(regression_statistics), intent(out), optional :: stats(:) + !! An M-element array of regression_statistics items where + !! M = ORDER + 1 when intercept is set to true; however, if + !! intercept is set to false, M = ORDER. + real(real64), intent(in), optional :: alpha + !! The significance level at which to evaluate the confidence + !! intervals. The default value is 0.05 such that a 95% + !! confidence interval is calculated. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not + !! approriately sized. + !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. + !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation + !! error. + + ! Parameters + real(real64), parameter :: zero = 0.0d0 + real(real64), parameter :: half = 0.5d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, npts, ncols, ncoeffs, flag + real(real64) :: alph, var, df, ssr, talpha + real(real64), allocatable :: a(:,:), c(:,:), cxt(:,:) + type(t_distribution) :: dist + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + npts = size(x) + ncoeffs = order + 1 + ncols = order + if (intercept) ncols = ncols + 1 + alph = 0.05d0 + if (present(alpha)) alph = alpha + + ! Input Check + if (order < 1) then + call errmgr%report_error("linear_least_squares", & + "The model order must be at least one.", FS_INVALID_INPUT_ERROR) + return + end if + if (size(y) /= npts) then + call report_array_size_error(errmgr, "linear_least_squares", & + "y", npts, size(y)) + return + end if + if (size(coeffs) /= ncoeffs) then + call report_array_size_error(errmgr, "linear_least_squares", & + "coeffs", ncoeffs, size(coeffs)) + return + end if + if (size(ymod) /= npts) then + call report_array_size_error(errmgr, "linear_least_squares", & + "ymod", npts, size(ymod)) + return + end if + if (size(resid) /= npts) then + call report_array_size_error(errmgr, "linear_least_squares", & + "resid", npts, size(resid)) + return + end if + if (present(stats)) then + if (size(stats) /= ncols) then + call report_array_size_error(errmgr, & + "linear_least_squares", "stats", ncols, size(stats)) + return + end if + end if + + ! Memory Allocation + allocate(a(npts, ncols), stat = flag) + if (flag == 0) allocate(c(ncols, ncols), stat = flag) + if (flag == 0) allocate(cxt(ncols, npts), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "linear_least_squares", flag) + return + end if + + ! Compute the coefficient matrix + call design_matrix(order, intercept, x, a, errmgr) + if (errmgr%has_error_occurred()) return + + ! Compute the covariance matrix + call covariance_matrix(a, c, errmgr) + if (errmgr%has_error_occurred()) return + + ! Compute the coefficients (NCOLS-by-1) + call DGEMM("N", "T", ncols, npts, ncols, one, c, ncols, a, npts, zero, & + cxt, ncols) ! C * X**T + + i = 2 + coeffs(1) = zero + if (intercept) i = 1 + call DGEMM("N", "N", ncols, 1, npts, one, cxt, ncols, y, npts, zero, & + coeffs(i:), ncols) ! (C * X**T) * Y + + ! Evaluate the model and compute the residuals + call DGEMM("N", "N", npts, 1, ncols, one, a, npts, coeffs(i:), & + ncols, zero, ymod, npts) + resid = ymod - y + + ! If the user doesn't want the statistics calculations we can stop now + if (.not.present(stats)) return + + ! Start the process of computing statistics + stats = calculate_regression_statistics(resid, coeffs(i:), c, alph, & + errmgr) +end subroutine + +! ------------------------------------------------------------------------------ +function calculate_regression_statistics(resid, params, c, alpha, err) & + result(rst) + !! Computes statistics for the quality of fit for a regression + !! model. + real(real64), intent(in) :: resid(:) + !! An M-element array containing the model residual errors. + real(real64), intent(in) :: params(:) + !! An N-element array containing the model parameters. + real(real64), intent(in) :: c(:,:) + !! The N-by-N covariance matrix. + real(real64), intent(in), optional :: alpha + !! The significance level at which to evaluate the confidence + !! intervals. The default value is 0.05 such that a 95% + !! confidence interval is calculated. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly. + !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. + !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation + !! error. + type(regression_statistics), allocatable :: rst(:) + !! A regression_statistics object containing the analysis results. + + ! Parameters + real(real64), parameter :: p05 = 0.05d0 + real(real64), parameter :: half = 0.5d0 + real(real64), parameter :: one = 1.0d0 + + ! Local Variables + integer(int32) :: i, m, n, dof, flag + real(real64) :: a, ssr, var, talpha + type(t_distribution) :: dist + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + + ! Initialization + m = size(resid) + n = size(params) + dof = m - n + if (present(alpha)) then + a = alpha + else + a = p05 + end if + allocate(rst(n), stat = flag) + if (flag /= 0) then + end if + + ! Input Checking + if (size(c, 1) /= n .or. size(c, 2) /= n) then + end if + + ! Process + ssr = norm2(resid)**2 ! sum of the squares of the residual + var = ssr / dof + dist%dof = real(dof, real64) + talpha = confidence_interval(dist, a, one, 1) + do i = 1, n + rst(i)%standard_error = sqrt(var * c(i,i)) + rst(i)%t_statistic = params(i) / rst(i)%standard_error + rst(i)%probability = regularized_beta( & + half * dof, & + half, & + real(dof, real64) / (dof + (rst(i)%t_statistic)**2) & + ) + rst(i)%confidence_interval = talpha * rst(i)%standard_error + end do +end function + +! ------------------------------------------------------------------------------ +subroutine jacobian(fun, xdata, params, & + jac, stop, f0, f1, step, err) + !! Computes the Jacobian matrix for a nonlinear regression problem. + procedure(regression_function), intent(in), pointer :: fun + !! A pointer to the regression_function to evaluate. + real(real64), intent(in) :: xdata(:) + !! The M-element array containing x-coordinate data. + real(real64), intent(in) :: params(:) + !! The N-element array containing the model parameters. + real(real64), intent(out) :: jac(:,:) + !! The M-by-N matrix where the Jacobian will be written. + logical, intent(out) :: stop + !! A value that the user can set in fun forcing the + !! evaluation process to stop prior to completion. + real(real64), intent(in), optional, target :: f0(:) + !! An optional M-element array containing the model values + !! using the current parameters as defined in m. This input + !! can be used to prevent the routine from performing a + !! function evaluation at the model parameter state defined in + !! params. + real(real64), intent(out), optional, target :: f1(:) + !! An optional M-element workspace array used for function + !! evaluations. + real(real64), intent(in), optional :: step + !! The differentiation step size. The default is the square + !! root of machine precision. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not + !! properly sized. + !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation + !! error. + + ! Local Variables + real(real64) :: h + integer(int32) :: m, n, flag, expected, actual + real(real64), pointer :: f1p(:), f0p(:) + real(real64), allocatable, target :: f1a(:), f0a(:), work(:) + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + if (present(step)) then + h = step + else + h = sqrt(epsilon(h)) + end if + m = size(xdata) + n = size(params) + + ! Input Size Checking + if (size(jac, 1) /= m .or. size(jac, 2) /= n) then + call report_matrix_size_error(errmgr, "jacobian", & + "JAC", m, n, size(jac, 1), size(jac, 2)) + return + end if + if (present(f0)) then + ! Check Size + if (size(f0) /= m) then + call report_array_size_error(errmgr, "jacobian", & + "F0", m, size(f0)) + return + end if + f0p(1:m) => f0 + else + ! Allocate space, and fill the array with the current function + ! results + allocate(f0a(m), stat = flag) + if (flag /= 0) go to 20 + f0p(1:m) => f0a + call fun(xdata, params, f0p, stop) + if (stop) return + end if + if (present(f1)) then + ! Check Size + if (size(f1) /= m) then + call report_array_size_error(errmgr, "jacobian", & + "F1", m, size(f1)) + return + end if + f1p(1:m) => f1 + else + ! Allocate space + allocate(f1a(m), stat = flag) + if (flag /= 0) go to 20 + f1p(1:m) => f1a + end if + + ! Allocate a workspace array the same size as params + allocate(work(n), stat = flag) + if (flag /= 0) go to 20 + + ! Compute the Jacobian + call jacobian_finite_diff(fun, xdata, params, f0p, jac, f1p, & + stop, h, work) + + ! End + return + + ! Memroy Allocation Error Handling +20 continue + call report_memory_error(errmgr, "jacobian", flag) + return +end subroutine + +! ------------------------------------------------------------------------------ +subroutine nonlinear_least_squares(fun, x, y, params, ymod, & + resid, weights, maxp, minp, stats, alpha, controls, settings, info, & + status, err) + !! Performs a nonlinear regression to fit a model using a version + !! of the Levenberg-Marquardt algorithm. + procedure(regression_function), intent(in), pointer :: fun + !! A pointer to the regression_function to evaluate. + real(real64), intent(in) :: x(:) + !! The M-element array containing independent data. + real(real64), intent(in) :: y(:) + !! The M-element array containing dependent data. + real(real64), intent(inout) :: params(:) + !! On input, the N-element array containing the initial estimate + !! of the model parameters. On output, the computed model + !! parameters. + real(real64), intent(out) :: ymod(:) + !! An M-element array where the modeled dependent data will + !! be written. + real(real64), intent(out) :: resid(:) + !! An M-element array where the model residuals will be + !! written. + real(real64), intent(in), optional, target :: weights(:) + !! An optional M-element array allowing the weighting of + !! individual points. + real(real64), intent(in), optional, target :: maxp(:) + !! An optional N-element array that can be used as upper limits + !! on the parameter values. If no upper limit is requested for + !! a particular parameter, utilize a very large value. The + !! internal default is to utilize huge() as a value. + real(real64), intent(in), optional, target :: minp(:) + !! An optional N-element array that can be used as lower limits + !! on the parameter values. If no lower limit is requested for + !! a particalar parameter, utilize a very large magnitude, but + !! negative, value. The internal default is to utilize -huge() + !! as a value. + type(regression_statistics), intent(out), optional :: stats(:) + !! An optional N-element array that, if supplied, will be used + !! to return statistics about the fit for each parameter. + real(real64), intent(in), optional :: alpha + !! The significance level at which to evaluate the confidence + !! intervals. The default value is 0.05 such that a 95% + !! confidence interval is calculated. + type(iteration_controls), intent(in), optional :: controls + !! An optional input providing custom iteration controls. + type(lm_solver_options), intent(in), optional :: settings + !! An optional input providing custom settings for the solver. + type(convergence_info), intent(out), optional, target :: info + !! An optional output that can be used to gain information about + !! the iterative solution and the nature of the convergence. + procedure(iteration_update), intent(in), pointer, optional :: status + !! An optional pointer to a routine that can be used to extract + !! iteration information. + class(errors), intent(inout), optional, target :: err + !! A mechanism for communicating errors and warnings to the + !! caller. Possible warning and error codes are as follows. + !! - FS_NO_ERROR: No errors encountered. + !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not + !! properly sized. + !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation + !! error. + !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed + !! is underdetetermined (M < N). + !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied + !! tolerances are too small to be practical. + !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations + !! are allowed. + + ! Parameters + real(real64), parameter :: too_small = 1.0d-14 + integer(int32), parameter :: min_iter_count = 2 + integer(int32), parameter :: min_fun_count = 10 + integer(int32), parameter :: min_update_count = 1 + + ! Local Variables + logical :: stop + integer(int32) :: m, n, actual, expected, flag + real(real64), pointer :: w(:), pmax(:), pmin(:) + real(real64), allocatable, target :: defaultWeights(:), maxparam(:), & + minparam(:), JtWJ(:,:) + type(iteration_controls) :: tol + type(lm_solver_options) :: opt + type(convergence_info) :: cInfo + class(errors), pointer :: errmgr + type(errors), target :: deferr + type(convergence_info), target :: defaultinfo + type(convergence_info), pointer :: inf + + ! Initialization + stop = .false. + m = size(x) + n = size(params) + if (present(info)) then + inf => info + else + inf => defaultinfo + end if + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + if (present(controls)) then + tol = controls + else + call tol%set_to_default() + end if + if (present(settings)) then + opt = settings + else + call opt%set_to_default() + end if + + ! Input Checking + if (size(y) /= m) then + call report_array_size_error(errmgr, "nonlinear_least_squares", & + "y", m, size(y)) + return + end if + if (size(ymod) /= m) then + call report_array_size_error(errmgr, "nonlinear_least_squares", & + "ymod", m, size(ymod)) + return + end if + if (size(resid) /= m) then + call report_array_size_error(errmgr, "nonlinear_least_squares", & + "resid", m, size(resid)) + return + end if + if (m < n) then + call report_underdefined_error(errmgr, & + "nonlinear_least_squares", n, m) + return + end if + + ! Tolerance Checking + if (tol%gradient_tolerance < too_small) then + call errmgr%report_error("nonlinear_least_squares", & + "The gradient tolerance was found to be too small.", & + FS_TOLERANCE_TOO_SMALL_ERROR) + return + end if + if (tol%change_in_solution_tolerance < too_small) then + call errmgr%report_error("nonlinear_least_squares", & + "The change in solution tolerance was found to be too small.", & + FS_TOLERANCE_TOO_SMALL_ERROR) + return + end if + if (tol%residual_tolerance < too_small) then + call errmgr%report_error("nonlinear_least_squares", & + "The residual error tolerance was found to be too small.", & + FS_TOLERANCE_TOO_SMALL_ERROR) + return + end if + if (tol%iteration_improvement_tolerance < too_small) then + call errmgr%report_error("nonlinear_least_squares", & + "The iteration improvement tolerance was found to be too small.", & + FS_TOLERANCE_TOO_SMALL_ERROR) + return + end if + + ! Iteration Count Checking + if (tol%max_iteration_count < min_iter_count) then + call report_iteration_count_error(errmgr, & + "nonlinear_least_squares", & + "Too few iterations were specified.", & + min_iter_count) + return + end if + if (tol%max_function_evaluations < min_fun_count) then + call report_iteration_count_error(errmgr, & + "nonlinear_least_squares", & + "Too few function evaluations were specified.", & + min_fun_count) + return + end if + if (tol%max_iteration_between_updates < min_update_count) then + call report_iteration_count_error(errmgr, & + "nonlinear_least_squares", & + "Too few iterations between updates were specified.", & + min_update_count) + return + end if + + ! Optional Array Arguments (weights, parameter limits, etc.) + if (present(weights)) then + if (size(weights) < m) then + call report_array_size_error(errmgr, & + "nonlinear_least_squares", "weights", m, size(weights)) + return + end if + w(1:m) => weights(1:m) + else + allocate(defaultWeights(m), source = 1.0d0, stat = flag) + if (flag /= 0) go to 50 + w(1:m) => defaultWeights(1:m) + end if + + if (present(maxp)) then + if (size(maxp) /= n) then + call report_array_size_error(errmgr, & + "nonlinear_least_squares", "maxp", n, size(maxp)) + return + end if + pmax(1:n) => maxp(1:n) + else + allocate(maxparam(n), source = huge(1.0d0), stat = flag) + if (flag /= 0) go to 50 + pmax(1:n) => maxparam(1:n) + end if + + if (present(minp)) then + if (size(minp) /= n) then + call report_array_size_error(errmgr, & + "nonlinear_least_squares", "minp", n, size(minp)) + return + end if + pmin(1:n) => minp(1:n) + else + allocate(minparam(n), source = -huge(1.0d0), stat = flag) + if (flag /= 0) go to 50 + pmin(1:n) => minparam(1:n) + end if + + ! Local Memory Allocations + allocate(JtWJ(n, n), stat = flag) + if (flag /= 0) go to 50 + + ! Process + call lm_solve(fun, x, y, params, w, pmax, pmin, tol, opt, ymod, & + resid, JtWJ, inf, stop, errmgr, status) + + ! Statistical Parameters + if (present(stats)) then + if (size(stats) /= n) then + call report_array_size_error(errmgr, & + "nonlinear_least_squares", "stats", n, size(stats)) + return + end if + + ! Compute the covariance matrix + call mtx_inverse(JtWJ, err = errmgr) + if (errmgr%has_error_occurred()) return + + ! Compute the statistics + stats = calculate_regression_statistics(resid, params, JtWJ, & + alpha, errmgr) + end if + + ! End + return + + ! Memory Error Handler +50 continue + call report_memory_error(errmgr, "nonlinear_least_squares", flag) + return +end subroutine + +! ****************************************************************************** +! SETTINGS DEFAULTS +! ------------------------------------------------------------------------------ +! Sets up default tolerances. +subroutine lm_set_default_tolerances(x) + ! Arguments + class(iteration_controls), intent(inout) :: x + + ! Set defaults + x%max_iteration_count = 500 + x%max_function_evaluations = 5000 + x%max_iteration_between_updates = 10 + x%gradient_tolerance = 1.0d-8 + x%residual_tolerance = 0.5d-2 + x%change_in_solution_tolerance = 1.0d-6 + x%iteration_improvement_tolerance = 1.0d-1 +end subroutine + +! ------------------------------------------------------------------------------ +! Sets up default solver settings. +subroutine lm_set_default_settings(x) + ! Arguments + class(lm_solver_options), intent(inout) :: x + + ! Set defaults + x%method = FS_LEVENBERG_MARQUARDT_UPDATE + x%finite_difference_step_size = sqrt(epsilon(1.0d0)) + x%damping_increase_factor = 11.0d0 + x%damping_decrease_factor = 9.0d0 +end subroutine + +! ****************************************************************************** +! PRIVATE ROUTINES +! ------------------------------------------------------------------------------ +! Computes the Jacobian matrix via a forward difference. +! +! Inputs: +! - fun: The function to evaluate +! - xdata: The independent coordinate data to fit (M-by-1) +! - params: The model parameters (N-by-1) +! - f0: The current model estimate (M-by-1) +! - step: The differentiation step size +! +! Outputs: +! - jac: The Jacobian matrix (M-by-N) +! - f1: A workspace array for the model output (M-by-1) +! - stop: A flag allowing the user to terminate model execution +! - work: A workspace array for the model parameters (N-by-1) +subroutine jacobian_finite_diff(fun, xdata, params, f0, jac, f1, & + stop, step, work) + ! Arguments + procedure(regression_function), intent(in), pointer :: fun + real(real64), intent(in) :: xdata(:), params(:) + real(real64), intent(in) :: f0(:) + real(real64), intent(out) :: jac(:,:) + real(real64), intent(out) :: f1(:), work(:) + logical, intent(out) :: stop + real(real64), intent(in) :: step + + ! Local Variables + integer(int32) :: i, n + + ! Initialization + n = size(params) + + ! Cycle over each column of the Jacobian and calculate the derivative + ! via a forward difference scheme + ! + ! J(i,j) = df(i) / dx(j) + work = params + do i = 1, n + work(i) = work(i) + step + call fun(xdata, work, f1, stop) + if (stop) return + + jac(:,i) = (f1 - f0) / step + work(i) = params(i) + end do +end subroutine + +! ------------------------------------------------------------------------------ +! Computes a rank-1 update to the Jacobian matrix +! +! Inputs: +! - pOld: previous set of parameters (N-by-1) +! - yOld: model evaluation at previous set of parameters (M-by-1) +! - jac: current Jacobian estimate (M-by-N) +! - p: current set of parameters (N-by-1) +! - y: model evaluation at current set of parameters (M-by-1) +! +! Outputs: +! - jac: updated Jacobian matrix (M-by-N) (dy * dp**T + J) +! - dp: p - pOld (N-by-1) +! - dy: (y - yOld - J * dp) / (dp' * dp) (M-by-1) +subroutine broyden_update(pOld, yOld, jac, p, y, dp, dy) + ! Arguments + real(real64), intent(in) :: pOld(:), yOld(:), p(:), y(:) + real(real64), intent(inout) :: jac(:,:) + real(real64), intent(out) :: dp(:), dy(:) + + ! Local Variables + real(real64) :: h2 + + ! Process + dp = p - pOld + h2 = dot_product(dp, dp) + dy = y - yOld - matmul(jac, dp) + dy = dy / h2 + call rank1_update(1.0d0, dy, dp, jac) +end subroutine + +! ------------------------------------------------------------------------------ +! Updates the Levenberg-Marquardt matrix by either computing a new Jacobian +! matrix or performing a rank-1 update to the existing Jacobian matrix. +! +! Inputs: +! - fun: The function to evaluate +! - xdata: The independent coordinate data to fit (M-by-1) +! - ydata: The dependent coordinate data to fit (M-by-1) +! - pOld: previous set of parameters (N-by-1) +! - yOld: model evaluation at previous set of parameters (M-by-1) +! - dX2: The previous change in the Chi-squared criteria +! - jac: current Jacobian estimate (M-by-N) +! - p: current set of parameters (N-by-1) +! - weights: A weighting vector (M-by-1) +! - neval: Current number of function evaluations +! - update: Set to true to force an update of the Jacobian; else, set to +! false to let the program choose based upon the change in the +! Chi-squared parameter. +! - step: The differentiation step size +! +! Outputs: +! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) +! - JtWdy: linearized fitting vector (N-by-1) +! - X2: Updated Chi-squared criteria +! - yNew: model evaluated with parameters of p (M-by-1) +! - jac: updated Jacobian matrix (M-by-N) +! - neval: updated count of function evaluations +! - stop: A flag allowing the user to terminate model execution +! - work: A workspace array (N+M-by-1) +! - mwork: A workspace matrix (N-by-M) +! - update: Reset to false if a Jacobian evaluation was performed. +subroutine lm_matrix(fun, xdata, ydata, pOld, yOld, dX2, jac, p, weights, & + neval, update, step, JtWJ, JtWdy, X2, yNew, stop, work, mwork) + ! Arguments + procedure(regression_function), pointer :: fun + real(real64), intent(in) :: xdata(:), ydata(:), pOld(:), yOld(:), & + p(:), weights(:) + real(real64), intent(in) :: dX2, step + real(real64), intent(inout) :: jac(:,:) + integer(int32), intent(inout) :: neval + logical, intent(inout) :: update + real(real64), intent(out) :: JtWJ(:,:), JtWdy(:) + real(real64), intent(out) :: X2, mwork(:,:), yNew(:) + logical, intent(out) :: stop + real(real64), intent(out), target :: work(:) + + ! Local Variables + integer(int32) :: m, n + real(real64), pointer :: w1(:), w2(:) + + ! Initialization + m = size(xdata) + n = size(p) + w1(1:m) => work(1:m) + w2(1:n) => work(m+1:n+m) + + ! Perform the next function evaluation + call fun(xdata, p, yNew, stop) + neval = neval + 1 + if (stop) return + + ! Update or recompute the Jacobian matrix + if (dX2 > 0 .or. update) then + ! Recompute the Jacobian + call jacobian_finite_diff(fun, xdata, p, yNew, jac, w1, & + stop, step, w2) + neval = neval + n + if (stop) return + update = .false. + else + ! Simply perform a rank-1 update to the Jacobian + call broyden_update(pOld, yOld, jac, p, yNew, w2, w1) + end if + + ! Update the Chi-squared estimate + w1 = ydata - yNew + X2 = dot_product(w1, w1 * weights) + + ! Compute J**T * (W .* dY) + w1 = w1 * weights + call mtx_mult(.true., 1.0d0, jac, w1, 0.0d0, JtWdy) + + ! Update the Hessian + ! First: J**T * W = MWORK + ! Second: (J**T * W) * J + call diag_mtx_mult(.false., .true., 1.0d0, weights, jac, 0.0d0, mwork) + call mtx_mult(.false., .false., 1.0d0, mwork, jac, 0.0d0, JtWJ) +end subroutine + +! ------------------------------------------------------------------------------ +! Performs a single iteration of the Levenberg-Marquardt algorithm. +! +! Inputs: +! - fun: The function to evaluate +! - xdata: The independent coordinate data to fit (M-by-1) +! - ydata: The dependent coordinate data to fit (M-by-1) +! - p: current set of parameters (N-by-1) +! - neval: current number of function evaluations +! - niter: current iteration number +! - update: set to 1 to use Marquardt's modification; else, +! - step: the differentiation step size +! - lambda: LM damping parameter +! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) +! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) +! - weights: a weighting vector (M-by-1) +! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) +! - JtWdy: linearized fitting vector (N-by-1) +! +! Outputs: +! - JtWJ: overwritten LU factorization of the original matrix (N-by-N) +! - h: The new estimate of the change in parameter (N-by-1) +! - pNew: The new parameter estimates (N-by-1) +! - deltaY: The new difference between data and model (M-by-1) +! - yNew: model evaluated with parameters of pNew (M-by-1) +! - neval: updated count of function evaluations +! - niter: updated current iteration number +! - X2: updated Chi-squared criteria +! - stop: A flag allowing the user to terminate model execution +! - iwork: A workspace array (N-by-1) +! - err: An error handling mechanism +subroutine lm_iter(fun, xdata, ydata, p, neval, niter, update, lambda, & + maxP, minP, weights, JtWJ, JtWdy, h, pNew, deltaY, yNew, X2, X2Old, & + alpha, stop, iwork, err, status) + ! Arguments + procedure(regression_function), pointer :: fun + real(real64), intent(in) :: xdata(:), ydata(:), p(:), maxP(:), & + minP(:), weights(:), JtWdy(:) + real(real64), intent(in) :: lambda, X2Old + integer(int32), intent(inout) :: neval, niter + integer(int32), intent(in) :: update + real(real64), intent(inout) :: JtWJ(:,:) + real(real64), intent(out) :: h(:), pNew(:), deltaY(:), yNew(:) + real(real64), intent(out) :: X2, alpha + logical, intent(out) :: stop + integer(int32), intent(out) :: iwork(:) + class(errors), intent(inout) :: err + procedure(iteration_update), intent(in), pointer, optional :: status + + ! Local Variables + integer(int32) :: i, n + real(real64) :: dpJh + + ! Initialization + n = size(p) + + ! Increment the iteration counter + niter = niter + 1 + + ! Solve the linear system to determine the change in parameters + ! A is N-by-N and is stored in JtWJ + ! b is N-by-1 + if (update == FS_LEVENBERG_MARQUARDT_UPDATE) then + ! Compute: h = A \ b + ! A = J**T * W * J + lambda * diag(J**T * W * J) + ! b = J**T * W * dy + do i = 1, n + JtWJ(i,i) = JtWJ(i,i) * (1.0d0 + lambda) + h(i) = JtWdy(i) + end do + else + ! Compute: h = A \ b + ! A = J**T * W * J + lambda * I + ! b = J**T * W * dy + do i = 1, n + JtWJ(i,i) = JtWJ(i,i) + lambda + h(i) = JtWdy(i) + end do + end if + call lu_factor(JtWJ, iwork, err) ! overwrites JtWJ with [L\U] + if (err%has_error_occurred()) return ! if JtWJ is singular + call solve_lu(JtWJ, iwork, h) ! solution stored in h + + ! Compute the new attempted solution, and apply any constraints + do i = 1, n + pNew(i) = min(max(minP(i), h(i) + p(i)), maxP(i)) + end do + + ! Update the residual error + call fun(xdata, pNew, yNew, stop) + neval = neval + 1 + deltaY = ydata - yNew + if (stop) return + + ! Update the Chi-squared estimate + X2 = dot_product(deltaY, deltaY * weights) + + ! Perform a quadratic line update in the H direction, if necessary + if (update == FS_QUADRATIC_UPDATE) then + dpJh = dot_product(JtWdy, h) + alpha = abs(dpJh / (0.5d0 * (X2 - X2Old) + 2.0d0 * dpJh)) + h = alpha * h + + do i = 1, n + pNew(i) = min(max(minP(i), p(i) + h(i)), maxP(i)) + end do + + call fun(xdata, pNew, yNew, stop) + if (stop) return + neval = neval + 1 + deltaY = ydata - yNew + X2 = dot_product(deltaY, deltaY * weights) + end if + + ! Update the status of the iteration, if needed + if (present(status)) then + call status(niter, yNew, deltaY, pNew, h) + end if +end subroutine + +! ------------------------------------------------------------------------------ +! A Levenberg-Marquardt solver. +! +! Inputs: +! - fun: The function to evaluate +! - xdata: The independent coordinate data to fit (M-by-1) +! - ydata: The dependent coordinate data to fit (M-by-1) +! - p: current set of parameters (N-by-1) +! - weights: a weighting vector (M-by-1) +! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) +! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) +! - controls: an iteration_controls instance containing solution tolerances +! +! Outputs: +! - p: solution (N-by-1) +! - y: model results at p (M-by-1) +! - resid: residual (ydata - y) (M-by-1) +! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) +! - opt: a convergence_info object containing information regarding +! convergence of the iteration +! - stop: A flag allowing the user to terminate model execution +! - err: An error handling object +subroutine lm_solve(fun, xdata, ydata, p, weights, maxP, minP, controls, & + opt, y, resid, JtWJ, info, stop, err, status) + ! Arguments + procedure(regression_function), intent(in), pointer :: fun + real(real64), intent(in) :: xdata(:), ydata(:), weights(:), maxP(:), & + minP(:) + real(real64), intent(inout) :: p(:) + class(iteration_controls), intent(in) :: controls + class(lm_solver_options), intent(in) :: opt + real(real64), intent(out) :: y(:), resid(:), JtWJ(:,:) + class(convergence_info), intent(out) :: info + logical, intent(out) :: stop + class(errors), intent(inout) :: err + procedure(iteration_update), intent(in), pointer, optional :: status + + ! Local Variables + logical :: update + integer(int32) :: i, m, n, dof, flag, neval, niter, nupdate + real(real64) :: dX2, X2, X2Old, X2Try, lambda, alpha, nu, step + real(real64), allocatable :: pOld(:), yOld(:), J(:,:), JtWdy(:), & + work(:), mwork(:,:), pTry(:), yTemp(:), JtWJc(:,:), h(:) + integer(int32), allocatable :: iwork(:) + character(len = :), allocatable :: errmsg + + ! Initialization + update = .true. + m = size(xdata) + n = size(p) + dof = m - n + niter = 0 + step = opt%finite_difference_step_size + stop = .false. + info%user_requested_stop = .false. + nupdate = 0 + + ! Local Memory Allocation + allocate(pOld(n), source = 0.0d0, stat = flag) + if (flag == 0) allocate(yOld(m), source = 0.0d0, stat = flag) + if (flag == 0) allocate(J(m, n), stat = flag) + if (flag == 0) allocate(JtWdy(n), stat = flag) + if (flag == 0) allocate(work(m + n), stat = flag) + if (flag == 0) allocate(mwork(n, m), stat = flag) + if (flag == 0) allocate(pTry(n), stat = flag) + if (flag == 0) allocate(h(n), stat = flag) + if (flag == 0) allocate(yTemp(m), stat = flag) + if (flag == 0) allocate(JtWJc(n, n), stat = flag) + if (flag == 0) allocate(iwork(n), stat = flag) + if (flag /= 0) go to 10 + + ! Perform an initial function evaluation + call fun(xdata, p, y, stop) + neval = 1 + + ! Evaluate the problem matrices + call lm_matrix(fun, xdata, ydata, pOld, yOld, 1.0d0, J, p, weights, & + neval, update, step, JtWJ, JtWdy, X2, y, stop, work, mwork) + if (stop) go to 5 + X2Old = X2 + JtWJc = JtWJ + + ! Determine an initial value for lambda + if (opt%method == FS_LEVENBERG_MARQUARDT_UPDATE) then + lambda = 1.0d-2 + else + call extract_diagonal(JtWJ, work(1:n)) + lambda = 1.0d-2 * maxval(work(1:n)) + nu = 2.0d0 + end if + + ! Main Loop + main : do while (niter < controls%max_iteration_count) + ! Compute the linear solution at the current solution estimate and + ! update the new parameter estimates + call lm_iter(fun, xdata, ydata, p, neval, niter, opt%method, & + lambda, maxP, minP, weights, JtWJc, JtWdy, h, pTry, resid, & + yTemp, X2Try, X2Old, alpha, stop, iwork, err, status) + if (stop) go to 5 + if (err%has_error_occurred()) return + + ! Update the Chi-squared estimate, update the damping parameter + ! lambda, and, if necessary, update the matrices + call lm_update(fun, xdata, ydata, pOld, p, pTry, yOld, y, h, dX2, & + X2Old, X2, X2Try, lambda, alpha, nu, JtWdy, JtWJ, J, weights, & + niter, neval, update, step, work, mwork, controls, opt, stop) + if (stop) go to 5 + JtWJc = JtWJ + + ! Determine the matrix update scheme + nupdate = nupdate + 1 + if (opt%method == FS_QUADRATIC_UPDATE) then + update = mod(niter, 2 * n) > 0 + else if (nupdate >= controls%max_iteration_between_updates) then + update = .true. + nupdate = 0 + end if + + ! Test for convergence + if (lm_check_convergence(controls, dof, resid, niter, neval, & + JtWdy, h, p, X2, info)) & + then + exit main + end if + end do main + + ! End + return + + ! User Requested End +5 continue + info%user_requested_stop = .true. + return + + ! Memory Error Handling +10 continue + allocate(character(len = 512) :: errmsg) + write(errmsg, 100) "Memory allocation error code ", flag, "." + call err%report_error("lm_solve", & + trim(errmsg), FS_MEMORY_ERROR) + return + + ! Formatting +100 format(A, I0, A) +end subroutine + +! ------------------------------------------------------------------------------ +! +subroutine lm_update(fun, xdata, ydata, pOld, p, pTry, yOld, y, h, dX2, & + X2old, X2, X2try, lambda, alpha, nu, JtWdy, JtWJ, J, weights, niter, & + neval, update, step, work, mwork, controls, opt, stop) + ! Arguments + procedure(regression_function), intent(in), pointer :: fun + real(real64), intent(in) :: xdata(:), ydata(:), X2try, h(:), step, & + pTry(:), weights(:), alpha + real(real64), intent(inout) :: pOld(:), p(:), yOld(:), y(:), lambda, & + JtWdy(:), dX2, X2, X2old, JtWJ(:,:), J(:,:), nu + real(real64), intent(out) :: work(:), mwork(:,:) + integer(int32), intent(in) :: niter + integer(int32), intent(inout) :: neval + logical, intent(inout) :: update + class(iteration_controls), intent(in) :: controls + class(lm_solver_options), intent(in) :: opt + logical, intent(out) :: stop + + ! Local Variables + integer(int32) :: n + real(real64) :: rho + + ! Initialization + n = size(p) + + ! Process + if (opt%method == FS_LEVENBERG_MARQUARDT_UPDATE) then + call extract_diagonal(JtWJ, work(1:n)) + work(1:n) = lambda * work(1:n) * h + JtWdy + else + work(1:n) = lambda * h + JtWdy + end if + rho = (X2 - X2try) / abs(dot_product(h, work(1:n))) + if (rho > controls%iteration_improvement_tolerance) then + ! Things are getting better at an acceptable rate + dX2 = X2 - X2old + X2old = X2 + pOld = p + yOld = y + p = pTry + + ! Recompute the matrices + call lm_matrix(fun, xdata, ydata, pOld, yOld, dX2, J, p, weights, & + neval, update, step, JtWJ, JtWdy, X2, y, stop, work, mwork) + if (stop) return + + ! Decrease lambda + select case (opt%method) + case (FS_LEVENBERG_MARQUARDT_UPDATE) + lambda = max(lambda / opt%damping_decrease_factor, 1.0d-7) + case (FS_QUADRATIC_UPDATE) + lambda = max(lambda / (1.0d0 + alpha), 1.0d-7) + case (FS_NIELSEN_UPDATE) + lambda = lambda * max(1.0d0 / 3.0d0, & + 1.0d0 - (2.0d0 * rho - 1.0d0**3)) + nu = 2.0d0 + end select + else + ! The iteration is not improving in a satisfactory manner + X2 = X2old + if (mod(niter, 2 * n) /= 0) then + call lm_matrix(fun, xdata, ydata, pOld, yOld, -1.0d0, J, p, & + weights, neval, update, step, JtWJ, JtWdy, dX2, y, stop, & + work, mwork) + if (stop) return + end if + + ! Increase lambda + select case (opt%method) + case (FS_LEVENBERG_MARQUARDT_UPDATE) + lambda = min(lambda * opt%damping_increase_factor, 1.0d7) + case (FS_QUADRATIC_UPDATE) + lambda = lambda + abs((X2try - X2) / 2.0d0 / alpha) + case (FS_NIELSEN_UPDATE) + lambda = lambda * nu + nu = 2.0d0 * nu + end select + end if +end subroutine + +! ------------------------------------------------------------------------------ +! Checks the Levenberg-Marquardt solution against the convergence criteria. +! +! Inputs: +! - controls: the solution controls and convergence criteria +! - dof: the statistical degrees of freedom of the system (M - N) +! - resid: the residual error (M-by-1) +! - niter: the number of iterations +! - neval: the number of function evaluations +! - JtWdy: linearized fitting vector (N-by-1) +! - h: the change in parameter (solution) values (N-by-1) +! - p: the parameter (solution) values (N-by-1) +! - X2: the Chi-squared estimate +! +! Outputs: +! - info: The convergence information. +! - rst: True if convergence was achieved; else, false. +function lm_check_convergence(controls, dof, resid, niter, neval, & + JtWdy, h, p, X2, info) result(rst) + ! Arguments + class(iteration_controls), intent(in) :: controls + real(real64), intent(in) :: resid(:), JtWdy(:), h(:), p(:), X2 + integer(int32), intent(in) :: dof, niter, neval + class(convergence_info), intent(out) :: info + logical :: rst + + ! Initialization + rst = .false. + + ! Iteration Checks + info%iteration_count = niter + if (niter >= controls%max_iteration_count) then + info%reach_iteration_limit = .true. + rst = .true. + else + info%reach_iteration_limit = .false. + end if + + info%function_evaluation_count = neval + if (neval >= controls%max_function_evaluations) then + info%reach_function_evaluation_limit = .true. + rst = .true. + else + info%reach_function_evaluation_limit = .false. + end if + + info%gradient_value = maxval(abs(JtWdy)) + if (info%gradient_value < controls%gradient_tolerance .and. niter > 2) & + then + info%converge_on_gradient = .true. + rst = .true. + else + info%converge_on_gradient = .false. + end if + + info%solution_change_value = maxval(abs(h) / (abs(p) + 1.0d-12)) + if (info%solution_change_value < & + controls%change_in_solution_tolerance .and. niter > 2) & + then + info%converge_on_solution_change = .true. + rst = .true. + else + info%converge_on_solution_change = .false. + end if + + info%residual_value = X2 / dof + if (info%residual_value < controls%residual_tolerance .and. niter > 2) & + then + info%converge_on_residual_parameter = .true. + rst = .true. + else + info%converge_on_residual_parameter = .false. + end if +end function + +! ------------------------------------------------------------------------------ +end module @@ -1826,7 +1828,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_sampling.f90.html b/doc/sourcefile/fstats_sampling.f90.html index 2e851f9..a08bdfb 100644 --- a/doc/sourcefile/fstats_sampling.f90.html +++ b/doc/sourcefile/fstats_sampling.f90.html @@ -74,7 +74,7 @@

            fstats_sampling.f90
          • 78 statements + title=" 2.7% of total for source files.">78 statements
          • @@ -307,7 +307,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_smoothing.f90.html b/doc/sourcefile/fstats_smoothing.f90.html index 3ffb58b..e54f6c3 100644 --- a/doc/sourcefile/fstats_smoothing.f90.html +++ b/doc/sourcefile/fstats_smoothing.f90.html @@ -74,7 +74,7 @@

            fstats_smoothing.f90
          • 215 statements + title=" 7.3% of total for source files.">215 statements
          • @@ -458,7 +458,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_special_functions.f90.html b/doc/sourcefile/fstats_special_functions.f90.html index 4e3e03d..c83d8f4 100644 --- a/doc/sourcefile/fstats_special_functions.f90.html +++ b/doc/sourcefile/fstats_special_functions.f90.html @@ -74,7 +74,7 @@

            fstats_special_functions.f90
          • 169 statements + title=" 5.7% of total for source files.">169 statements
          • @@ -476,7 +476,7 @@

            Source Code

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/sourcefile/fstats_types.f90.html b/doc/sourcefile/fstats_types.f90.html new file mode 100644 index 0000000..1df350f --- /dev/null +++ b/doc/sourcefile/fstats_types.f90.html @@ -0,0 +1,212 @@ + + + + + + + + + + + + + fstats_types.f90 – FSTATS + + + + + + + + + + + + + + +
            + +
            + +
            +
            +

            fstats_types.f90 + Source File + +

            +
            +
            +
            + +
            +
            + +
            +
            +
            + + +
            +
            + +
            + +
            + +
            +

            Source Code

            +
            module fstats_types
            +    use iso_fortran_env
            +    implicit none
            +
            +    type array_container
            +        !! Provides a container for a real-valued array.  A practical use of
            +        !! this construct is in the construction of jagged arrays.
            +        real(real64), allocatable, dimension(:) :: x
            +            !! The array.
            +    end type
            +end module
            +
            + +
            +
            +
            + +
            +
            +
            +
            +
            +

            FSTATS was developed by Jason Christopherson
            © 2024 +

            +
            +
            +

            + Documentation generated by + FORD + on 2024-04-19 07:47

            +
            +
            +
            +
            +
            + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/src/fstats.f90 b/doc/src/fstats.f90 index 17ddec2..7eb1e80 100644 --- a/doc/src/fstats.f90 +++ b/doc/src/fstats.f90 @@ -49,7 +49,7 @@ module fstats public :: digamma public :: incomplete_gamma_upper public :: incomplete_gamma_lower - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: regression_statistics @@ -78,6 +78,10 @@ module fstats public :: box_muller_sample public :: rejection_sample public :: lowess + public :: pooled_variance + public :: bartletts_test + public :: levenes_test + public :: sample_size public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE diff --git a/doc/src/fstats_anova.f90 b/doc/src/fstats_anova.f90 index 51ed9a6..fffddb7 100644 --- a/doc/src/fstats_anova.f90 +++ b/doc/src/fstats_anova.f90 @@ -5,6 +5,7 @@ module fstats_anova use fstats_descriptive_statistics use ferror use fstats_errors + use fstats_distributions implicit none private public :: anova_factor @@ -427,18 +428,13 @@ subroutine anova_probability(v1, v2, dof1, dof2, f, p) real(real64), intent(out) :: f, p ! Local Variables - real(real64) :: d1, d2, a, b, x + type(f_distribution) :: dist ! Process f = v1 / v2 - d1 = dof1 - d2 = dof2 - - a = 0.5d0 * d2 - b = 0.5d0 * d1 - x = d2 / (d2 + d1 * f) - - p = regularized_beta(a, b, x) + dist%d1 = dof1 + dist%d2 = dof2 + p = 1.0d0 - dist%cdf(f) if (p > 1.0d0) then p = 2.0d0 - p end if diff --git a/doc/src/fstats_descriptive_statistics.f90 b/doc/src/fstats_descriptive_statistics.f90 index b6a376e..591904a 100644 --- a/doc/src/fstats_descriptive_statistics.f90 +++ b/doc/src/fstats_descriptive_statistics.f90 @@ -3,6 +3,7 @@ module fstats_descriptive_statistics use linalg, only : sort use ferror use fstats_errors + use fstats_types implicit none private public :: mean @@ -12,7 +13,13 @@ module fstats_descriptive_statistics public :: quantile public :: trimmed_mean public :: covariance + public :: pooled_variance + interface pooled_variance + !! Computes the pooled estimate of variance. + module procedure :: pooled_variance_1 + module procedure :: pooled_variance_2 + end interface contains ! ------------------------------------------------------------------------------ pure function mean(x) result(rst) @@ -237,5 +244,53 @@ pure function covariance(x, y) result(rst) end if end function +! ------------------------------------------------------------------------------ +pure function pooled_variance_1(si, ni) result(rst) + !! Computes the pooled estimate of variance. + real(real64), intent(in), dimension(:) :: si + !! An N-element array containing the estimates for each of the N + !! variances. + integer(int32), intent(in), dimension(size(si)) :: ni + !! An N-element array containing the number of data points in each + !! of the data sets used to compute the variances in si. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n + + ! Process + k = size(si) + rst = 0.0d0 + n = 0 + do i = 1, k + n = n + ni(i) + rst = rst + (ni(i) - 1.0d0) * si(i) + end do + rst = rst / real(n - k, real64) +end function + +pure function pooled_variance_2(x) result(rst) + !! Computes the pooled estimate of variance. + type(array_container), intent(in), dimension(:) :: x + !! An array of arrays of data. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n, ni + + ! Process + k = size(x) + n = 0 + rst = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + rst = rst + variance(x(i)%x) * (ni - 1.0) + end do + rst = rst / real(n - k, real64) +end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/doc/src/fstats_distributions.f90 b/doc/src/fstats_distributions.f90 index bc30726..559afa0 100644 --- a/doc/src/fstats_distributions.f90 +++ b/doc/src/fstats_distributions.f90 @@ -31,6 +31,8 @@ module fstats_distributions !! Computes the mode of the distribution. procedure(distribution_property), deferred, pass :: variance !! Computes the variance of the distribution. + procedure, public :: standardized_variable => dist_std_var + !! Computes the standardized variable for the distribution. end type interface @@ -135,8 +137,40 @@ pure function distribution_property(this) result(rst) procedure, public :: variance => bd_variance end type -! ------------------------------------------------------------------------------ contains +! ------------------------------------------------------------------------------ +pure elemental function dist_std_var(this, x) result(rst) + !! Computes the standardized variable for the distribution. + class(distribution), intent(in) :: this + !! The distribution object. + real(real64), intent(in) :: x + !! The value of interest. + real(real64) :: rst + !! The result. + + ! Local Variables + integer(int32), parameter :: maxiter = 100 + real(real64), parameter :: tol = 1.0d-6 + integer(int32) :: i + real(real64) :: f, df, h, twoh, dy + + ! Process + ! + ! We use a simplified Newton's method to solve for the independent variable + ! of the CDF function + h = 1.0d-6 + twoh = 2.0d0 * h + rst = 0.5d0 ! just an initial guess + do i = 1, maxiter + ! Compute the CDF and its derivative at y + f = this%cdf(rst) - x + df = (this%cdf(rst + h) - this%cdf(rst - h)) / twoh + dy = f / df + rst = rst - dy + if (abs(dy) < tol) exit + end do +end function + ! ****************************************************************************** ! STUDENT'S T-DISTRIBUTION ! ------------------------------------------------------------------------------ diff --git a/doc/src/fstats_hypothesis.f90 b/doc/src/fstats_hypothesis.f90 index d6eb068..98cabf7 100644 --- a/doc/src/fstats_hypothesis.f90 +++ b/doc/src/fstats_hypothesis.f90 @@ -5,12 +5,16 @@ module fstats_hypothesis use fstats_special_functions use fstats_distributions use fstats_descriptive_statistics + use fstats_types private public :: confidence_interval public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test + public :: bartletts_test + public :: levenes_test + public :: sample_size interface confidence_interval !! Computes the confidence interval for the specified distribution. @@ -39,29 +43,11 @@ pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) !! The result. ! Local Variables - integer(int32), parameter :: maxiter = 100 - real(real64), parameter :: tol = 1.0d-6 - integer(int32) :: i - real(real64) :: x, f, df, h, twoh, dy + real(real64) :: x ! Process - ! - ! We use a simplified Newton's method to solve for the independent variable - ! of the CDF function where it equals 1 - alpha / 2. - h = 1.0d-6 - twoh = 2.0d0 * h x = 1.0d0 - alpha / 2.0d0 - rst = 0.5d0 - do i = 1, maxiter - ! Compute the CDF and its derivative at y - f = dist%cdf(rst) - x - df = (dist%cdf(rst + h) - dist%cdf(rst - h)) / twoh - dy = f / df - rst = rst - dy - if (abs(dy) < tol) exit - end do - - ! Determine the actual interval + rst = dist%standardized_variable(x) rst = rst * s / sqrt(real(n, real64)) end function @@ -279,13 +265,13 @@ subroutine f_test(x1, x2, stat, p, dof1, dof2) !! A measure of the degrees of freedom. ! Parameters - real(real64), parameter :: half = 0.5d0 real(real64), parameter :: one = 1.0d0 real(real64), parameter :: two = 2.0d0 ! Local Variables integer(int32) :: n1, n2 - real(real64) :: v1, v2, m1, m2, a, b, x + real(real64) :: v1, v2, m1, m2 + type(f_distribution) :: dist ! Compute the F-statistic n1 = size(x1) @@ -304,13 +290,211 @@ subroutine f_test(x1, x2, stat, p, dof1, dof2) dof2 = n1 - one end if - ! Compute the probability - a = half * dof2 - b = half * dof1 - x = dof2 / (dof2 + dof1 * stat) - p = two * regularized_beta(a, b, x) + dist%d1 = dof1 + dist%d2 = dof2 + p = two * (one - dist%cdf(stat))! 2x because this is a two-tailed estimate if (p > one) p = two - p end subroutine +! ------------------------------------------------------------------------------ +subroutine bartletts_test(x, stat, p) + !! Computes Bartlett's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! + !! $$ \chi^{2} = \frac{(N - k) \ln(S_{p}^{2}) \sum_{i = 1}^{k} + !! \left(n_{i} - 1 \right) \ln(S_{i}^{2})}{1 + + !! \frac{1}{3 \left( k - 1 \right)} \left( \sum_{i = 1}^{k} + !! \left( \frac{1}{n_{i} - 1} \right) - \frac{1}{N - k} \right)} $$ + !! + !! Where \( N = \sum_{i = 1}^{k} n_{i} \) and \( S_{p}^{2} \) is the pooled + !! variance. + !! + !! The probability is calculated as the right-tail probability of the + !! chi-squared distribution. + !! + !! Bartlett's test is most relevant for distributions showing strong + !! normality. For distributions lacking strong normality, consider + !! Levene's test instead. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Bartlett%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + + ! Local Variables + integer(int32) :: i, n, k, ni + real(real64) :: si, sp, numer, denom + type(chi_squared_distribution) :: dist + + ! Initialization + k = size(x) + n = 0 + do i = 1, k + n = n + size(x(i)%x) + end do + + ! Compute the statistic + n = 0 + sp = 0.0d0 + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + si = variance(x(i)%x) + sp = sp + (ni - 1.0d0) * si + numer = numer + (ni - 1.0d0) * log(variance(x(i)%x)) + denom = denom + 1.0d0 / (ni - 1.0d0) + end do + sp = sp / real(n - k, real64) + stat = ((n - k) * log(sp) - numer) / & + (1.0d0 + (1.0d0 / (3.0d0 * k - 3.0d0)) * & + (denom - 1.0d0 / real(n - k, real64))) + + ! Compute the p-value + dist%dof = k - 1 + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine levenes_test(x, stat, p, err) + !! Computes Levene's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! $$ W = \frac{N - k}{k - 1} \frac{ \sum_{i = 1}^{k} N_{i} \left( Z_{i.} - + !! Z{..} \right)^{2}}{ \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} \left( Z_{ij} - + !! Z_{i.} \right)^{2} } $$ + !! + !! Where: + !! $$ Z_{ij} = |X_{ij} - \overline{X_{i.}}| $$ + !! $$ Z_{i.} = \frac{1}{n_{i}} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! $$ Z_{..} = \frac{1}{N} \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! + !! As the test statistic is approximately F-distributed, the F-distribution + !! is used to calculate the probability term. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Levene%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + class(errors), intent(inout), optional, target :: err + + ! Local Variables + integer(int32) :: i, j, k, n, ni, flag + real(real64) :: numer, denom, inner, yi, z, zij + real(real64), allocatable, dimension(:) :: y, zt, zi + type(f_distribution) :: dist + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + k = size(x) + + ! Local Memory Allocations + allocate(y(k), zi(k), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "levenes_test", flag) + return + end if + + ! Compute the total mean + z = 0.0d0 + n = 0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + y(i) = mean(x(i)%x) + zt = abs(x(i)%x - y(i)) + zi(i) = mean(zt) + z = z + zi(i) * ni + end do + z = z / n + + ! Process + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + yi = y(i) + numer = numer + ni * (zi(i) - z)**2 + + inner = 0.0d0 + do j = 1, ni + zij = abs(x(i)%x(j) - yi) + inner = inner + (zij - zi(i))**2 + end do + denom = denom + inner + end do + stat = real((N - k) / (k - 1), real64) * (numer / denom) + dist%d1 = k - 1.0d0 + dist%d2 = real(n - k, real64) + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +pure function sample_size(dist, var, delta, bet, alpha) result(rst) + !! Estimates the sample size required to achieve an experiment with the + !! desired power and significance levels to ascertain the desired + !! difference in parameter. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Power_of_a_test) + class(distribution), intent(in) :: dist + !! The distribution to utilize as a measure. + real(real64), intent(in) :: var + !! An estimate of the population variance. + real(real64), intent(in) :: delta + !! The parameter difference that is desired. + real(real64), intent(in), optional :: bet + !! The desired power level. The default for this value is 0.2, for a + !! power of 80%. + real(real64), intent(in), optional :: alpha + !! The desired significance level. The default for this value is 0.05 + !! for a confidence level of 95%. + real(real64) :: rst + !! The minimum sample size requried to achieve the desired experimental + !! outcome. + + ! Local Variables + real(real64) :: a, b, za, zb + + ! Initialization + if (present(bet)) then + b = bet + else + b = 0.8d0 + end if + if (present(alpha)) then + a = alpha + else + a = 0.05d0 + end if + + za = dist%standardized_variable(1.0d0 - a / 2.0d0) + zb = dist%standardized_variable(b) + rst = 2.0d0 * (za + zb)**2 * var / (delta**2) +end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/doc/src/fstats_regression.f90 b/doc/src/fstats_regression.f90 index 9e05a76..5b79337 100644 --- a/doc/src/fstats_regression.f90 +++ b/doc/src/fstats_regression.f90 @@ -19,7 +19,7 @@ module fstats_regression public :: r_squared public :: adjusted_r_squared public :: correlation - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: calculate_regression_statistics @@ -293,16 +293,18 @@ pure function correlation(x, y) result(rst) end function ! ------------------------------------------------------------------------------ -subroutine coefficient_matrix(order, intercept, x, c, err) - !! Computes the coefficient matrix \( X \) to the linear +subroutine design_matrix(order, intercept, x, c, err) + !! Computes the design matrix \( X \) for the linear !! least-squares regression problem of \( X \beta = y \), where - !! \( X \) is the coefficient matrix computed here, \( \beta \) is + !! \( X \) is the matrix computed here, \( \beta \) is !! the vector of coefficients to be determined, and \( y \) is the !! vector of measured dependent variables. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) + !! - [Wikipedia](https://en.wikipedia.org/wiki/Vandermonde_matrix) + !! - [Wikipedia](https://en.wikipedia.org/wiki/Design_matrix) integer(int32), intent(in) :: order !! The order of the equation to fit. This value must be !! at least one (linear equation), but can be higher as desired. @@ -343,12 +345,12 @@ subroutine coefficient_matrix(order, intercept, x, c, err) ! Input Check if (order < 1) then - call errmgr%report_error("coefficient_matrix", & + call errmgr%report_error("design_matrix", & "The model order must be at least one.", FS_INVALID_INPUT_ERROR) return end if if (size(c, 1) /= npts .or. size(c, 2) /= ncols) then - call report_matrix_size_error(errmgr, "coefficient_matrix", & + call report_matrix_size_error(errmgr, "design_matrix", & "c", npts, ncols, size(c, 1), size(c, 2)) return end if @@ -372,7 +374,7 @@ subroutine coefficient_matrix(order, intercept, x, c, err) subroutine covariance_matrix(x, c, err) !! Computes the covariance matrix \( C \) where !! \( C = \left( X^{T} X \right)^{-1} \) and \( X \) is computed - !! by coefficient_matrix. + !! by design_matrix. !! !! See Also !! @@ -380,7 +382,7 @@ subroutine covariance_matrix(x, c, err) !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) real(real64), intent(in) :: x(:,:) !! An M-by-N matrix containing the formatted independent data - !! matrix \( X \) as computed by coefficient_matrix. + !! matrix \( X \) as computed by design_matrix. real(real64), intent(out) :: c(:,:) !! The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err @@ -551,7 +553,7 @@ subroutine linear_least_squares(order, intercept, x, y, coeffs, & end if ! Compute the coefficient matrix - call coefficient_matrix(order, intercept, x, a, errmgr) + call design_matrix(order, intercept, x, a, errmgr) if (errmgr%has_error_occurred()) return ! Compute the covariance matrix diff --git a/doc/src/fstats_types.f90 b/doc/src/fstats_types.f90 new file mode 100644 index 0000000..62cff8f --- /dev/null +++ b/doc/src/fstats_types.f90 @@ -0,0 +1,11 @@ +module fstats_types + use iso_fortran_env + implicit none + + type array_container + !! Provides a container for a real-valued array. A practical use of + !! this construct is in the construction of jagged arrays. + real(real64), allocatable, dimension(:) :: x + !! The array. + end type +end module \ No newline at end of file diff --git a/doc/tipuesearch/tipuesearch_content.js b/doc/tipuesearch/tipuesearch_content.js index 32829f5..ce52f8f 100644 --- a/doc/tipuesearch/tipuesearch_content.js +++ b/doc/tipuesearch/tipuesearch_content.js @@ -1 +1 @@ -var tipuesearch = {"pages":[{"title":" FSTATS ","text":"FSTATS Developer Info Jason Christopherson","tags":"home","loc":"index.html"},{"title":"bootstrap_regression_statistics – FSTATS ","text":"type, public :: bootstrap_regression_statistics A container for regression-related statistical information as \ncomputed in a bootstrap, or equivalent, calculation. Components Type Visibility Attributes Name Initial real(kind=real64), public :: lower_confidence_interval The lower limit of the confidence interval for the parameter. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. real(kind=real64), public :: upper_confidence_interval The upper limit of the confidence interval for the parameter.","tags":"","loc":"type\\bootstrap_regression_statistics.html"},{"title":"bootstrap_statistics – FSTATS ","text":"type, public :: bootstrap_statistics A collection of statistics resulting from the bootstrap process. Components Type Visibility Attributes Name Initial real(kind=real64), public :: bias The bias in the statistic. real(kind=real64), public :: lower_confidence_interval The lower confidence limit on the statistic. real(kind=real64), public, allocatable, dimension(:) :: population An array of the population values generated by the bootstrap\nprocess. real(kind=real64), public :: standard_error The standard error of the statistic. real(kind=real64), public :: statistic_value The value of the statistic of interest. real(kind=real64), public :: upper_confidence_interval The upper confidence limit on the statistic.","tags":"","loc":"type\\bootstrap_statistics.html"},{"title":"binomial_distribution – FSTATS ","text":"type, public, extends( distribution ) :: binomial_distribution Defines a binomial distribution. The binomial distribution describes\nthe probability p of getting k successes in n independent trials. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: n The number of independent trials. real(kind=real64), public :: p The success probability for each trial. This parameter must\nexist on the set [0, 1]. Type-Bound Procedures procedure, public :: cdf => bd_cdf private pure elemental function bd_cdf(this, x) result(rst) Computes the cumulative distribution funtion. The CDF for a binomial distribution is given as , which is simply\nthe regularized incomplete beta function. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. This parameter\nis the number k successes in the n independent trials. As\nsuch, this parameter must exist on the set [0, n]. Return Value real(kind=real64) The value of the function. procedure, public :: mean => bd_mean private pure function bd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => bd_median private pure function bd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => bd_mode private pure function bd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => bd_pdf private pure elemental function bd_pdf(this, x) result(rst) Computes the probability mass function. The PMF for a binomial distribution is given as . Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. This parameter\nis the number k successes in the n independent trials. As\nsuch, this parameter must exist on the set [0, n]. Return Value real(kind=real64) The value of the function. procedure, public :: variance => bd_variance private pure function bd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\binomial_distribution.html"},{"title":"chi_squared_distribution – FSTATS ","text":"type, public, extends( distribution ) :: chi_squared_distribution Defines a Chi-squared distribution. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => cs_cdf private pure elemental function cs_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a Chi-squared distribution is given as . Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => cs_mean private pure function cs_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => cs_median private pure function cs_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => cs_mode private pure function cs_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => cs_pdf private pure elemental function cs_pdf(this, x) result(rst) Computes the probability density function. The PDF for a Chi-squared distribution is given as . Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: variance => cs_variance private pure function cs_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\chi_squared_distribution.html"},{"title":"distribution – FSTATS ","text":"type, public :: distribution Defines a probability distribution. Type-Bound Procedures procedure( distribution_function ), public, deferred, pass :: cdf Computes the cumulative distribution function. pure elemental function distribution_function(this, x) result(rst) Prototype Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure( distribution_property ), public, deferred, pass :: mean Computes the mean of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_property ), public, deferred, pass :: median Computes the median of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_property ), public, deferred, pass :: mode Computes the mode of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_function ), public, deferred, pass :: pdf Computes the probability density function. pure elemental function distribution_function(this, x) result(rst) Prototype Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure( distribution_property ), public, deferred, pass :: variance Computes the variance of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value.","tags":"","loc":"type\\distribution.html"},{"title":"f_distribution – FSTATS ","text":"type, public, extends( distribution ) :: f_distribution Defines an F-distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: d1 The measure of degrees of freedom for the first data set. real(kind=real64), public :: d2 The measure of degrees of freedom for the second data set. Type-Bound Procedures procedure, public :: cdf => fd_cdf private pure elemental function fd_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a F distribution is given as . Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => fd_mean private pure function fd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => fd_median private pure function fd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => fd_mode private pure function fd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => fd_pdf private pure elemental function fd_pdf(this, x) result(rst) Computes the probability density function. The PDF for a F distribution is given as . Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: variance => fd_variance private pure function fd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\f_distribution.html"},{"title":"normal_distribution – FSTATS ","text":"type, public, extends( distribution ) :: normal_distribution Defines a normal distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: mean_value The mean value of the distribution. real(kind=real64), public :: standard_deviation The standard deviation of the distribution. Type-Bound Procedures procedure, public :: cdf => nd_cdf private pure elemental function nd_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a normal distribution is given as . Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => nd_mean private pure function nd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The mean procedure, public :: median => nd_median private pure function nd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => nd_mode private pure function nd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => nd_pdf private pure elemental function nd_pdf(this, x) result(rst) Computes the probability density function. The PDF for a normal distribution is given as . Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardize => nd_standardize private subroutine nd_standardize(this) Standardizes the normal distribution to a mean of 0 and a \nstandard deviation of 1. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(inout) :: this The normal_distribution object. procedure, public :: variance => nd_variance private pure function nd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\normal_distribution.html"},{"title":"t_distribution – FSTATS ","text":"type, public, extends( distribution ) :: t_distribution Defines Student's T-Distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => td_cdf private pure elemental function td_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for Student's T-Distribution is given as where . Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => td_mean private pure function td_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => td_median private pure function td_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) procedure, public :: mode => td_mode private pure function td_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => td_pdf private pure elemental function td_pdf(this, x) result(rst) Computes the probability density function. The PDF for Student's T-Distribution is given as . Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: variance => td_variance private pure function td_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\t_distribution.html"},{"title":"convergence_info – FSTATS ","text":"type, public :: convergence_info Provides information regarding convergence status. Components Type Visibility Attributes Name Initial logical, public :: converge_on_gradient True if convergence on the gradient was achieved; else, false. logical, public :: converge_on_residual_parameter True if convergence on the residual error parameter was achieved; \nelse, false. logical, public :: converge_on_solution_change True if convergence on the change in solution was achieved; else,\nfalse. integer(kind=int32), public :: function_evaluation_count The function evaluation count. real(kind=real64), public :: gradient_value The value of the gradient test parameter. integer(kind=int32), public :: iteration_count The iteration count. logical, public :: reach_function_evaluation_limit True if the solution did not converge in the allowed number of\nfunction evaluations. logical, public :: reach_iteration_limit True if the solution did not converge in the allowed number of \niterations. real(kind=real64), public :: residual_value The value of the residual error parameter. real(kind=real64), public :: solution_change_value The value of the change in solution parameter. logical, public :: user_requested_stop True if the user requested the stop; else, false.","tags":"","loc":"type\\convergence_info.html"},{"title":"iteration_controls – FSTATS ","text":"type, public :: iteration_controls Provides a collection of iteration control parameters. Components Type Visibility Attributes Name Initial real(kind=real64), public :: change_in_solution_tolerance Defines a tolerance on the change in parameter values. real(kind=real64), public :: gradient_tolerance Defines a tolerance on the gradient of the fitted function. real(kind=real64), public :: iteration_improvement_tolerance Defines a tolerance to ensure adequate improvement on each \niteration. integer(kind=int32), public :: max_function_evaluations Defines the maximum number of function evaluations allowed. integer(kind=int32), public :: max_iteration_between_updates Defines how many iterations can pass before a re-evaluation of \nthe Jacobian matrix is forced. integer(kind=int32), public :: max_iteration_count Defines the maximum number of iterations allowed. real(kind=real64), public :: residual_tolerance Defines a tolerance on the metric associated with the residual \nerror. Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_tolerances private subroutine lm_set_default_tolerances(x) Arguments Type Intent Optional Attributes Name class( iteration_controls ), intent(inout) :: x","tags":"","loc":"type\\iteration_controls.html"},{"title":"lm_solver_options – FSTATS ","text":"type, public :: lm_solver_options Options to control the Levenberg-Marquardt solver. Components Type Visibility Attributes Name Initial real(kind=real64), public :: damping_decrease_factor The factor to use when decreasing the damping parameter. real(kind=real64), public :: damping_increase_factor The factor to use when increasing the damping parameter. real(kind=real64), public :: finite_difference_step_size The step size used for the finite difference calculations of the\nJacobian matrix. integer(kind=int32), public :: method The solver method to utilize.\n- FS_LEVENBERG_MARQUARDT_UPDATE:\n- FS_QUADRATIC_UPDATE:\n- FS_NIELSEN_UDPATE: Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_settings private subroutine lm_set_default_settings(x) Arguments Type Intent Optional Attributes Name class( lm_solver_options ), intent(inout) :: x","tags":"","loc":"type\\lm_solver_options.html"},{"title":"regression_statistics – FSTATS ","text":"type, public :: regression_statistics A container for regression-related statistical information. Components Type Visibility Attributes Name Initial real(kind=real64), public :: confidence_interval The confidence interval for the parameter at the level \ndetermined by the regression process. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient.","tags":"","loc":"type\\regression_statistics.html"},{"title":"anova_factor – FSTATS ","text":"type, public :: anova_factor Defines an ANOVA factor result. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedome. real(kind=real64), public :: f_statistic The F-statistic. real(kind=real64), public :: probability The variance probability term. real(kind=real64), public :: sum_of_squares The sum of the squares. real(kind=real64), public :: variance The estimate of variance.","tags":"","loc":"type\\anova_factor.html"},{"title":"single_factor_anova_table – FSTATS ","text":"type, public :: single_factor_anova_table Defines a single-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: main_factor The main, or main factor, results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within-treatement (error) results.","tags":"","loc":"type\\single_factor_anova_table.html"},{"title":"two_factor_anova_table – FSTATS ","text":"type, public :: two_factor_anova_table Defines a two-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: interaction The interaction effects. type( anova_factor ), public :: main_factor_1 The first main-factor results. type( anova_factor ), public :: main_factor_2 The second main-factor results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within (error) factor results.","tags":"","loc":"type\\two_factor_anova_table.html"},{"title":"bootstrap – FSTATS","text":"public function bootstrap(stat, x, method, nsamples, alpha) result(rst) Performs a bootstrap calculation on the supplied data set for the given\nstatistic. The default implementation utlizes a random resampling with \nreplacement. Other resampling methods may be defined by specifying an \nappropriate routine by means of the method input. Arguments Type Intent Optional Attributes Name procedure( bootstrap_statistic_routine ), intent(in), pointer :: stat The routine used to compute the desired statistic. real(kind=real64), intent(in), dimension(:) :: x The N-element data set. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. integer(kind=int32), intent(in), optional :: nsamples An optional input, that if supplied, specifies the number of \nresampling runs to perform. The default is 10 000. real(kind=real64), intent(in), optional :: alpha An optional input, that if supplied, defines the significance level\nto use for the analysis. The default is 0.05. Return Value type( bootstrap_statistics ) The resulting bootstrap_statistics type containing the confidence\nintervals, bias, standard error, etc. for the analyzed statistic.","tags":"","loc":"proc\\bootstrap.html"},{"title":"bootstrap_linear_least_squares – FSTATS","text":"public subroutine bootstrap_linear_least_squares(order, intercept, x, y, coeffs, ymod, resid, nsamples, stats, bias, alpha, method, bscoeffs, err) Computes a linear least-squares regression to fit a set of data.\nBootstrapping is utilized to gain insight into the quality of \nthe fit. Resampling for the bootstrap process is a random resampling \nwith replacement process with the range of values limited by the \nstandard deviation of the original data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out), dimension(:) :: coeffs An ORDER+1 element array where the coefficients will\nbe written. real(kind=real64), intent(out), dimension(:) :: ymod An N-element array where the modeled data will be written. real(kind=real64), intent(out), dimension(:) :: resid An N-element array where the residual error data will be \nwritten (modeled - actual). integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. type( bootstrap_regression_statistics ), intent(out), optional, dimension(:) :: stats An M-element array of bootstrap_regression_statistics items \nwhere M = ORDER + 1 when intercept is set to true; however, \nif intercept is set to false, M = ORDER. real(kind=real64), intent(out), optional, dimension(:) :: bias An ORDER+1 element array where an estimate of the bias of\neach coefficient is returned based upon the results of the\nbootstrapping analysis. The bias is computed as the difference \nbetween the mean of the boostrap population results for the given \nparameter and the original estimate of the given parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\bootstrap_linear_least_squares.html"},{"title":"bootstrap_nonlinear_least_squares – FSTATS","text":"public subroutine bootstrap_nonlinear_least_squares(fun, x, y, params, ymod, resid, nsamples, weights, maxp, minp, stats, alpha, controls, settings, info, bias, method, bscoeffs, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain \ninsight into the quality of the fit. Resampling for the bootstrap \nprocess is a random resampling with replacement process with the \nrange of values limited by the standard deviation of the original \ndata set. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( bootstrap_regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. real(kind=real64), intent(out), optional, dimension(:) :: bias An optional N-element array that, if supplied, will be used to \nprovide an estimate of the bias of each model parameter based upon\nthe results of the bootstrapping analysis. The bias is computed as \nthe difference between the mean of the boostrap population results \nfor the given parameter and the original estimate of the given \nparameter. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"proc\\bootstrap_nonlinear_least_squares.html"},{"title":"random_resample – FSTATS","text":"public subroutine random_resample(x, xn) Random resampling, with replacement, based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"proc\\random_resample.html"},{"title":"scaled_random_resample – FSTATS","text":"public subroutine scaled_random_resample(x, xn) A random resampling, scaled by the standard deviation of the original\ndata, but based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"proc\\scaled_random_resample.html"},{"title":"bootstrap_resampling_routine – FSTATS","text":"interface public subroutine bootstrap_resampling_routine(x, xn) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be \nwritten. Description Defines the signature of a subroutine used to compute a \nresampling of data for bootstrapping purposes.","tags":"","loc":"interface\\bootstrap_resampling_routine.html"},{"title":"bootstrap_statistic_routine – FSTATS","text":"interface public function bootstrap_statistic_routine(x) result(rst) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The array of data to analyze. Return Value real(kind=real64) The resulting statistic. Description Defines the signature of a function for computing the desired\nbootstrap statistic.","tags":"","loc":"interface\\bootstrap_statistic_routine.html"},{"title":"covariance – FSTATS","text":"public pure function covariance(x, y) result(rst) Computes the sample covariance of two data sets. The covariance computed is the sample covariance such that . Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The covariance.","tags":"","loc":"proc\\covariance.html"},{"title":"mean – FSTATS","text":"public pure function mean(x) result(rst) Computes the mean of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\mean.html"},{"title":"median – FSTATS","text":"public function median(x) result(rst) Computes the median of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout) :: x (:) The array of values to analyze. On output, this array is sorted into\nascending order. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\median.html"},{"title":"quantile – FSTATS","text":"public pure function quantile(x, q) result(rst) Computes the specified quantile of a data set using the SAS \nMethod 4. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the data. real(kind=real64), intent(in) :: q The quantile to compute (e.g. 0.25 computes the 25% quantile). Return Value real(kind=real64) The result.","tags":"","loc":"proc\\quantile.html"},{"title":"standard_deviation – FSTATS","text":"public pure function standard_deviation(x) result(rst) Computes the sample standard deviation of the values in an array. The value computed is the sample standard deviation. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\standard_deviation.html"},{"title":"trimmed_mean – FSTATS","text":"public function trimmed_mean(x, p) result(rst) Computes the trimmed mean of a data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout), dimension(:) :: x An N-element array containing the data. On output, the\narray is sorted into ascending order. real(kind=real64), intent(in), optional :: p An optional parameter specifying the percentage of values\nfrom either end of the distribution to remove. The default\nis 0.05 such that the bottom 5% and top 5% are removed. Return Value real(kind=real64) The trimmed mean.","tags":"","loc":"proc\\trimmed_mean.html"},{"title":"variance – FSTATS","text":"public pure function variance(x) result(rst) Computes the sample variance of the values in an array. The variance computed is the sample variance such that . Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64)","tags":"","loc":"proc\\variance.html"},{"title":"distribution_function – FSTATS","text":"interface public pure elemental function distribution_function(this, x) result(rst) Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. Description Defines the interface for a probability distribution function.","tags":"","loc":"interface\\distribution_function.html"},{"title":"distribution_property – FSTATS","text":"interface public pure function distribution_property(this) result(rst) Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. Description Computes the value of a distribution property.","tags":"","loc":"interface\\distribution_property.html"},{"title":"rejection_sample – FSTATS","text":"public function rejection_sample(tdist, n, xmin, xmax) result(rst) Uses rejection sampling to randomly sample a target distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: tdist The distribution to sample integer(kind=int32), intent(in) :: n The number of samples to make. real(kind=real64), intent(in) :: xmin The minimum range to explore. real(kind=real64), intent(in) :: xmax The maximum range to explore. Return Value real(kind=real64), allocatable, dimension(:) An N-element array containing the N samples from the \ndistribution.","tags":"","loc":"proc\\rejection_sample.html"},{"title":"box_muller_sample – FSTATS","text":"public interface box_muller_sample Generates random, normally distributed values via the Box-Muller \ntransform. Module Procedures private function box_muller_sample_scalar(mu, sigma) result(rst) Generates a pair of independent, standard, normally distributed\nrandom values using the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. Return Value real(kind=real64), (2) The pair of random values. private function box_muller_array(mu, sigma, n) result(rst) Generates an array of normally distributed random values sampled\nby the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. integer(kind=int32), intent(in) :: n The number of Box-Muller pairs to generate. Return Value real(kind=real64), allocatable, dimension(:) A 2N-element array containing the N Box-Muller pairs.","tags":"","loc":"interface\\box_muller_sample.html"},{"title":"beta – FSTATS","text":"public pure elemental function beta(a, b) result(rst) Computes the beta function. The beta function is related to the gamma function\nby the following relationship. . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. Return Value real(kind=real64) The value of the beta function at and .","tags":"","loc":"proc\\beta.html"},{"title":"digamma – FSTATS","text":"public pure elemental function digamma(x) result(rst) Computes the digamma function. The digamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\digamma.html"},{"title":"incomplete_beta – FSTATS","text":"public pure elemental function incomplete_beta(a, b, x) result(rst) Computes the incomplete beta function. The incomplete beta function is defind as: . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the incomplete beta function.","tags":"","loc":"proc\\incomplete_beta.html"},{"title":"incomplete_gamma_lower – FSTATS","text":"public pure elemental function incomplete_gamma_lower(a, x) result(rst) Computes the lower incomplete gamma function. The lower incomplete gamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\incomplete_gamma_lower.html"},{"title":"incomplete_gamma_upper – FSTATS","text":"public pure elemental function incomplete_gamma_upper(a, x) result(rst) Computes the upper incomplete gamma function. The upper incomplete gamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\incomplete_gamma_upper.html"},{"title":"regularized_beta – FSTATS","text":"public pure elemental function regularized_beta(a, b, x) result(rst) Computes the regularized beta function. The regularized beta function is defined as the ratio between\nthe incomplete beta function and the beta function. . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the regularized beta function.","tags":"","loc":"proc\\regularized_beta.html"},{"title":"adjusted_r_squared – FSTATS","text":"public function adjusted_r_squared(p, x, xm, err) result(rst) Computes the adjusted R-squared value for a data set. The adjusted R-squared provides a mechanism for tempering the effects\nof extra explanatory variables on the traditional R-squared \ncalculation. It is computed by noting the sample size and \nthe number of variables . . See Also: Wikipedia Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: p The number of variables. real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\adjusted_r_squared.html"},{"title":"calculate_regression_statistics – FSTATS","text":"public function calculate_regression_statistics(resid, params, c, alpha, err) result(rst) Computes statistics for the quality of fit for a regression \nmodel. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: resid (:) An M-element array containing the model residual errors. real(kind=real64), intent(in) :: params (:) An N-element array containing the model parameters. real(kind=real64), intent(in) :: c (:,:) The N-by-N covariance matrix. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value type( regression_statistics ), allocatable, (:) A regression_statistics object containing the analysis results.","tags":"","loc":"proc\\calculate_regression_statistics.html"},{"title":"correlation – FSTATS","text":"public pure function correlation(x, y) result(rst) Computes the sample correlation coefficient (an estimate to the \npopulation Pearson correlation) as follows. . Where, & are the sample standard deviations of\nx and y respectively. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The correlation coefficient.","tags":"","loc":"proc\\correlation.html"},{"title":"r_squared – FSTATS","text":"public function r_squared(x, xm, err) result(rst) Computes the R-squared value for a data set. The R-squared value is computed by determining the sum of the squares\nof the residuals: The total sum of the squares: . \nThe R-squared value is then: . See Also: Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\r_squared.html"},{"title":"coefficient_matrix – FSTATS","text":"public subroutine coefficient_matrix(order, intercept, x, c, err) Computes the coefficient matrix to the linear \nleast-squares regression problem of , where is the coefficient matrix computed here, is \nthe vector of coefficients to be determined, and is the \nvector of measured dependent variables. See Also Wikipedia Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be\nat least one (linear equation), but can be higher as desired. logical, intent(in) :: intercept Set to true if the intercept is being computed\nas part of the regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(out) :: c (:,:) An N-by-K matrix where the results will be written. K\nmust equal order + 1 in the event intercept is true; \nhowever, if intercept is false, K must equal order. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.","tags":"","loc":"proc\\coefficient_matrix.html"},{"title":"covariance_matrix – FSTATS","text":"public subroutine covariance_matrix(x, c, err) Computes the covariance matrix where and is computed\nby coefficient_matrix. See Also Wikipedia Wikipedia - Regression Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the formatted independent data\n matrix as computed by coefficient_matrix. real(kind=real64), intent(out) :: c (:,:) The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not \n sized correctly.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\covariance_matrix.html"},{"title":"jacobian – FSTATS","text":"public subroutine jacobian(fun, xdata, params, jac, stop, f0, f1, step, err) Computes the Jacobian matrix for a nonlinear regression problem. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: xdata (:) The M-element array containing x-coordinate data. real(kind=real64), intent(in) :: params (:) The N-element array containing the model parameters. real(kind=real64), intent(out) :: jac (:,:) The M-by-N matrix where the Jacobian will be written. logical, intent(out) :: stop A value that the user can set in fun forcing the\nevaluation process to stop prior to completion. real(kind=real64), intent(in), optional, target :: f0 (:) An optional M-element array containing the model values\n using the current parameters as defined in m. This input \ncan be used to prevent the routine from performing a \nfunction evaluation at the model parameter state defined in \nparams. real(kind=real64), intent(out), optional, target :: f1 (:) An optional M-element workspace array used for function\nevaluations. real(kind=real64), intent(in), optional :: step The differentiation step size. The default is the square \nroot of machine precision. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\jacobian.html"},{"title":"linear_least_squares – FSTATS","text":"public subroutine linear_least_squares(order, intercept, x, y, coeffs, ymod, resid, stats, alpha, err) Computes a linear least-squares regression to fit a set of data. See Also Wikipedia SPC Excel Understanding Regression Statistics Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in) :: y (:) An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out) :: coeffs (:) An ORDER+1 element array where the coefficients will be written. real(kind=real64), intent(out) :: ymod (:) An N-element array where the modeled data will be written. real(kind=real64), intent(out) :: resid (:) An N-element array where the residual error data will be \nwritten (modeled - actual). type( regression_statistics ), intent(out), optional :: stats (:) An M-element array of regression_statistics items where \nM = ORDER + 1 when intercept is set to true; however, if \nintercept is set to false, M = ORDER. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\linear_least_squares.html"},{"title":"nonlinear_least_squares – FSTATS","text":"public subroutine nonlinear_least_squares(fun, x, y, params, ymod, resid, weights, maxp, minp, stats, alpha, controls, settings, info, status, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. procedure( iteration_update ), intent(in), optional, pointer :: status An optional pointer to a routine that can be used to extract\niteration information. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"proc\\nonlinear_least_squares.html"},{"title":"iteration_update – FSTATS","text":"interface public subroutine iteration_update(iter, funvals, resid, params, step) Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: iter real(kind=real64), intent(in) :: funvals (:) real(kind=real64), intent(in) :: resid (:) real(kind=real64), intent(in) :: params (:) real(kind=real64), intent(in) :: step (:)","tags":"","loc":"interface\\iteration_update.html"},{"title":"regression_function – FSTATS","text":"interface public subroutine regression_function(xdata, params, resid, stop) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: xdata real(kind=real64), intent(in), dimension(:) :: params real(kind=real64), intent(out), dimension(:) :: resid logical, intent(out) :: stop","tags":"","loc":"interface\\regression_function.html"},{"title":"allan_variance – FSTATS","text":"public function allan_variance(x, dt, err) result(rst) Computes the Allan variance of a data set. Remarks This implementation computes the fully overlapped Allan variance \nusing the method presented by Yadav et. al. Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, \nViraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm \nfor Fully Overlapped Allan Variance and Total Variance for Analysis and \nModeling of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. \n10.1109/LSENS.2018.2829799. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element data set to analyze. real(kind=real64), intent(in), optional :: dt An optional input specifying the time increment between \nsamples in x. If not specified, this value is set to 1. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value real(kind=real64), allocatable, dimension(:,:) An M-by-2 array containing the results where M is N / 2 - 1\nif N is even; else, M is (N - 1) / 2 - 1 if N is odd. The \nfirst column contains the averaging times associated with \nthe M results stored in the second column.","tags":"","loc":"proc\\allan_variance.html"},{"title":"difference – FSTATS","text":"public pure function difference(x) result(rst) Computes the difference between elements in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array on which to operate. Return Value real(kind=real64), allocatable, dimension(:) The (N-1)-element array containing the differences between adjacent\nelements.","tags":"","loc":"proc\\difference.html"},{"title":"factorial – FSTATS","text":"public pure elemental function factorial(x) result(rst) Computes the factorial of X. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value whose factorial is to be computed. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\factorial.html"},{"title":"f_test – FSTATS","text":"public subroutine f_test(x1, x2, stat, p, dof1, dof2) Computes the F-test and returns the probability (two-tailed) that\nthe variances of two data sets are not significantly different. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The F-statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from the two underlying populations that \nhave the same variance. real(kind=real64), intent(out) :: dof1 A measure of the degrees of freedom. real(kind=real64), intent(out) :: dof2 A measure of the degrees of freedom.","tags":"","loc":"proc\\f_test.html"},{"title":"t_test_equal_variance – FSTATS","text":"public subroutine t_test_equal_variance(x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed equivalent variances. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"proc\\t_test_equal_variance.html"},{"title":"t_test_paired – FSTATS","text":"public subroutine t_test_paired(x1, x2, stat, p, dof, err) Computes the 2-tailed Student's T-Test for two paired data sets. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An N-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same \n length.","tags":"","loc":"proc\\t_test_paired.html"},{"title":"t_test_unequal_variance – FSTATS","text":"public subroutine t_test_unequal_variance(x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed non-equivalent variances. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"proc\\t_test_unequal_variance.html"},{"title":"confidence_interval – FSTATS","text":"public interface confidence_interval Computes the confidence interval for the specified distribution. See Also Wikipedia Module Procedures private pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: s The sample standard deviation. integer(kind=int32), intent(in) :: n The number of samples in the data set. Return Value real(kind=real64) The result. private pure function confidence_interval_array(dist, alpha, x) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: x (:) An N-element array containing the data to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"interface\\confidence_interval.html"},{"title":"report_array_size_error – FSTATS","text":"public subroutine report_array_size_error(err, fname, name, expect, actual) Reports an array size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the array. integer(kind=int32), intent(in) :: expect The expected size of the array. integer(kind=int32), intent(in) :: actual The actual size of the array. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_array_size_error.html"},{"title":"report_arrays_not_same_size_error – FSTATS","text":"public subroutine report_arrays_not_same_size_error(err, fname, name1, name2, size1, size2) Reports an error relating to two arrays not being the same size\nwhen they should be the same size. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name1 The name of the first array. character(len=*), intent(in) :: name2 The name of the second array. integer(kind=int32), intent(in) :: size1 The size of the first array. integer(kind=int32), intent(in) :: size2 The size of the second array. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_arrays_not_same_size_error.html"},{"title":"report_iteration_count_error – FSTATS","text":"public subroutine report_iteration_count_error(err, fname, msg, mincount) Reports an iteration count error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*) :: fname The name of the routine in which the error occurred. character(len=*) :: msg The error message. integer(kind=int32), intent(in) :: mincount The minimum iteration count expected. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: emsg","tags":"","loc":"proc\\report_iteration_count_error.html"},{"title":"report_matrix_size_error – FSTATS","text":"public subroutine report_matrix_size_error(err, fname, name, expect_rows, expect_cols, actual_rows, actual_cols) Reports a matrix size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the matrix. integer(kind=int32), intent(in) :: expect_rows The expected number of rows. integer(kind=int32), intent(in) :: expect_cols The expected number of columns. integer(kind=int32), intent(in) :: actual_rows The actual number of rows. integer(kind=int32), intent(in) :: actual_cols The actual number of columns. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_matrix_size_error.html"},{"title":"report_memory_error – FSTATS","text":"public subroutine report_memory_error(err, fname, code) Reports a memory allocation related error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: code The error code returned by the allocation routine. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_memory_error.html"},{"title":"report_underdefined_error – FSTATS","text":"public subroutine report_underdefined_error(err, fname, expect, actual) Reports an underdefined problem error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: expect The expected minimum number of equations. integer(kind=int32), intent(in) :: actual The actual number of equations. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_underdefined_error.html"},{"title":"lowess – FSTATS","text":"public subroutine lowess(x, y, ys, fsmooth, nstps, del, rweights, resid, err) Computes the smoothing of a data set using a robust locally weighted\nscatterplot smoothing (LOWESS) algorithm. Fitted values are computed at\neach of the supplied x values. Remarks The code is a reimplementation of the LOWESS library. For a detailed\nunderstanding, see [this]\n(http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf) \npaper by William Cleveland. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable data. This\narray must be monotonically increasing. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable data. real(kind=real64), intent(out), dimension(:) :: ys An N-element array where the smoothed results will be written. real(kind=real64), intent(in), optional :: fsmooth An optional input that specifies the amount of smoothing. Specifically, this value is the fraction of points used to compute\neach value. As this value increases, the output becomes smoother.\nChoosing a value in the range of 0.2 to 0.8 typically results in a\ngood fit. The default value is 0.2. integer(kind=int32), intent(in), optional :: nstps An optional input that specifies the numb of iterations. If set to\nzero, a non-robust fit is returned. The default value is set to 2. real(kind=real64), intent(in), optional :: del real(kind=real64), intent(out), optional, dimension(:), target :: rweights An optional N-element array, that if supplied, will be used to\nreturn the weights given to each data point. real(kind=real64), intent(out), optional, dimension(:), target :: resid An optional N-element array, that if supplied, will be used to \nreturn the residual. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation error.","tags":"","loc":"proc\\lowess.html"},{"title":"full_factorial – FSTATS","text":"public subroutine full_factorial(vars, tbl, err) Computes a table with values scaled from 1 to N describing a \nfull-factorial design. program example use iso_fortran_env use fstats implicit none ! Local Variables integer ( int32 ) :: i , vars ( 3 ), tbl ( 24 , 3 ) ! Define the number of design points for each of the 3 factors to study vars = [ 2 , 4 , 3 ] ! Determine the design table call full_factorial ( vars , tbl ) ! Display the table do i = 1 , size ( tbl , 1 ) print * , tbl ( i ,:) end do end program The above program produces the following output. 1 1 1\n1 1 2\n1 1 3\n1 2 1\n1 2 2\n1 2 3\n1 3 1\n1 3 2\n1 3 3\n1 4 1\n1 4 2\n1 4 3\n2 1 1\n2 1 2\n2 1 3\n2 2 1\n2 2 2\n2 2 3\n2 3 1\n2 3 2\n2 3 3\n2 4 1\n2 4 2\n2 4 3 Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each of the M entries to the array is expected to contain \nthe number of options for that particular factor to explore. \nThis value must be greater than or equal to 1. integer(kind=int32), intent(out) :: tbl (:,:) A table where the design will be written. Use \nget_full_factorial_matrix_size to determine the appropriate \ntable size. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.\n- FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized.","tags":"","loc":"proc\\full_factorial.html"},{"title":"get_full_factorial_matrix_size – FSTATS","text":"public subroutine get_full_factorial_matrix_size(vars, m, n, err) Computes the appropriate size for a full-factorial design table. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each \nof the M entries to the array is expected to contain the \nnumber of options for that particular factor to explore. This value must be greater than or equal to 1. integer(kind=int32), intent(out) :: m The number of rows for the table. integer(kind=int32), intent(out) :: n The number of columns for the table. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.","tags":"","loc":"proc\\get_full_factorial_matrix_size.html"},{"title":"anova – FSTATS","text":"public interface anova Performs an analysis of variance (ANOVA) on the supplied data \nset. The following example illustrates a single-factor ANOVA on a \ndata set. program example use iso_fortran_env use fstats implicit none ! Local Variables character , parameter :: tab = achar ( 9 ) real ( real64 ) :: x ( 10 , 2 ) type ( single_factor_anova_table ) :: tbl ! Define the data x = reshape ( & [ & 3.086d3 , 3.082d3 , 3.069d3 , 3.072d3 , 3.045d3 , 3.070d3 , 3.079d3 , & 3.050d3 , 3.062d3 , 3.062d3 , 3.075d3 , 3.061d3 , 3.063d3 , 3.038d3 , & 3.070d3 , 3.062d3 , 3.070d3 , 3.049d3 , 3.042d3 , 3.063d3 & ], & [ 10 , 2 ] & ) ! Perform the ANOVA tbl = anova ( x ) ! Print out the table print '(A)' , \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" print '(AF2.0AF5.1AF5.1AF5.3AF5.3)' , \"Main Factor: \" // tab , & tbl % main_factor % dof , tab , & tbl % main_factor % sum_of_squares , tab // tab , & tbl % main_factor % variance , tab // tab , & tbl % main_factor % f_statistic , tab , & tbl % main_factor % probability print '(AF3.0AF6.1AF5.1)' , \"Within: \" // tab , & tbl % within_factor % dof , tab , & tbl % within_factor % sum_of_squares , tab // tab , & tbl % within_factor % variance print '(AF3.0AF6.1AF5.1)' , \"Total: \" // tab // tab , & tbl % total_dof , tab , & tbl % total_sum_of_squares , tab // tab , & tbl % total_variance print '(AF6.1)' , \"Overall Mean: \" , tbl % overall_mean end program The above program produces the following output. Description DOF Sum of Sq. Variance F-Stat P-Value\nMain Factor: 1. 352.8 352.8 2.147 0.160\nWithin: 18. 2958.2 164.3\nTotal: 19. 3311.0 174.3\nOverall Mean: 3063.5 See Also Wikipedia SPC Excel Single Factor ANOVA SPC Excel Gage R&R SPC Excel Understanding Regression Statistics NIST - Two Way ANOVA Module Procedures private function anova_1_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the M replications of the N test \npoints of interest. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. private function anova_2_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:,:) An M-by-N-by-K array containing the M replications of the\nN first factor results, and the K second factor results. Return Value type( two_factor_anova_table ) A two_factor_anova_table instance containing the ANOVA results. private function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: nmodelparams The number of model parameters. real(kind=real64), intent(in) :: ymeas (:) An N-element array containing the measured dependent variable data. real(kind=real64), intent(in) :: ymod (:) An N-element array containing the modeled dependent variable data. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the \n same length.\n- FS_MEMORY_ERROR: Occurs if a memory error is encountered. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results.","tags":"","loc":"interface\\anova.html"},{"title":"fstats_bootstrap – FSTATS","text":"Uses omp_lib linalg fstats_errors fstats_distributions fstats_regression fstats_descriptive_statistics iso_fortran_env fstats_special_functions Interfaces interface public subroutine bootstrap_resampling_routine(x, xn) Defines the signature of a subroutine used to compute a \nresampling of data for bootstrapping purposes. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be \nwritten. interface public function bootstrap_statistic_routine(x) result(rst) Defines the signature of a function for computing the desired\nbootstrap statistic. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The array of data to analyze. Return Value real(kind=real64) The resulting statistic. Derived Types type, public :: bootstrap_regression_statistics A container for regression-related statistical information as \ncomputed in a bootstrap, or equivalent, calculation. Components Type Visibility Attributes Name Initial real(kind=real64), public :: lower_confidence_interval The lower limit of the confidence interval for the parameter. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. Read more… real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. Read more… real(kind=real64), public :: upper_confidence_interval The upper limit of the confidence interval for the parameter. type, public :: bootstrap_statistics A collection of statistics resulting from the bootstrap process. Components Type Visibility Attributes Name Initial real(kind=real64), public :: bias The bias in the statistic. real(kind=real64), public :: lower_confidence_interval The lower confidence limit on the statistic. real(kind=real64), public, allocatable, dimension(:) :: population An array of the population values generated by the bootstrap\nprocess. real(kind=real64), public :: standard_error The standard error of the statistic. real(kind=real64), public :: statistic_value The value of the statistic of interest. real(kind=real64), public :: upper_confidence_interval The upper confidence limit on the statistic. Functions public function bootstrap (stat, x, method, nsamples, alpha) result(rst) Performs a bootstrap calculation on the supplied data set for the given\nstatistic. The default implementation utlizes a random resampling with \nreplacement. Other resampling methods may be defined by specifying an \nappropriate routine by means of the method input. Arguments Type Intent Optional Attributes Name procedure( bootstrap_statistic_routine ), intent(in), pointer :: stat The routine used to compute the desired statistic. real(kind=real64), intent(in), dimension(:) :: x The N-element data set. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. integer(kind=int32), intent(in), optional :: nsamples An optional input, that if supplied, specifies the number of \nresampling runs to perform. The default is 10 000. real(kind=real64), intent(in), optional :: alpha An optional input, that if supplied, defines the significance level\nto use for the analysis. The default is 0.05. Return Value type( bootstrap_statistics ) The resulting bootstrap_statistics type containing the confidence\nintervals, bias, standard error, etc. for the analyzed statistic. Subroutines public subroutine bootstrap_linear_least_squares (order, intercept, x, y, coeffs, ymod, resid, nsamples, stats, bias, alpha, method, bscoeffs, err) Computes a linear least-squares regression to fit a set of data.\nBootstrapping is utilized to gain insight into the quality of \nthe fit. Resampling for the bootstrap process is a random resampling \nwith replacement process with the range of values limited by the \nstandard deviation of the original data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out), dimension(:) :: coeffs An ORDER+1 element array where the coefficients will\nbe written. real(kind=real64), intent(out), dimension(:) :: ymod An N-element array where the modeled data will be written. real(kind=real64), intent(out), dimension(:) :: resid An N-element array where the residual error data will be \nwritten (modeled - actual). integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. type( bootstrap_regression_statistics ), intent(out), optional, dimension(:) :: stats An M-element array of bootstrap_regression_statistics items \nwhere M = ORDER + 1 when intercept is set to true; however, \nif intercept is set to false, M = ORDER. real(kind=real64), intent(out), optional, dimension(:) :: bias An ORDER+1 element array where an estimate of the bias of\neach coefficient is returned based upon the results of the\nbootstrapping analysis. The bias is computed as the difference \nbetween the mean of the boostrap population results for the given \nparameter and the original estimate of the given parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine bootstrap_nonlinear_least_squares (fun, x, y, params, ymod, resid, nsamples, weights, maxp, minp, stats, alpha, controls, settings, info, bias, method, bscoeffs, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain \ninsight into the quality of the fit. Resampling for the bootstrap \nprocess is a random resampling with replacement process with the \nrange of values limited by the standard deviation of the original \ndata set. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( bootstrap_regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. real(kind=real64), intent(out), optional, dimension(:) :: bias An optional N-element array that, if supplied, will be used to \nprovide an estimate of the bias of each model parameter based upon\nthe results of the bootstrapping analysis. The bias is computed as \nthe difference between the mean of the boostrap population results \nfor the given parameter and the original estimate of the given \nparameter. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed. public subroutine random_resample (x, xn) Random resampling, with replacement, based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written. public subroutine scaled_random_resample (x, xn) A random resampling, scaled by the standard deviation of the original\ndata, but based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"module\\fstats_bootstrap.html"},{"title":"fstats_descriptive_statistics – FSTATS","text":"Uses linalg fstats_errors ferror iso_fortran_env Functions public pure function covariance (x, y) result(rst) Computes the sample covariance of two data sets. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The covariance. public pure function mean (x) result(rst) Computes the mean of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result. public function median (x) result(rst) Computes the median of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout) :: x (:) The array of values to analyze. On output, this array is sorted into\nascending order. Return Value real(kind=real64) The result. public pure function quantile (x, q) result(rst) Computes the specified quantile of a data set using the SAS \nMethod 4. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the data. real(kind=real64), intent(in) :: q The quantile to compute (e.g. 0.25 computes the 25% quantile). Return Value real(kind=real64) The result. public pure function standard_deviation (x) result(rst) Computes the sample standard deviation of the values in an array. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result. public function trimmed_mean (x, p) result(rst) Computes the trimmed mean of a data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout), dimension(:) :: x An N-element array containing the data. On output, the\narray is sorted into ascending order. real(kind=real64), intent(in), optional :: p An optional parameter specifying the percentage of values\nfrom either end of the distribution to remove. The default\nis 0.05 such that the bottom 5% and top 5% are removed. Return Value real(kind=real64) The trimmed mean. public pure function variance (x) result(rst) Computes the sample variance of the values in an array. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64)","tags":"","loc":"module\\fstats_descriptive_statistics.html"},{"title":"fstats_distributions – FSTATS","text":"Uses fstats_special_functions fstats_helper_routines ieee_arithmetic iso_fortran_env Interfaces interface public pure elemental function distribution_function(this, x) result(rst) Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. interface public pure function distribution_property(this) result(rst) Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. Derived Types type, public, extends( distribution ) :: binomial_distribution Defines a binomial distribution. The binomial distribution describes\nthe probability p of getting k successes in n independent trials. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: n The number of independent trials. real(kind=real64), public :: p The success probability for each trial. This parameter must\nexist on the set [0, 1]. Type-Bound Procedures procedure, public :: cdf => bd_cdf procedure, public :: mean => bd_mean procedure, public :: median => bd_median procedure, public :: mode => bd_mode procedure, public :: pdf => bd_pdf procedure, public :: variance => bd_variance type, public, extends( distribution ) :: chi_squared_distribution Defines a Chi-squared distribution. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => cs_cdf procedure, public :: mean => cs_mean procedure, public :: median => cs_median procedure, public :: mode => cs_mode procedure, public :: pdf => cs_pdf procedure, public :: variance => cs_variance type, public :: distribution Defines a probability distribution. Type-Bound Procedures procedure( distribution_function ), public, deferred, pass :: cdf ..\\..\\ Computes the cumulative distribution function.<\\p> procedure( distribution_property ), public, deferred, pass :: mean ..\\..\\ Computes the mean of the distribution.<\\p> procedure( distribution_property ), public, deferred, pass :: median ..\\..\\ Computes the median of the distribution.<\\p> procedure( distribution_property ), public, deferred, pass :: mode ..\\..\\ Computes the mode of the distribution.<\\p> procedure( distribution_function ), public, deferred, pass :: pdf ..\\..\\ Computes the probability density function.<\\p> procedure( distribution_property ), public, deferred, pass :: variance ..\\..\\ Computes the variance of the distribution.<\\p> type, public, extends( distribution ) :: f_distribution Defines an F-distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: d1 The measure of degrees of freedom for the first data set. real(kind=real64), public :: d2 The measure of degrees of freedom for the second data set. Type-Bound Procedures procedure, public :: cdf => fd_cdf procedure, public :: mean => fd_mean procedure, public :: median => fd_median procedure, public :: mode => fd_mode procedure, public :: pdf => fd_pdf procedure, public :: variance => fd_variance type, public, extends( distribution ) :: normal_distribution Defines a normal distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: mean_value The mean value of the distribution. real(kind=real64), public :: standard_deviation The standard deviation of the distribution. Type-Bound Procedures procedure, public :: cdf => nd_cdf procedure, public :: mean => nd_mean procedure, public :: median => nd_median procedure, public :: mode => nd_mode procedure, public :: pdf => nd_pdf procedure, public :: standardize => nd_standardize procedure, public :: variance => nd_variance type, public, extends( distribution ) :: t_distribution Defines Student's T-Distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => td_cdf procedure, public :: mean => td_mean procedure, public :: median => td_median procedure, public :: mode => td_mode procedure, public :: pdf => td_pdf procedure, public :: variance => td_variance","tags":"","loc":"module\\fstats_distributions.html"},{"title":"fstats_sampling – FSTATS","text":"Uses linalg fstats_distributions iso_fortran_env Interfaces public interface box_muller_sample Generates random, normally distributed values via the Box-Muller \ntransform. private function box_muller_sample_scalar(mu, sigma) result(rst) Generates a pair of independent, standard, normally distributed\nrandom values using the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. Return Value real(kind=real64), (2) The pair of random values. private function box_muller_array(mu, sigma, n) result(rst) Generates an array of normally distributed random values sampled\nby the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. integer(kind=int32), intent(in) :: n The number of Box-Muller pairs to generate. Return Value real(kind=real64), allocatable, dimension(:) A 2N-element array containing the N Box-Muller pairs. Functions public function rejection_sample (tdist, n, xmin, xmax) result(rst) Uses rejection sampling to randomly sample a target distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: tdist The distribution to sample integer(kind=int32), intent(in) :: n The number of samples to make. real(kind=real64), intent(in) :: xmin The minimum range to explore. real(kind=real64), intent(in) :: xmax The maximum range to explore. Return Value real(kind=real64), allocatable, dimension(:) An N-element array containing the N samples from the \ndistribution.","tags":"","loc":"module\\fstats_sampling.html"},{"title":"fstats_special_functions – FSTATS","text":"Uses ieee_arithmetic iso_fortran_env Functions public pure elemental function beta (a, b) result(rst) Computes the beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. Return Value real(kind=real64) The value of the beta function at and . public pure elemental function digamma (x) result(rst) Computes the digamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function incomplete_beta (a, b, x) result(rst) Computes the incomplete beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the incomplete beta function. public pure elemental function incomplete_gamma_lower (a, x) result(rst) Computes the lower incomplete gamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function incomplete_gamma_upper (a, x) result(rst) Computes the upper incomplete gamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function regularized_beta (a, b, x) result(rst) Computes the regularized beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the regularized beta function.","tags":"","loc":"module\\fstats_special_functions.html"},{"title":"fstats_regression – FSTATS","text":"Uses linalg fstats_errors fstats_distributions blas fstats_descriptive_statistics iso_fortran_env fstats_special_functions fstats_hypothesis ferror Variables Type Visibility Attributes Name Initial integer(kind=int32), public, parameter :: FS_LEVENBERG_MARQUARDT_UPDATE = 1 integer(kind=int32), public, parameter :: FS_NIELSEN_UPDATE = 3 integer(kind=int32), public, parameter :: FS_QUADRATIC_UPDATE = 2 Interfaces interface public subroutine iteration_update(iter, funvals, resid, params, step) Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: iter real(kind=real64), intent(in) :: funvals (:) real(kind=real64), intent(in) :: resid (:) real(kind=real64), intent(in) :: params (:) real(kind=real64), intent(in) :: step (:) interface public subroutine regression_function(xdata, params, resid, stop) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: xdata real(kind=real64), intent(in), dimension(:) :: params real(kind=real64), intent(out), dimension(:) :: resid logical, intent(out) :: stop Derived Types type, public :: convergence_info Provides information regarding convergence status. Components Type Visibility Attributes Name Initial logical, public :: converge_on_gradient True if convergence on the gradient was achieved; else, false. logical, public :: converge_on_residual_parameter True if convergence on the residual error parameter was achieved; \nelse, false. logical, public :: converge_on_solution_change True if convergence on the change in solution was achieved; else,\nfalse. integer(kind=int32), public :: function_evaluation_count The function evaluation count. real(kind=real64), public :: gradient_value The value of the gradient test parameter. integer(kind=int32), public :: iteration_count The iteration count. logical, public :: reach_function_evaluation_limit True if the solution did not converge in the allowed number of\nfunction evaluations. logical, public :: reach_iteration_limit True if the solution did not converge in the allowed number of \niterations. real(kind=real64), public :: residual_value The value of the residual error parameter. real(kind=real64), public :: solution_change_value The value of the change in solution parameter. logical, public :: user_requested_stop True if the user requested the stop; else, false. type, public :: iteration_controls Provides a collection of iteration control parameters. Components Type Visibility Attributes Name Initial real(kind=real64), public :: change_in_solution_tolerance Defines a tolerance on the change in parameter values. real(kind=real64), public :: gradient_tolerance Defines a tolerance on the gradient of the fitted function. real(kind=real64), public :: iteration_improvement_tolerance Defines a tolerance to ensure adequate improvement on each \niteration. integer(kind=int32), public :: max_function_evaluations Defines the maximum number of function evaluations allowed. integer(kind=int32), public :: max_iteration_between_updates Defines how many iterations can pass before a re-evaluation of \nthe Jacobian matrix is forced. integer(kind=int32), public :: max_iteration_count Defines the maximum number of iterations allowed. real(kind=real64), public :: residual_tolerance Defines a tolerance on the metric associated with the residual \nerror. Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_tolerances type, public :: lm_solver_options Options to control the Levenberg-Marquardt solver. Components Type Visibility Attributes Name Initial real(kind=real64), public :: damping_decrease_factor The factor to use when decreasing the damping parameter. real(kind=real64), public :: damping_increase_factor The factor to use when increasing the damping parameter. real(kind=real64), public :: finite_difference_step_size The step size used for the finite difference calculations of the\nJacobian matrix. integer(kind=int32), public :: method The solver method to utilize.\n- FS_LEVENBERG_MARQUARDT_UPDATE:\n- FS_QUADRATIC_UPDATE:\n- FS_NIELSEN_UDPATE: Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_settings type, public :: regression_statistics A container for regression-related statistical information. Components Type Visibility Attributes Name Initial real(kind=real64), public :: confidence_interval The confidence interval for the parameter at the level \ndetermined by the regression process. Read more… real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. Read more… real(kind=real64), public :: standard_error The standard error for the model coefficient. Read more… real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. Read more… Functions public function adjusted_r_squared (p, x, xm, err) result(rst) Computes the adjusted R-squared value for a data set. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: p The number of variables. real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result. public function calculate_regression_statistics (resid, params, c, alpha, err) result(rst) Computes statistics for the quality of fit for a regression \nmodel. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: resid (:) An M-element array containing the model residual errors. real(kind=real64), intent(in) :: params (:) An N-element array containing the model parameters. real(kind=real64), intent(in) :: c (:,:) The N-by-N covariance matrix. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value type( regression_statistics ), allocatable, (:) A regression_statistics object containing the analysis results. public pure function correlation (x, y) result(rst) Computes the sample correlation coefficient (an estimate to the \npopulation Pearson correlation) as follows. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The correlation coefficient. public function r_squared (x, xm, err) result(rst) Computes the R-squared value for a data set. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result. Subroutines public subroutine coefficient_matrix (order, intercept, x, c, err) Computes the coefficient matrix to the linear \nleast-squares regression problem of , where is the coefficient matrix computed here, is \nthe vector of coefficients to be determined, and is the \nvector of measured dependent variables. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be\nat least one (linear equation), but can be higher as desired. logical, intent(in) :: intercept Set to true if the intercept is being computed\nas part of the regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(out) :: c (:,:) An N-by-K matrix where the results will be written. K\nmust equal order + 1 in the event intercept is true; \nhowever, if intercept is false, K must equal order. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. public subroutine covariance_matrix (x, c, err) Computes the covariance matrix where and is computed\nby coefficient_matrix. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the formatted independent data\n matrix as computed by coefficient_matrix. real(kind=real64), intent(out) :: c (:,:) The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not \n sized correctly.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine jacobian (fun, xdata, params, jac, stop, f0, f1, step, err) Computes the Jacobian matrix for a nonlinear regression problem. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: xdata (:) The M-element array containing x-coordinate data. real(kind=real64), intent(in) :: params (:) The N-element array containing the model parameters. real(kind=real64), intent(out) :: jac (:,:) The M-by-N matrix where the Jacobian will be written. logical, intent(out) :: stop A value that the user can set in fun forcing the\nevaluation process to stop prior to completion. real(kind=real64), intent(in), optional, target :: f0 (:) An optional M-element array containing the model values\n using the current parameters as defined in m. This input \ncan be used to prevent the routine from performing a \nfunction evaluation at the model parameter state defined in \nparams. real(kind=real64), intent(out), optional, target :: f1 (:) An optional M-element workspace array used for function\nevaluations. real(kind=real64), intent(in), optional :: step The differentiation step size. The default is the square \nroot of machine precision. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine linear_least_squares (order, intercept, x, y, coeffs, ymod, resid, stats, alpha, err) Computes a linear least-squares regression to fit a set of data. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in) :: y (:) An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out) :: coeffs (:) An ORDER+1 element array where the coefficients will be written. real(kind=real64), intent(out) :: ymod (:) An N-element array where the modeled data will be written. real(kind=real64), intent(out) :: resid (:) An N-element array where the residual error data will be \nwritten (modeled - actual). type( regression_statistics ), intent(out), optional :: stats (:) An M-element array of regression_statistics items where \nM = ORDER + 1 when intercept is set to true; however, if \nintercept is set to false, M = ORDER. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine nonlinear_least_squares (fun, x, y, params, ymod, resid, weights, maxp, minp, stats, alpha, controls, settings, info, status, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. procedure( iteration_update ), intent(in), optional, pointer :: status An optional pointer to a routine that can be used to extract\niteration information. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"module\\fstats_regression.html"},{"title":"fstats_allan – FSTATS","text":"Uses fstats_errors iso_fortran_env Functions public function allan_variance (x, dt, err) result(rst) Computes the Allan variance of a data set. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element data set to analyze. real(kind=real64), intent(in), optional :: dt An optional input specifying the time increment between \nsamples in x. If not specified, this value is set to 1. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value real(kind=real64), allocatable, dimension(:,:) An M-by-2 array containing the results where M is N / 2 - 1\nif N is even; else, M is (N - 1) / 2 - 1 if N is odd. The \nfirst column contains the averaging times associated with \nthe M results stored in the second column.","tags":"","loc":"module\\fstats_allan.html"},{"title":"fstats_helper_routines – FSTATS","text":"Uses iso_fortran_env Functions public pure function difference (x) result(rst) Computes the difference between elements in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array on which to operate. Return Value real(kind=real64), allocatable, dimension(:) The (N-1)-element array containing the differences between adjacent\nelements. public pure elemental function factorial (x) result(rst) Computes the factorial of X. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value whose factorial is to be computed. Return Value real(kind=real64) The result.","tags":"","loc":"module\\fstats_helper_routines.html"},{"title":"fstats_hypothesis – FSTATS","text":"Uses fstats_errors fstats_distributions fstats_descriptive_statistics iso_fortran_env fstats_special_functions ieee_arithmetic Interfaces public interface confidence_interval Computes the confidence interval for the specified distribution. See Also Wikipedia private pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: s The sample standard deviation. integer(kind=int32), intent(in) :: n The number of samples in the data set. Return Value real(kind=real64) The result. private pure function confidence_interval_array(dist, alpha, x) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: x (:) An N-element array containing the data to analyze. Return Value real(kind=real64) The result. Subroutines public subroutine f_test (x1, x2, stat, p, dof1, dof2) Computes the F-test and returns the probability (two-tailed) that\nthe variances of two data sets are not significantly different. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The F-statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from the two underlying populations that \nhave the same variance. real(kind=real64), intent(out) :: dof1 A measure of the degrees of freedom. real(kind=real64), intent(out) :: dof2 A measure of the degrees of freedom. public subroutine t_test_equal_variance (x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed equivalent variances. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. public subroutine t_test_paired (x1, x2, stat, p, dof, err) Computes the 2-tailed Student's T-Test for two paired data sets. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An N-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same \n length. public subroutine t_test_unequal_variance (x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed non-equivalent variances. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"module\\fstats_hypothesis.html"},{"title":"fstats_errors – FSTATS","text":"Uses ferror iso_fortran_env Variables Type Visibility Attributes Name Initial integer(kind=int32), public, parameter :: FS_ARRAY_SIZE_ERROR = 10000 integer(kind=int32), public, parameter :: FS_INVALID_INPUT_ERROR = 10002 integer(kind=int32), public, parameter :: FS_MATRIX_SIZE_ERROR = 10001 integer(kind=int32), public, parameter :: FS_MEMORY_ERROR = 10003 integer(kind=int32), public, parameter :: FS_NO_ERROR = 0 integer(kind=int32), public, parameter :: FS_TOLERANCE_TOO_SMALL_ERROR = 10005 integer(kind=int32), public, parameter :: FS_TOO_FEW_ITERATION_ERROR = 10006 integer(kind=int32), public, parameter :: FS_UNDERDEFINED_PROBLEM_ERROR = 10004 Subroutines public subroutine report_array_size_error (err, fname, name, expect, actual) Reports an array size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the array. integer(kind=int32), intent(in) :: expect The expected size of the array. integer(kind=int32), intent(in) :: actual The actual size of the array. public subroutine report_arrays_not_same_size_error (err, fname, name1, name2, size1, size2) Reports an error relating to two arrays not being the same size\nwhen they should be the same size. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name1 The name of the first array. character(len=*), intent(in) :: name2 The name of the second array. integer(kind=int32), intent(in) :: size1 The size of the first array. integer(kind=int32), intent(in) :: size2 The size of the second array. public subroutine report_iteration_count_error (err, fname, msg, mincount) Reports an iteration count error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*) :: fname The name of the routine in which the error occurred. character(len=*) :: msg The error message. integer(kind=int32), intent(in) :: mincount The minimum iteration count expected. public subroutine report_matrix_size_error (err, fname, name, expect_rows, expect_cols, actual_rows, actual_cols) Reports a matrix size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the matrix. integer(kind=int32), intent(in) :: expect_rows The expected number of rows. integer(kind=int32), intent(in) :: expect_cols The expected number of columns. integer(kind=int32), intent(in) :: actual_rows The actual number of rows. integer(kind=int32), intent(in) :: actual_cols The actual number of columns. public subroutine report_memory_error (err, fname, code) Reports a memory allocation related error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: code The error code returned by the allocation routine. public subroutine report_underdefined_error (err, fname, expect, actual) Reports an underdefined problem error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: expect The expected minimum number of equations. integer(kind=int32), intent(in) :: actual The actual number of equations.","tags":"","loc":"module\\fstats_errors.html"},{"title":"fstats_smoothing – FSTATS","text":"Uses linalg fstats_errors ferror iso_fortran_env Subroutines public subroutine lowess (x, y, ys, fsmooth, nstps, del, rweights, resid, err) Computes the smoothing of a data set using a robust locally weighted\nscatterplot smoothing (LOWESS) algorithm. Fitted values are computed at\neach of the supplied x values. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable data. This\narray must be monotonically increasing. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable data. real(kind=real64), intent(out), dimension(:) :: ys An N-element array where the smoothed results will be written. real(kind=real64), intent(in), optional :: fsmooth An optional input that specifies the amount of smoothing. Specifically, this value is the fraction of points used to compute\neach value. As this value increases, the output becomes smoother.\nChoosing a value in the range of 0.2 to 0.8 typically results in a\ngood fit. The default value is 0.2. integer(kind=int32), intent(in), optional :: nstps An optional input that specifies the numb of iterations. If set to\nzero, a non-robust fit is returned. The default value is set to 2. real(kind=real64), intent(in), optional :: del real(kind=real64), intent(out), optional, dimension(:), target :: rweights An optional N-element array, that if supplied, will be used to\nreturn the weights given to each data point. real(kind=real64), intent(out), optional, dimension(:), target :: resid An optional N-element array, that if supplied, will be used to \nreturn the residual. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation error.","tags":"","loc":"module\\fstats_smoothing.html"},{"title":"fstats – FSTATS","text":"FSTATS is a modern Fortran statistical library containing routines for \ncomputing basic statistical properties, hypothesis testing, regression, \nspecial functions, and experimental design. Uses fstats_anova fstats_distributions fstats_allan fstats_bootstrap fstats_regression fstats_experimental_design fstats_smoothing fstats_descriptive_statistics iso_fortran_env fstats_special_functions fstats_sampling fstats_helper_routines fstats_hypothesis","tags":"","loc":"module\\fstats.html"},{"title":"fstats_experimental_design – FSTATS","text":"Uses fstats_errors iso_fortran_env Subroutines public subroutine full_factorial (vars, tbl, err) Computes a table with values scaled from 1 to N describing a \nfull-factorial design. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each of the M entries to the array is expected to contain \nthe number of options for that particular factor to explore. \nThis value must be greater than or equal to 1. integer(kind=int32), intent(out) :: tbl (:,:) A table where the design will be written. Use \nget_full_factorial_matrix_size to determine the appropriate \ntable size. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.\n- FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized. public subroutine get_full_factorial_matrix_size (vars, m, n, err) Computes the appropriate size for a full-factorial design table. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each \nof the M entries to the array is expected to contain the \nnumber of options for that particular factor to explore. This value must be greater than or equal to 1. integer(kind=int32), intent(out) :: m The number of rows for the table. integer(kind=int32), intent(out) :: n The number of columns for the table. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.","tags":"","loc":"module\\fstats_experimental_design.html"},{"title":"fstats_anova – FSTATS","text":"Uses fstats_errors fstats_descriptive_statistics iso_fortran_env fstats_special_functions ieee_arithmetic ferror Interfaces public interface anova Performs an analysis of variance (ANOVA) on the supplied data \nset. The following example illustrates a single-factor ANOVA on a \ndata set. program example use iso_fortran_env use fstats implicit none ! Local Variables character , parameter :: tab = achar ( 9 ) real ( real64 ) :: x ( 10 , 2 ) type ( single_factor_anova_table ) :: tbl ! Define the data x = reshape ( & [ & 3.086d3 , 3.082d3 , 3.069d3 , 3.072d3 , 3.045d3 , 3.070d3 , 3.079d3 , & 3.050d3 , 3.062d3 , 3.062d3 , 3.075d3 , 3.061d3 , 3.063d3 , 3.038d3 , & 3.070d3 , 3.062d3 , 3.070d3 , 3.049d3 , 3.042d3 , 3.063d3 & ], & [ 10 , 2 ] & ) ! Perform the ANOVA tbl = anova ( x ) ! Print out the table print '(A)' , \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" print '(AF2.0AF5.1AF5.1AF5.3AF5.3)' , \"Main Factor: \" // tab , & tbl % main_factor % dof , tab , & tbl % main_factor % sum_of_squares , tab // tab , & tbl % main_factor % variance , tab // tab , & tbl % main_factor % f_statistic , tab , & tbl % main_factor % probability print '(AF3.0AF6.1AF5.1)' , \"Within: \" // tab , & tbl % within_factor % dof , tab , & tbl % within_factor % sum_of_squares , tab // tab , & tbl % within_factor % variance print '(AF3.0AF6.1AF5.1)' , \"Total: \" // tab // tab , & tbl % total_dof , tab , & tbl % total_sum_of_squares , tab // tab , & tbl % total_variance print '(AF6.1)' , \"Overall Mean: \" , tbl % overall_mean end program The above program produces the following output. Description DOF Sum of Sq. Variance F-Stat P-Value\nMain Factor: 1. 352.8 352.8 2.147 0.160\nWithin: 18. 2958.2 164.3\nTotal: 19. 3311.0 174.3\nOverall Mean: 3063.5 See Also Wikipedia SPC Excel Single Factor ANOVA SPC Excel Gage R&R SPC Excel Understanding Regression Statistics NIST - Two Way ANOVA private function anova_1_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the M replications of the N test \npoints of interest. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. private function anova_2_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:,:) An M-by-N-by-K array containing the M replications of the\nN first factor results, and the K second factor results. Return Value type( two_factor_anova_table ) A two_factor_anova_table instance containing the ANOVA results. private function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: nmodelparams The number of model parameters. real(kind=real64), intent(in) :: ymeas (:) An N-element array containing the measured dependent variable data. real(kind=real64), intent(in) :: ymod (:) An N-element array containing the modeled dependent variable data. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the \n same length.\n- FS_MEMORY_ERROR: Occurs if a memory error is encountered. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. Derived Types type, public :: anova_factor Defines an ANOVA factor result. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedome. real(kind=real64), public :: f_statistic The F-statistic. real(kind=real64), public :: probability The variance probability term. real(kind=real64), public :: sum_of_squares The sum of the squares. real(kind=real64), public :: variance The estimate of variance. type, public :: single_factor_anova_table Defines a single-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: main_factor The main, or main factor, results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within-treatement (error) results. type, public :: two_factor_anova_table Defines a two-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: interaction The interaction effects. type( anova_factor ), public :: main_factor_1 The first main-factor results. type( anova_factor ), public :: main_factor_2 The second main-factor results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within (error) factor results.","tags":"","loc":"module\\fstats_anova.html"},{"title":"fstats_bootstrap.f90 – FSTATS","text":"Source Code module fstats_bootstrap use iso_fortran_env use fstats_errors use omp_lib use fstats_distributions use fstats_descriptive_statistics use fstats_special_functions use fstats_regression use linalg , only : sort implicit none private public :: bootstrap_resampling_routine public :: bootstrap_statistic_routine public :: random_resample public :: scaled_random_resample public :: bootstrap_statistics public :: bootstrap public :: bootstrap_regression_statistics public :: bootstrap_linear_least_squares public :: bootstrap_nonlinear_least_squares ! REFERENCES: ! - https://medium.com/@m21413108/bootstrapping-maximum-entropy-non-parametric-boot-python-3b1e23ea589d ! - https://cran.r-project.org/web/packages/meboot/vignettes/meboot.pdf ! - https://gist.github.com/christianjauregui/314456688a3c2fead43a48be3a47dad6 type bootstrap_regression_statistics !! A container for regression-related statistical information as !! computed in a bootstrap, or equivalent, calculation. real ( real64 ) :: standard_error !! The standard error for the model coefficient. real ( real64 ) :: t_statistic !! The T-statistic for the model coefficient. !! !! t_o = \\frac{ \\beta_{i} }{E_{s}(\\beta_{i})} real ( real64 ) :: probability !! The probability that the coefficient is not statistically !! important. A statistically important coefficient will have a !! low probability (p-value), typically 0.05 or lower; however, a !! p-value of up to ~0.2 may be acceptable dependent upon the !! problem. Typically any p-value larger than ~0.2 indicates the !! parameter is not statistically important for the model. !! !! p = t_{|t_o|, df_{residual}} real ( real64 ) :: upper_confidence_interval !! The upper limit of the confidence interval for the parameter. real ( real64 ) :: lower_confidence_interval !! The lower limit of the confidence interval for the parameter. end type type bootstrap_statistics !! A collection of statistics resulting from the bootstrap process. real ( real64 ) :: statistic_value !! The value of the statistic of interest. real ( real64 ) :: upper_confidence_interval !! The upper confidence limit on the statistic. real ( real64 ) :: lower_confidence_interval !! The lower confidence limit on the statistic. real ( real64 ) :: bias !! The bias in the statistic. real ( real64 ) :: standard_error !! The standard error of the statistic. real ( real64 ), allocatable , dimension (:) :: population !! An array of the population values generated by the bootstrap !! process. end type interface subroutine bootstrap_resampling_routine ( x , xn ) !! Defines the signature of a subroutine used to compute a !! resampling of data for bootstrapping purposes. use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be !! written. end subroutine function bootstrap_statistic_routine ( x ) result ( rst ) !! Defines the signature of a function for computing the desired !! bootstrap statistic. use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: x !! The array of data to analyze. real ( real64 ) :: rst !! The resulting statistic. end function end interface contains ! ****************************************************************************** ! RESAMPLING ! ------------------------------------------------------------------------------ subroutine random_resample ( x , xn ) !! Random resampling, with replacement, based upon a normal distribution. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be written. ! Parameters real ( real64 ), parameter :: scale = 1.25d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: xmin , xmax , rng ! Process n = size ( x ) xmin = x ( 1 ) xmax = x ( 1 ) do i = 2 , n xmin = min ( xmin , x ( i )) xmax = max ( xmax , x ( i )) end do rng = ( xmax - xmin ) call random_number ( xn ) xn = xn * rng + xmin end subroutine ! ------------------------------------------------------------------------------ subroutine scaled_random_resample ( x , xn ) !! A random resampling, scaled by the standard deviation of the original !! data, but based upon a normal distribution. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be written. ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: n real ( real64 ) :: eps ! Process n = size ( x ) eps = standard_deviation ( x ) / sqrt ( real ( n , real64 )) call random_number ( xn ) xn = eps * ( xn - half ) + x end subroutine ! ****************************************************************************** ! BOOTSTRAPPING ! ------------------------------------------------------------------------------ function bootstrap ( stat , x , method , nsamples , alpha ) result ( rst ) !! Performs a bootstrap calculation on the supplied data set for the given !! statistic. The default implementation utlizes a random resampling with !! replacement. Other resampling methods may be defined by specifying an !! appropriate routine by means of the method input. procedure ( bootstrap_statistic_routine ), pointer , intent ( in ) :: stat !! The routine used to compute the desired statistic. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element data set. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. integer ( int32 ), intent ( in ), optional :: nsamples !! An optional input, that if supplied, specifies the number of !! resampling runs to perform. The default is 10 000. real ( real64 ), intent ( in ), optional :: alpha !! An optional input, that if supplied, defines the significance level !! to use for the analysis. The default is 0.05. type ( bootstrap_statistics ) :: rst !! The resulting bootstrap_statistics type containing the confidence !! intervals, bias, standard error, etc. for the analyzed statistic. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , i1 , i2 , n , ns real ( real64 ) :: a real ( real64 ), allocatable , dimension (:) :: xn procedure ( bootstrap_resampling_routine ), pointer :: resample ! Initialization n = size ( x ) if ( present ( method )) then resample => method else resample => random_resample end if if ( present ( nsamples )) then ns = nsamples else ns = 10000 end if if ( present ( alpha )) then a = alpha else a = p05 end if allocate ( rst % population ( ns )) i1 = floor ( half * a * ns , int32 ) i2 = ns - i1 + 1 ! Analyze the basic data set rst % statistic_value = stat ( x ) rst % population ( 1 ) = rst % statistic_value ! Resampling Process #ifdef USEOPENMP ! Use OpenMP to run operations in parallel !$OMP PARALLEL DO PRIVATE(xn) SHARED(rst) do i = 2 , ns ! Per-thread memory allocation if (. not . allocated ( xn )) allocate ( xn ( n )) ! Resample the data call resample ( x , xn ) ! Compute the statistic rst % population ( i ) = stat ( xn ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( xn ( n )) do i = 2 , ns ! Resample the data call resample ( x , xn ) ! Compute the statistic for the resampled data rst % population ( i ) = stat ( xn ) end do #endif ! Compute the relevant quantities on the resampled statistic call sort ( rst % population , . true .) rst % upper_confidence_interval = rst % population ( i2 ) rst % lower_confidence_interval = rst % population ( i1 ) rst % bias = mean ( rst % population ) - rst % statistic_value rst % standard_error = standard_deviation ( rst % population ) end function ! ****************************************************************************** ! LINEAR REGRESSION ! ------------------------------------------------------------------------------ subroutine bootstrap_linear_least_squares ( order , intercept , x , y , & coeffs , ymod , resid , nsamples , stats , bias , alpha , method , bscoeffs , err ) !! Computes a linear least-squares regression to fit a set of data. !! Bootstrapping is utilized to gain insight into the quality of !! the fit. Resampling for the bootstrap process is a random resampling !! with replacement process with the range of values limited by the !! standard deviation of the original data set. integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be at !! least one (linear equation), but can be higher as desired, !! as long as there is sufficient data. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed as part of !! the regression; else, false. real ( real64 ), intent ( in ), dimension (:) :: x !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( in ), dimension (:) :: y !! An N-element array containing the dependent variable !! measurement points. real ( real64 ), intent ( out ), dimension (:) :: coeffs !! An ORDER+1 element array where the coefficients will !! be written. real ( real64 ), intent ( out ), dimension (:) :: ymod !! An N-element array where the modeled data will be written. real ( real64 ), intent ( out ), dimension (:) :: resid !! An N-element array where the residual error data will be !! written (modeled - actual). integer ( int32 ), intent ( in ), optional :: nsamples !! The number of bootstrapping samples to utilize. type ( bootstrap_regression_statistics ), intent ( out ), optional , & dimension (:) :: stats !! An M-element array of bootstrap_regression_statistics items !! where M = ORDER + 1 when intercept is set to true; however, !! if intercept is set to false, M = ORDER. real ( real64 ), intent ( out ), optional , dimension (:) :: bias !! An ORDER+1 element array where an estimate of the bias of !! each coefficient is returned based upon the results of the !! bootstrapping analysis. The bias is computed as the difference !! between the mean of the boostrap population results for the given !! parameter and the original estimate of the given parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. real ( real64 ), intent ( out ), optional , allocatable , target , dimension (:,:) :: bscoeffs !! An optional, allocatable matrix, containing the bootstrap !! distributions for each parameter stored in each row of the matrix !! such that the resulting matrix is NCOEFFS -by- NSAMPLES. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , j , n , ns , nc , ncoeffs , flag , nthreads , thread real ( real64 ) :: alph real ( real64 ), allocatable , dimension (:) :: fLocal , yLocal , rLocal real ( real64 ), allocatable , target , dimension (:,:) :: coeffstorage real ( real64 ), pointer , dimension (:,:) :: allcoeffs class ( errors ), pointer :: errmgr type ( errors ), target :: deferr procedure ( bootstrap_resampling_routine ), pointer :: resample ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( nsamples )) then ns = nsamples else ns = 1000 end if if ( present ( alpha )) then alph = alpha else alph = p05 end if if ( present ( method )) then resample => method else resample => scaled_random_resample end if n = size ( x ) ncoeffs = order + 1 nc = order if ( intercept ) nc = nc + 1 nthreads = omp_get_num_threads () ! Compute the fit call linear_least_squares ( order , intercept , x , y , coeffs , & ymod , resid , alpha = alph , err = errmgr ) if ( errmgr % has_error_occurred ()) return ! Memory Allocations if ( present ( bscoeffs )) then allocate ( bscoeffs ( ncoeffs , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"bootstrap_linear_least_squares\" , & flag ) return end if allcoeffs => bscoeffs else allocate ( coeffstorage ( ncoeffs , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"bootstrap_linear_least_squares\" , & flag ) return end if allcoeffs => coeffstorage end if allcoeffs (:, 1 ) = coeffs ! Cycle over each data set and perform the fit #ifdef USEOPENMP !$OMP PARALLEL DO PRIVATE(fLocal, yLocal, rLocal) SHARED(allcoeffs) do i = 2 , ns ! Get the current thread number ! The +1 is because OpenMP is zero-based for thread numbering thread = omp_get_thread_num () + 1 ! Allocate local arrays on a per-thread basis if (. not . allocated ( fLocal )) allocate ( fLocal ( n )) if (. not . allocated ( yLocal )) allocate ( yLocal ( n )) if (. not . allocated ( rLocal )) allocate ( rLocal ( n )) ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call linear_least_squares ( order , intercept , x , yLocal , & allcoeffs (:, i ), fLocal , rLocal , alpha = alph ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( fLocal ( n ), yLocal ( n ), rLocal ( n )) do i = 2 , ns ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call linear_least_squares ( order , intercept , x , yLocal , & allcoeffs (:, i ), fLocal , rLocal , alpha = alph ) end do #endif ! Perform statistics calculations, if needed if ( present ( stats )) then call compute_stats ( coeffs , allcoeffs , alph , intercept , stats ) end if ! Compute the bias for each parameter, if needed if ( present ( bias )) then ! Verify the size of the array if ( size ( bias ) /= ncoeffs ) then call report_array_size_error ( errmgr , & \"bootstrap_linear_least_squares\" , \"bias\" , ncoeffs , size ( bias )) return end if ! Perform the calculations do i = 1 , ncoeffs bias ( i ) = mean ( allcoeffs ( i ,:)) - coeffs ( i ) end do end if end subroutine ! ****************************************************************************** ! NONLINEAR REGRESSION ! ------------------------------------------------------------------------------ subroutine bootstrap_nonlinear_least_squares ( fun , x , y , params , ymod , resid , & nsamples , weights , maxp , minp , stats , alpha , controls , settings , info , & bias , method , bscoeffs , err ) !! Performs a nonlinear regression to fit a model using a version !! of the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain !! insight into the quality of the fit. Resampling for the bootstrap !! process is a random resampling with replacement process with the !! range of values limited by the standard deviation of the original !! data set. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: x (:) !! The M-element array containing independent data. real ( real64 ), intent ( in ) :: y (:) !! The M-element array containing dependent data. real ( real64 ), intent ( inout ) :: params (:) !! On input, the N-element array containing the initial estimate !! of the model parameters. On output, the computed model !! parameters. real ( real64 ), intent ( out ) :: ymod (:) !! An M-element array where the modeled dependent data will !! be written. real ( real64 ), intent ( out ) :: resid (:) !! An M-element array where the model residuals will be !! written. integer ( int32 ), intent ( in ), optional :: nsamples !! The number of bootstrapping samples to utilize. real ( real64 ), intent ( in ), optional , target :: weights (:) !! An optional M-element array allowing the weighting of !! individual points. real ( real64 ), intent ( in ), optional , target :: maxp (:) !! An optional N-element array that can be used as upper limits !! on the parameter values. If no upper limit is requested for !! a particular parameter, utilize a very large value. The !! internal default is to utilize huge() as a value. real ( real64 ), intent ( in ), optional , target :: minp (:) !! An optional N-element array that can be used as lower limits !! on the parameter values. If no lower limit is requested for !! a particalar parameter, utilize a very large magnitude, but !! negative, value. The internal default is to utilize -huge() !! as a value. type ( bootstrap_regression_statistics ), intent ( out ), optional :: stats (:) !! An optional N-element array that, if supplied, will be used !! to return statistics about the fit for each parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. type ( iteration_controls ), intent ( in ), optional :: controls !! An optional input providing custom iteration controls. type ( lm_solver_options ), intent ( in ), optional :: settings !! An optional input providing custom settings for the solver. type ( convergence_info ), intent ( out ), optional , target :: info !! An optional output that can be used to gain information about !! the iterative solution and the nature of the convergence. real ( real64 ), intent ( out ), optional , dimension (:) :: bias !! An optional N-element array that, if supplied, will be used to !! provide an estimate of the bias of each model parameter based upon !! the results of the bootstrapping analysis. The bias is computed as !! the difference between the mean of the boostrap population results !! for the given parameter and the original estimate of the given !! parameter. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. real ( real64 ), intent ( out ), optional , allocatable , target , dimension (:,:) :: bscoeffs !! An optional, allocatable matrix, containing the bootstrap !! distributions for each parameter stored in each row of the matrix !! such that the resulting matrix is NCOEFFS -by- NSAMPLES. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed !! is underdetetermined (M < N). !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied !! tolerances are too small to be practical. !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations !! are allowed. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , n , ns , nparams , flag real ( real64 ) :: alph real ( real64 ), allocatable , dimension (:) :: fLocal , yLocal , rLocal real ( real64 ), allocatable , target , dimension (:,:) :: coeffstorage real ( real64 ), pointer , dimension (:,:) :: allcoeffs procedure ( bootstrap_resampling_routine ), pointer :: resample class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( nsamples )) then ns = nsamples else ns = 1000 end if if ( present ( alpha )) then alph = alpha else alph = p05 end if if ( present ( method )) then resample => method else resample => scaled_random_resample end if n = size ( x ) nparams = size ( params ) ! Compute the fit call nonlinear_least_squares ( fun , x , y , params , ymod , resid , & weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info , err = err ) ! Memory Allocations if ( present ( bscoeffs )) then allocate ( bscoeffs ( nparams , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , flag ) return end if allcoeffs => bscoeffs else allocate ( coeffstorage ( nparams , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , flag ) return end if allcoeffs => coeffstorage end if allcoeffs (:, 1 ) = params ! Define initial guesses for each step. Base upon the results of the ! initial analysis as this should provide a strong starting point for ! subsequent analysis do i = 1 , nparams allcoeffs ( i ,:) = params ( i ) end do ! Cycle over each data set and perform the fit #ifdef USEOPENMP !$OMP PARALLEL DO PRIVATE(fLocal, yLocal, rLocal) do i = 2 , ns ! Allocate local arrays on a per-thread basis if (. not . allocated ( fLocal )) allocate ( fLocal ( n )) if (. not . allocated ( yLocal )) allocate ( yLocal ( n )) if (. not . allocated ( rLocal )) allocate ( rLocal ( n )) ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call nonlinear_least_squares ( fun , x , yLocal , allcoeffs (:, i ), fLocal , & rLocal , weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( fLocal ( n ), yLocal ( n ), rLocal ( n )) do i = 2 , ns ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call nonlinear_least_squares ( fun , x , yLocal , allcoeffs (:, i ), fLocal , & rLocal , weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info ) end do #endif ! Perform the statistics calculations, if needed if ( present ( stats )) then ! Verify the size of stats if ( size ( stats ) /= nparams ) then call report_array_size_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , \"stats\" , & nparams , size ( stats )) return end if ! Perform the calculations call compute_stats ( params , allcoeffs , alph , . true ., stats ) end if ! Compute the bias for each parameter, if needed if ( present ( bias )) then ! Verify the size of the array if ( size ( bias ) /= nparams ) then call report_array_size_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , \"bias\" , & nparams , size ( bias )) return end if ! Perform the calculations do i = 1 , nparams bias ( i ) = mean ( allcoeffs ( i ,:)) - params ( i ) end do end if end subroutine ! ****************************************************************************** ! PRIVATE HELPER ROUTINES ! ------------------------------------------------------------------------------ subroutine compute_stats ( mdl , coeffs , alpha , intercept , stats ) ! Arguments real ( real64 ), intent ( in ), dimension (:) :: mdl real ( real64 ), intent ( inout ), dimension (:,:) :: coeffs real ( real64 ), intent ( in ) :: alpha logical , intent ( in ) :: intercept type ( bootstrap_regression_statistics ), intent ( out ), dimension (:) :: stats ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: i , j , i1 , i2 , ncoeffs , nc , nsamples real ( real64 ) :: ms type ( t_distribution ) :: dist ! Initialization ncoeffs = size ( coeffs , 1 ) nsamples = size ( coeffs , 2 ) nc = ncoeffs if (. not . intercept ) nc = ncoeffs - 1 i1 = floor ( half * alpha * nsamples , int32 ) i2 = nsamples - i1 + 1 dist % dof = real ( nsamples - nc ) ! Process j = 1 if ( intercept ) j = 0 do i = 1 , nc j = j + 1 ms = trimmed_mean ( coeffs ( j ,:), p = half * alpha ) ! As we have a distribution of mean values, the standard deviation ! of this population yields the standard error estimate for the ! overall problem stats ( i )% standard_error = standard_deviation ( coeffs ( j ,:)) ! As before, this is a distribution of mean values. The CI can ! be directly estimated by considering the values of the bottom ! alpha/2 and top alpha/2 terms. stats ( i )% upper_confidence_interval = coeffs ( j , i2 ) stats ( i )% lower_confidence_interval = coeffs ( j , i1 ) ! Compute the remaining parameters stats ( i )% t_statistic = mdl ( j ) / stats ( i )% standard_error stats ( i )% probability = regularized_beta ( half * dist % dof , half , & dist % dof / ( dist % dof + ( stats ( i )% t_statistic ) ** 2 )) end do end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_bootstrap.f90.html"},{"title":"fstats_descriptive_statistics.f90 – FSTATS","text":"Source Code module fstats_descriptive_statistics use iso_fortran_env use linalg , only : sort use ferror use fstats_errors implicit none private public :: mean public :: variance public :: standard_deviation public :: median public :: quantile public :: trimmed_mean public :: covariance contains ! ------------------------------------------------------------------------------ pure function mean ( x ) result ( rst ) !! Computes the mean of the values in an array. real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 ! Local Variables integer ( int32 ) :: i , n ! Process n = size ( x ) if ( n == 0 ) then rst = zero else rst = x ( 1 ) do i = 2 , n rst = rst + ( x ( i ) - rst ) / i end do end if end function ! ------------------------------------------------------------------------------ pure function variance ( x ) result ( rst ) !! Computes the sample variance of the values in an array. !! !! The variance computed is the sample variance such that !! s^2 = \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right)^2}{n - 1} . real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: oldMean , newMean ! Process n = size ( x ) if ( n <= 1 ) then rst = zero else oldMean = x ( 1 ) rst = zero do i = 2 , n newMean = oldMean + ( x ( i ) - oldMean ) / i rst = rst + ( x ( i ) - oldMean ) * ( x ( i ) - newMean ) oldMean = newMean end do rst = rst / ( n - one ) end if end function ! ------------------------------------------------------------------------------ pure function standard_deviation ( x ) result ( rst ) !! Computes the sample standard deviation of the values in an array. !! !! The value computed is the sample standard deviation. !! s = \\sqrt{ \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right)^2}{n - 1} } real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst !! The result. ! Process rst = sqrt ( variance ( x )) end function ! ------------------------------------------------------------------------------ function median ( x ) result ( rst ) !! Computes the median of the values in an array. real ( real64 ), intent ( inout ) :: x (:) !! The array of values to analyze. On output, this array is sorted into !! ascending order. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: n , nmid , nmidp1 , flag , iflag ! Initialization n = size ( x ) nmid = n / 2 nmidp1 = nmid + 1 iflag = n - 2 * nmid ! Sort the array in ascending order call sort ( x , . true .) ! Find the median if ( iflag == 0 ) then rst = half * ( x ( nmid ) + x ( nmidp1 )) else rst = x ( nmidp1 ) end if end function ! ------------------------------------------------------------------------------ ! REF: https://fortranwiki.org/fortran/show/Quartiles ! ! This is the method used by Minitab pure function quantile ( x , q ) result ( rst ) !! Computes the specified quantile of a data set using the SAS !! Method 4. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Quantile) real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the data. real ( real64 ), intent ( in ) :: q !! The quantile to compute (e.g. 0.25 computes the 25% quantile). real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Local Variables real ( real64 ) :: a , b , c , tol integer ( int32 ) :: n , ib ! Initialization tol = sqrt ( epsilon ( tol )) n = size ( x ) ! Process a = ( n + one ) * q b = mod ( a , one ) c = a - b ib = int ( c , int32 ) if (( ib + 1 ) > n ) then rst = ( one - b ) * x ( ib ) + b * x ( n ) else rst = ( one - b ) * x ( ib ) + b * x ( ib + 1 ) end if end function ! ------------------------------------------------------------------------------ function trimmed_mean ( x , p ) result ( rst ) !! Computes the trimmed mean of a data set. real ( real64 ), intent ( inout ), dimension (:) :: x !! An N-element array containing the data. On output, the !! array is sorted into ascending order. real ( real64 ), intent ( in ), optional :: p !! An optional parameter specifying the percentage of values !! from either end of the distribution to remove. The default !! is 0.05 such that the bottom 5% and top 5% are removed. real ( real64 ) :: rst !! The trimmed mean. ! Local Variables integer ( int32 ) :: i1 , i2 , n real ( real64 ) :: pv ! Initialization if ( present ( p )) then pv = abs ( p ) else pv = 0.05d0 end if ! Sort the array into ascending order call sort ( x , . true .) ! Find the limiting indices n = size ( x ) i1 = max ( floor ( n * pv , int32 ), 1 ) i2 = min ( n , n - i1 + 1 ) rst = mean ( x ( i1 : i2 )) end function ! ------------------------------------------------------------------------------ pure function covariance ( x , y ) result ( rst ) !! Computes the sample covariance of two data sets. !! !! The covariance computed is the sample covariance such that !! q_{jk} = \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right) !! \\left( y_{i} - \\bar{y} \\right)}{n - 1} . real ( real64 ), intent ( in ), dimension (:) :: x !! The first N-element data set. real ( real64 ), intent ( in ), dimension ( size ( x )) :: y !! The second N-element data set. real ( real64 ) :: rst !! The covariance. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: meanX , meanY ! Process n = size ( x ) if ( n <= 1 ) then rst = zero else ! Compute the means meanX = x ( 1 ) meanY = y ( 1 ) do i = 2 , n meanX = meanX + ( x ( i ) - meanX ) / i meanY = meanY + ( y ( i ) - meanY ) / i end do ! Compute the covariance rst = sum (( x - meanX ) * ( y - meanY )) / ( n - one ) end if end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_descriptive_statistics.f90.html"},{"title":"fstats_distributions.f90 – FSTATS","text":"Source Code module fstats_distributions use iso_fortran_env use ieee_arithmetic use fstats_special_functions use fstats_helper_routines implicit none private public :: distribution public :: distribution_function public :: distribution_property public :: t_distribution public :: normal_distribution public :: f_distribution public :: chi_squared_distribution public :: binomial_distribution real ( real64 ), parameter :: pi = 2.0d0 * acos ( 0.0d0 ) type , abstract :: distribution !! Defines a probability distribution. contains procedure ( distribution_function ), deferred , pass :: pdf !! Computes the probability density function. procedure ( distribution_function ), deferred , pass :: cdf !! Computes the cumulative distribution function. procedure ( distribution_property ), deferred , pass :: mean !! Computes the mean of the distribution. procedure ( distribution_property ), deferred , pass :: median !! Computes the median of the distribution. procedure ( distribution_property ), deferred , pass :: mode !! Computes the mode of the distribution. procedure ( distribution_property ), deferred , pass :: variance !! Computes the variance of the distribution. end type interface pure elemental function distribution_function ( this , x ) result ( rst ) !! Defines the interface for a probability distribution function. use iso_fortran_env , only : real64 import distribution class ( distribution ), intent ( in ) :: this !! The distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. end function pure function distribution_property ( this ) result ( rst ) !! Computes the value of a distribution property. use iso_fortran_env , only : real64 import distribution class ( distribution ), intent ( in ) :: this !! The distribution object. real ( real64 ) :: rst !! The property value. end function end interface ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: t_distribution !! Defines Student's T-Distribution. real ( real64 ) :: dof !! The number of degrees of freedom. contains procedure , public :: pdf => td_pdf procedure , public :: cdf => td_cdf procedure , public :: mean => td_mean procedure , public :: median => td_median procedure , public :: mode => td_mode procedure , public :: variance => td_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: normal_distribution !! Defines a normal distribution. real ( real64 ) :: standard_deviation !! The standard deviation of the distribution. real ( real64 ) :: mean_value !! The mean value of the distribution. contains procedure , public :: pdf => nd_pdf procedure , public :: cdf => nd_cdf procedure , public :: mean => nd_mean procedure , public :: median => nd_median procedure , public :: mode => nd_mode procedure , public :: variance => nd_variance procedure , public :: standardize => nd_standardize end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: f_distribution !! Defines an F-distribution. real ( real64 ) :: d1 !! The measure of degrees of freedom for the first data set. real ( real64 ) :: d2 !! The measure of degrees of freedom for the second data set. contains procedure , public :: pdf => fd_pdf procedure , public :: cdf => fd_cdf procedure , public :: mean => fd_mean procedure , public :: median => fd_median procedure , public :: mode => fd_mode procedure , public :: variance => fd_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: chi_squared_distribution !! Defines a Chi-squared distribution. integer ( int32 ) :: dof !! The number of degrees of freedom. contains procedure , public :: pdf => cs_pdf procedure , public :: cdf => cs_cdf procedure , public :: mean => cs_mean procedure , public :: median => cs_median procedure , public :: mode => cs_mode procedure , public :: variance => cs_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: binomial_distribution !! Defines a binomial distribution. The binomial distribution describes !! the probability p of getting k successes in n independent trials. integer ( int32 ) :: n !! The number of independent trials. real ( real64 ) :: p !! The success probability for each trial. This parameter must !! exist on the set [0, 1]. contains procedure , public :: pdf => bd_pdf procedure , public :: cdf => bd_cdf procedure , public :: mean => bd_mean procedure , public :: median => bd_median procedure , public :: mode => bd_mode procedure , public :: variance => bd_variance end type ! ------------------------------------------------------------------------------ contains ! ****************************************************************************** ! STUDENT'S T-DISTRIBUTION ! ------------------------------------------------------------------------------ ! REF: https://en.wikipedia.org/wiki/Student%27s_t-distribution pure elemental function td_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for Student's T-Distribution is given as !! f(t) = \\frac{ \\Gamma \\left( \\frac{\\nu + 1}{2} \\right) } !! { \\sqrt{\\nu \\pi} \\Gamma \\left( \\frac{\\nu}{2} \\right) } !! \\left( 1 + \\frac{t^2}{\\nu} \\right)^{-(\\nu + 1) / 2} . class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process rst = gamma (( this % dof + 1.0d0 ) / 2.0d0 ) / & ( sqrt ( this % dof * pi ) * gamma ( this % dof / 2.0d0 )) * & ( 1.0d0 + x ** 2 / this % dof ) ** ( - 0.5d0 * ( 1.0d0 + this % dof )) end function ! ------------------------------------------------------------------------------ pure elemental function td_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for Student's T-Distribution is given as !! F(t) = \\int_{-\\infty}^{t} f(u) \\,du = 1 - \\frac{1}{2} I_{x(t)} !! \\left( \\frac{\\nu}{2}, \\frac{1}{2} \\right) !! where x(t) = \\frac{\\nu}{\\nu + t^2} . class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: t t = this % dof / ( this % dof + x ** 2 ) rst = 1.0d0 - 0.5d0 * regularized_beta ( 0.5d0 * this % dof , 0.5d0 , t ) if ( x < 0 ) rst = 1.0d0 - rst end function ! ------------------------------------------------------------------------------ pure function td_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The mean. ! Process if ( this % dof < 1.0d0 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) else rst = 0.0d0 end if end function ! ------------------------------------------------------------------------------ pure function td_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst ! Process rst = 0.0d0 end function ! ------------------------------------------------------------------------------ pure function td_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The mode. ! Process rst = 0.0d0 end function ! ------------------------------------------------------------------------------ pure function td_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The variance. ! Process if ( this % dof <= 1.0d0 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) else if ( this % dof > 1.0d0 . and . this % dof <= 2.0d0 ) then rst = ieee_value ( rst , IEEE_POSITIVE_INF ) else rst = this % dof / ( this % dof - 2.0d0 ) end if end function ! ****************************************************************************** ! NORMAL DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function nd_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a normal distribution is given as !! f(x) = \\frac{1}{\\sigma \\sqrt{2 \\pi}} \\exp \\left(-\\frac{1}{2} !! \\left( \\frac{x - \\mu}{\\sigma} \\right)^2 \\right) . class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. rst = exp ( - 0.5d0 * (( x - this % mean_value ) / this % standard_deviation ) ** 2 ) / & ( this % standard_deviation * sqrt ( 2.0d0 * pi )) end function ! ------------------------------------------------------------------------------ pure elemental function nd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a normal distribution is given as !! F(x) = \\frac{1}{2} \\left( 1 + erf \\left( \\frac{x - \\mu} !! {\\sigma \\sqrt{2}} \\right) \\right) . class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. rst = 0.5d0 * ( 1.0d0 + erf (( x - this % mean_value ) / & ( this % standard_deviation * sqrt ( 2.0d0 )))) end function ! ------------------------------------------------------------------------------ pure function nd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The mean rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The median. rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The mode. rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The variance. rst = this % standard_deviation ** 2 end function ! ------------------------------------------------------------------------------ subroutine nd_standardize ( this ) !! Standardizes the normal distribution to a mean of 0 and a !! standard deviation of 1. class ( normal_distribution ), intent ( inout ) :: this !! The normal_distribution object. this % mean_value = 0.0d0 this % standard_deviation = 1.0d0 end subroutine ! ****************************************************************************** ! F DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function fd_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a F distribution is given as !! f(x) = !! \\sqrt{ \\frac{ (d_1 x)^{d_1} d_{2}^{d_2} }{ (d_1 x + d_2)^{d_1 + d_2} } } !! \\frac{1}{x \\beta \\left( \\frac{d_1}{2}, \\frac{d_2}{2} \\right) } . class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 rst = ( 1.0d0 / beta ( 0.5d0 * d1 , 0.5d0 * d2 )) * ( d1 / d2 ) ** ( 0.5d0 * d1 ) * & x ** ( 0.5d0 * d1 - 1.0d0 ) * ( 1.0d0 + d1 * x / d2 ) ** ( - 0.5d0 * ( d1 + d2 )) end function ! ------------------------------------------------------------------------------ pure elemental function fd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a F distribution is given as !! F(x) = I_{d_1 x/(d_1 x + d_2)} \\left( \\frac{d_1}{2}, !! \\frac{d_2}{2} \\right) . class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 rst = regularized_beta ( 0.5d0 * d1 , 0.5d0 * d2 , d1 * x / ( d1 * x + d2 )) end function ! ------------------------------------------------------------------------------ pure function fd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The mean. ! Process if ( this % d2 > 2.0d0 ) then rst = this % d2 / ( this % d2 - 2.0d0 ) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ------------------------------------------------------------------------------ pure function fd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The median. rst = ieee_value ( rst , IEEE_QUIET_NAN ) end function ! ------------------------------------------------------------------------------ pure function fd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The mode. ! Process if ( this % d1 > 2.0d0 ) then rst = (( this % d1 - 2.0d0 ) / this % d1 ) * ( this % d2 / ( this % d2 + 2.0d0 )) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ------------------------------------------------------------------------------ pure function fd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The variance. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 if ( d2 > 4.0d0 ) then rst = ( 2.0d0 * d2 ** 2 * ( d1 + d2 - 2.0d0 )) / & ( d1 * ( d2 - 2.0d0 ) ** 2 * ( d2 - 4.0d0 )) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ****************************************************************************** ! CHI-SQUARED DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function cs_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a Chi-squared distribution is given as !! f(x) = \\frac{x^{k/2 - 1} \\exp{-x / 2}} {2^{k / 2} !! \\Gamma \\left( \\frac{k}{2} \\right)} . class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: arg ! Process arg = 0.5d0 * this % dof rst = 1.0d0 / ( 2.0d0 ** arg * gamma ( arg )) * x ** ( arg - 1.0d0 ) * exp ( - 0.5d0 * x ) end function ! ------------------------------------------------------------------------------ pure elemental function cs_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a Chi-squared distribution is given as !! F(x) = \\frac{ \\gamma \\left( \\frac{k}{2}, \\frac{x}{2} \\right) } !! { \\Gamma \\left( \\frac{k}{2} \\right)} . class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: arg ! Process arg = 0.5d0 * this % dof rst = incomplete_gamma_lower ( arg , 0.5d0 * x ) / gamma ( arg ) end function ! ------------------------------------------------------------------------------ pure function cs_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The mean. ! Process rst = real ( this % dof , real64 ) end function ! ------------------------------------------------------------------------------ pure function cs_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The median. ! Process rst = this % dof * ( 1.0d0 - 2.0d0 / ( 9.0d0 * this % dof )) ** 3 end function ! ------------------------------------------------------------------------------ pure function cs_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The mode. ! Process rst = max ( this % dof - 2.0d0 , 0.0d0 ) end function ! ------------------------------------------------------------------------------ pure function cs_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The variance. ! Process rst = 2.0d0 * this % dof end function ! ****************************************************************************** ! BINOMIAL DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function bd_pdf ( this , x ) result ( rst ) !! Computes the probability mass function. !! !! The PMF for a binomial distribution is given as !! f(k,n,p) = \\frac{n!}{k! \\left( n - k! \\right)} p^k !! \\left( 1 - p \\right)^{n-k} . class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. This parameter !! is the number k successes in the n independent trials. As !! such, this parameter must exist on the set [0, n]. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: dn ! Process dn = real ( this % n , real64 ) rst = ( factorial ( dn ) / ( factorial ( x ) * factorial ( dn - x ))) * ( this % p ** x ) * ( 1.0d0 - this % p ) ** ( dn - x ) end function ! ------------------------------------------------------------------------------ pure elemental function bd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution funtion. !! !! The CDF for a binomial distribution is given as !! F(k,n,p) = I_{1-p} \\left( n - k, 1 + k \\right) , which is simply !! the regularized incomplete beta function. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. This parameter !! is the number k successes in the n independent trials. As !! such, this parameter must exist on the set [0, n]. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: dn ! Process dn = real ( this % n , real64 ) rst = regularized_beta ( dn - x , x + 1.0d0 , 1.0d0 - this % p ) end function ! ------------------------------------------------------------------------------ pure function bd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The mean. rst = real ( this % n * this % p , real64 ) end function ! ------------------------------------------------------------------------------ pure function bd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The median. rst = real ( this % n * this % p , real64 ) end function ! ------------------------------------------------------------------------------ pure function bd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The mode. rst = ( this % n + 1.0d0 ) * this % p end function ! ------------------------------------------------------------------------------ pure function bd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The variance. rst = this % n * this % p * ( 1.0d0 - this % p ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_distributions.f90.html"},{"title":"fstats_sampling.f90 – FSTATS","text":"Source Code module fstats_sampling use iso_fortran_env use linalg , only : sort use fstats_distributions implicit none private public :: box_muller_sample public :: rejection_sample real ( real64 ), parameter :: pi = 2.0d0 * acos ( 0.0d0 ) real ( real64 ), parameter :: twopi = 2.0d0 * pi real ( real64 ), parameter :: pi_f = 2.0 * acos ( 0.0 ) real ( real64 ), parameter :: twopi_f = 2.0 * pi_f interface box_muller_sample !! Generates random, normally distributed values via the Box-Muller !! transform. module procedure :: box_muller_sample_scalar module procedure :: box_muller_array end interface contains ! ------------------------------------------------------------------------------ function box_muller_sample_scalar ( mu , sigma ) result ( rst ) !! Generates a pair of independent, standard, normally distributed !! random values using the Box-Muller transform. real ( real64 ), intent ( in ) :: mu !! The mean of the distribution. real ( real64 ), intent ( in ) :: sigma !! The standard deviation of the distribution. real ( real64 ) :: rst ( 2 ) !! The pair of random values. ! Parameters complex ( real64 ), parameter :: j = ( 0.0d0 , 1.0d0 ) ! Local Variables real ( real64 ) :: u1 , u2 complex ( real64 ) :: z ! Process call random_number ( u1 ) call random_number ( u2 ) z = sqrt ( - log ( u1 )) * exp ( j * twopi * u2 ) rst = [ real ( z , real64 ), aimag ( z )] end function ! ------------------------------------------------------------------------------ function box_muller_array ( mu , sigma , n ) result ( rst ) !! Generates an array of normally distributed random values sampled !! by the Box-Muller transform. real ( real64 ), intent ( in ) :: mu !! The mean of the distribution. real ( real64 ), intent ( in ) :: sigma !! The standard deviation of the distribution. integer ( int32 ), intent ( in ) :: n !! The number of Box-Muller pairs to generate. real ( real64 ), allocatable , dimension (:) :: rst !! A 2N-element array containing the N Box-Muller pairs. ! Local Variables integer ( int32 ) :: i ! Process if ( n < 1 ) then allocate ( rst ( 0 )) return end if allocate ( rst ( 2 * n )) do i = 1 , n rst ( 2 * i - 1 : 2 * i ) = box_muller_sample ( mu , sigma ) end do end function ! ****************************************************************************** ! REJECTION SAMPLING ! ------------------------------------------------------------------------------ function rejection_sample ( tdist , n , xmin , xmax ) result ( rst ) !! Uses rejection sampling to randomly sample a target distribution. class ( distribution ), intent ( in ) :: tdist !! The distribution to sample integer ( int32 ), intent ( in ) :: n !! The number of samples to make. real ( real64 ), intent ( in ) :: xmin !! The minimum range to explore. real ( real64 ), intent ( in ) :: xmax !! The maximum range to explore. real ( real64 ), allocatable , dimension (:) :: rst !! An N-element array containing the N samples from the !! distribution. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: c_start = 1.01d0 ! Local Variables integer ( int32 ) :: i , j , jmax real ( real64 ) :: u , c , g , f , rng ! Quick Return if ( n < 1 ) then allocate ( rst ( 0 ), source = zero ) end if ! Process i = 0 j = 0 jmax = min ( 1000 * n , huge ( j )) ! Guard against insanity rng = xmax - xmin c = c_start allocate ( rst ( n ), source = zero ) do while ( i <= n ) ! Update the acceptance threshold call random_number ( u ) ! Sample from the proposal distribution call random_number ( g ) g = g * rng + xmin ! Sample the target distribution f = tdist % pdf ( g ) ! Test if ( u <= f / ( c * g )) then i = i + 1 rst ( i ) = g end if ! Update C c = max ( c , f / g ) ! Update the infinite loop guard variable j = j + 1 if ( j == jmax ) exit end do end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_sampling.f90.html"},{"title":"fstats_special_functions.f90 – FSTATS","text":"Source Code module fstats_special_functions use iso_fortran_env use ieee_arithmetic implicit none private public :: beta public :: regularized_beta public :: incomplete_beta public :: incomplete_gamma_lower public :: incomplete_gamma_upper public :: digamma contains ! ------------------------------------------------------------------------------ pure elemental function beta ( a , b ) result ( rst ) !! Computes the beta function. !! !! The beta function is related to the gamma function !! by the following relationship. !! \\beta(a,b) = \\frac{\\Gamma(a) \\Gamma(b)}{\\Gamma(a + b)} . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ) :: rst !! The value of the beta function at a and b . ! Process ! REF: https://en.wikipedia.org/wiki/Beta_function rst = exp ( log_gamma ( a ) + log_gamma ( b ) - log_gamma ( a + b )) end function ! ------------------------------------------------------------------------------ ! source: https://people.math.sc.edu/Burkardt/f_src/special_functions/special_functions.f90 pure elemental function regularized_beta ( a , b , x ) result ( rst ) !! Computes the regularized beta function. !! !! The regularized beta function is defined as the ratio between !! the incomplete beta function and the beta function. !! I_{x}(a,b) = \\frac{\\beta(x;a,b)}{\\beta(a,b)} . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ), intent ( in ) :: x !! The upper limit of the integration. real ( real64 ) :: rst !! The value of the regularized beta function. ! Local Variables real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 real ( real64 ) :: bt , dk ( 51 ), fk ( 51 ), s0 , t1 , t2 , ta , tb integer ( int32 ) :: k ! Process s0 = ( a + one ) / ( a + b + two ) bt = beta ( a , b ) if ( x <= s0 ) then do k = 1 , 20 dk ( 2 * k ) = k * ( b - k ) * x / ( a + two * k - one ) / ( a + two * k ) end do do k = 0 , 20 dk ( 2 * k + 1 ) = - ( a + k ) * ( a + b + k ) * x / ( a + two * k ) / & ( a + two * k + one ) end do t1 = zero do k = 20 , 1 , - 1 t1 = dk ( k ) / ( one + t1 ) end do ta = one / ( one + t1 ) rst = x ** a * ( one - x ) ** b / ( a * bt ) * ta else do k = 1 , 20 fk ( 2 * k ) = k * ( a - k ) * ( one - x ) / ( b + two * k - one ) / & ( b + two * k ) end do do k = 0 , 20 fk ( 2 * k + 1 ) = - ( b + k ) * ( a + b + k ) * ( one - x ) / ( b + two * k ) / & ( b + two * k + one ) end do t2 = zero do k = 20 , 1 , - 1 t2 = fk ( k ) / ( one + t2 ) end do tb = one / ( one + t2 ) rst = one - x ** a * ( one - x ) ** b / ( b * bt ) * tb end if end function ! ------------------------------------------------------------------------------ pure elemental function incomplete_beta ( a , b , x ) result ( rst ) !! Computes the incomplete beta function. !! !! The incomplete beta function is defind as: !! \\beta(x;a,b) = \\int_{0}^{x} t^{a-1} (1 - t)^{b-1} dt . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ), intent ( in ) :: x !! The upper limit of the integration. real ( real64 ) :: rst !! The value of the incomplete beta function. ! Process rst = beta ( a , b ) * regularized_beta ( a , b , x ) end function ! ------------------------------------------------------------------------------ ! REF: https://people.math.sc.edu/Burkardt/f_src/special_functions/special_functions.f90 pure elemental function incomplete_gamma_upper ( a , x ) result ( rst ) !! Computes the upper incomplete gamma function. !! !! The upper incomplete gamma function is defined as: !! \\Gamma(a, x) = \\int_{x}^{\\infty} t^{a-1} e^{-t} \\,dt !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Incomplete_gamma_function) real ( real64 ), intent ( in ) :: a !! The coefficient value. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: ten = 1.0d1 ! Local Variables real ( real64 ) :: ga , gin , gip , r , s , t0 , xam , small integer ( int32 ) :: k ! Process small = ten * epsilon ( small ) xam = - x + a * log ( x ) if ( xam > 7.0d2 . or . a > 1.7d2 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) return end if if ( x == zero ) then rst = gamma ( a ) else if ( x <= one + a ) then s = one / a r = s do k = 1 , 60 r = r * x / ( a + k ) s = s + r if ( abs ( r / s ) < small ) then exit end if end do gin = exp ( xam ) * s ga = gamma ( a ) gip = gin / ga rst = ga - gin else if ( one + a < x ) then t0 = zero do k = 60 , 1 , - 1 t0 = ( k - a ) / ( one + k / ( x + t0 )) end do rst = exp ( xam ) / ( x + t0 ) end if end function ! ------------------------------------------------------------------------------ pure elemental function incomplete_gamma_lower ( a , x ) result ( rst ) !! Computes the lower incomplete gamma function. !! !! The lower incomplete gamma function is defined as: !! \\gamma(a, x) = \\int_{0}^{x} t^{a-1} e^{-t} \\,dt !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Incomplete_gamma_function) real ( real64 ), intent ( in ) :: a !! The coefficient value. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: ten = 1.0d1 ! Local Variables real ( real64 ) :: ga , gim , r , s , t0 , xam , small integer ( int32 ) :: k ! Process small = ten * epsilon ( small ) xam = - x + a * log ( x ) if ( xam > 7.0d2 . or . a > 1.7d2 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) return end if if ( x == zero ) then rst = 0.0d0 else if ( x <= one + a ) then s = one / a r = s do k = 1 , 60 r = r * x / ( a + k ) s = s + r if ( abs ( r / s ) < small ) then exit end if end do rst = exp ( xam ) * s else if ( one + a < x ) then t0 = zero do k = 60 , 1 , - 1 t0 = ( k - a ) / ( one + k / ( x + t0 )) end do gim = exp ( xam ) / ( x + t0 ) ga = gamma ( a ) rst = ga - gim end if end function ! ------------------------------------------------------------------------------ pure elemental function digamma ( x ) result ( rst ) !! Computes the digamma function. !! !! The digamma function is defined as: !! \\psi(x) = !! \\frac{d}{dx}\\left( \\ln \\left( \\Gamma \\left( x \\right) \\right) !! \\right) !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Digamma_function) real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: c = 8.5d0 real ( real64 ), parameter :: euler_mascheroni = 0.57721566490153286060d0 ! Local Variables real ( real64 ) :: r , x2 , nan ! REF: ! - https://people.sc.fsu.edu/~jburkardt/f_src/asa103/asa103.f90 ! If x <= 0.0 if ( x <= 0.0 ) then nan = ieee_value ( nan , IEEE_QUIET_NAN ) rst = nan return end if ! Approximation for a small argument if ( x <= 1.0d-6 ) then rst = - euler_mascheroni - 1.0d0 / x + 1.6449340668482264365d0 * x return end if ! Process rst = 0.0d0 x2 = x do while ( x2 < c ) rst = rst - 1.0d0 / x2 x2 = x2 + 1.0d0 end do r = 1.0d0 / x2 rst = rst + log ( x2 ) - 0.5d0 * r r = r * r rst = rst & - r * ( 1.0d0 / 1 2.0d0 & - r * ( 1.0d0 / 12 0.0d0 & - r * ( 1.0d0 / 25 2.0d0 & - r * ( 1.0d0 / 24 0.0d0 & - r * ( 1.0d0 / 13 2.0d0 ) & )))) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_special_functions.f90.html"},{"title":"fstats_regression.f90 – FSTATS","text":"Source Code module fstats_regression use iso_fortran_env use linalg use fstats_errors use blas use ferror use fstats_descriptive_statistics use fstats_distributions use fstats_special_functions use fstats_hypothesis implicit none private public :: iteration_controls public :: convergence_info public :: lm_solver_options public :: regression_function public :: iteration_update public :: regression_statistics public :: r_squared public :: adjusted_r_squared public :: correlation public :: coefficient_matrix public :: covariance_matrix public :: linear_least_squares public :: calculate_regression_statistics public :: jacobian public :: nonlinear_least_squares public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE ! ****************************************************************************** ! CONSTANTS ! ------------------------------------------------------------------------------ integer ( int32 ), parameter :: FS_LEVENBERG_MARQUARDT_UPDATE = 1 integer ( int32 ), parameter :: FS_QUADRATIC_UPDATE = 2 integer ( int32 ), parameter :: FS_NIELSEN_UPDATE = 3 ! ****************************************************************************** ! TYPES ! ------------------------------------------------------------------------------ type regression_statistics !! A container for regression-related statistical information. real ( real64 ) :: standard_error !! The standard error for the model coefficient. !! !! E_{s}(\\beta_{i}) = \\sqrt{\\sigma^{2} C_{ii}} real ( real64 ) :: t_statistic !! The T-statistic for the model coefficient. !! !! t_o = \\frac{ \\beta_{i} }{E_{s}(\\beta_{i})} real ( real64 ) :: probability !! The probability that the coefficient is not statistically !! important. A statistically important coefficient will have a !! low probability (p-value), typically 0.05 or lower; however, a !! p-value of up to ~0.2 may be acceptable dependent upon the !! problem. Typically any p-value larger than ~0.2 indicates the !! parameter is not statistically important for the model. !! !! p = t_{|t_o|, df_{residual}} real ( real64 ) :: confidence_interval !! The confidence interval for the parameter at the level !! determined by the regression process. !! !! c = t_{\\alpha, df} E_{s}(\\beta_{i}) end type type iteration_controls !! Provides a collection of iteration control parameters. integer ( int32 ) :: max_iteration_count !! Defines the maximum number of iterations allowed. integer ( int32 ) :: max_function_evaluations !! Defines the maximum number of function evaluations allowed. real ( real64 ) :: gradient_tolerance !! Defines a tolerance on the gradient of the fitted function. real ( real64 ) :: change_in_solution_tolerance !! Defines a tolerance on the change in parameter values. real ( real64 ) :: residual_tolerance !! Defines a tolerance on the metric associated with the residual !! error. real ( real64 ) :: iteration_improvement_tolerance !! Defines a tolerance to ensure adequate improvement on each !! iteration. integer ( int32 ) :: max_iteration_between_updates !! Defines how many iterations can pass before a re-evaluation of !! the Jacobian matrix is forced. contains procedure , public :: set_to_default => lm_set_default_tolerances end type type convergence_info !! Provides information regarding convergence status. logical :: converge_on_gradient !! True if convergence on the gradient was achieved; else, false. real ( real64 ) :: gradient_value !! The value of the gradient test parameter. logical :: converge_on_solution_change !! True if convergence on the change in solution was achieved; else, !! false. real ( real64 ) :: solution_change_value !! The value of the change in solution parameter. logical :: converge_on_residual_parameter !! True if convergence on the residual error parameter was achieved; !! else, false. real ( real64 ) :: residual_value !! The value of the residual error parameter. logical :: reach_iteration_limit !! True if the solution did not converge in the allowed number of !! iterations. integer ( int32 ) :: iteration_count !! The iteration count. logical :: reach_function_evaluation_limit !! True if the solution did not converge in the allowed number of !! function evaluations. integer ( int32 ) :: function_evaluation_count !! The function evaluation count. logical :: user_requested_stop !! True if the user requested the stop; else, false. end type type lm_solver_options !! Options to control the Levenberg-Marquardt solver. integer ( int32 ) :: method !! The solver method to utilize. !! - FS_LEVENBERG_MARQUARDT_UPDATE: !! - FS_QUADRATIC_UPDATE: !! - FS_NIELSEN_UDPATE: real ( real64 ) :: finite_difference_step_size !! The step size used for the finite difference calculations of the !! Jacobian matrix. real ( real64 ) :: damping_increase_factor !! The factor to use when increasing the damping parameter. real ( real64 ) :: damping_decrease_factor !! The factor to use when decreasing the damping parameter. contains procedure , public :: set_to_default => lm_set_default_settings end type interface subroutine regression_function ( xdata , params , resid , stop ) use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: xdata , params real ( real64 ), intent ( out ), dimension (:) :: resid logical , intent ( out ) :: stop end subroutine subroutine iteration_update ( iter , funvals , resid , params , step ) use iso_fortran_env , only : int32 , real64 integer ( int32 ), intent ( in ) :: iter real ( real64 ), intent ( in ) :: funvals (:), resid (:), params (:), step (:) end subroutine end interface contains ! ------------------------------------------------------------------------------ function r_squared ( x , xm , err ) result ( rst ) !! Computes the R-squared value for a data set. !! !! The R-squared value is computed by determining the sum of the squares !! of the residuals: !! SS_{res} = \\Sigma \\left( y_i - f_i \\right)^2 !! The total sum of the squares: !! SS_{tot} = \\Sigma \\left( y_i - \\bar{y} \\right)^2 . !! The R-squared value is then: !! R^2 = 1 - \\frac{SS_{res}}{SS_{tot}} . !! !! See Also: !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Coefficient_of_determination) real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the dependent variables from !! the data set. real ( real64 ), intent ( in ) :: xm (:) !! An N-element array containing the corresponding modeled !! values. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings !! to the caller. Possible warning and error codes are as !! follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the !! same size. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: esum , vt class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Input Check n = size ( x ) if ( size ( xm ) /= n ) then call report_array_size_error ( errmgr , \"r_squared_real64\" , \"XM\" , n , & size ( xm )) return end if ! Process esum = zero do i = 1 , n esum = esum + ( x ( i ) - xm ( i )) ** 2 end do vt = variance ( x ) * ( n - one ) rst = one - esum / vt end function ! ------------------------------------------------------------------------------ function adjusted_r_squared ( p , x , xm , err ) result ( rst ) !! Computes the adjusted R-squared value for a data set. !! !! The adjusted R-squared provides a mechanism for tempering the effects !! of extra explanatory variables on the traditional R-squared !! calculation. It is computed by noting the sample size n and !! the number of variables p . !! \\bar{R}^2 = 1 - \\left( 1 - R^2 \\right) \\frac{n - 1}{n - p} . !! !! See Also: !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Coefficient_of_determination#Adjusted_R2) integer ( int32 ), intent ( in ) :: p !! The number of variables. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the dependent variables from !! the data set. real ( real64 ), intent ( in ) :: xm (:) !! An N-element array containing the corresponding modeled !! values. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings !! to the caller. Possible warning and error codes are as !! follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the !! same size. real ( real64 ) :: rst !! The result. ! Local Variables integer ( int32 ) :: n real ( real64 ) :: r2 class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n = size ( x ) ! Process r2 = r_squared ( x , xm , errmgr ) if ( errmgr % has_error_occurred ()) return rst = one - ( one - r2 ) * ( n - one ) / ( n - p - one ) end function ! ------------------------------------------------------------------------------ pure function correlation ( x , y ) result ( rst ) !! Computes the sample correlation coefficient (an estimate to the !! population Pearson correlation) as follows. !! !! r_{xy} = \\frac{cov(x, y)}{s_{x} s_{y}} . !! !! Where, s_{x} & s_{y} are the sample standard deviations of !! x and y respectively. real ( real64 ), intent ( in ), dimension (:) :: x !! The first N-element data set. real ( real64 ), intent ( in ), dimension ( size ( x )) :: y !! The second N-element data set. real ( real64 ) :: rst !! The correlation coefficient. ! Process rst = covariance ( x , y ) / ( standard_deviation ( x ) * standard_deviation ( y )) end function ! ------------------------------------------------------------------------------ subroutine coefficient_matrix ( order , intercept , x , c , err ) !! Computes the coefficient matrix X to the linear !! least-squares regression problem of X \\beta = y , where !! X is the coefficient matrix computed here, \\beta is !! the vector of coefficients to be determined, and y is the !! vector of measured dependent variables. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be !! at least one (linear equation), but can be higher as desired. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed !! as part of the regression; else, false. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( out ) :: c (:,:) !! An N-by-K matrix where the results will be written. K !! must equal order + 1 in the event intercept is true; !! however, if intercept is false, K must equal order. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , start , npts , ncols class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x ) ncols = order if ( intercept ) ncols = ncols + 1 ! Input Check if ( order < 1 ) then call errmgr % report_error ( \"coefficient_matrix\" , & \"The model order must be at least one.\" , FS_INVALID_INPUT_ERROR ) return end if if ( size ( c , 1 ) /= npts . or . size ( c , 2 ) /= ncols ) then call report_matrix_size_error ( errmgr , \"coefficient_matrix\" , & \"c\" , npts , ncols , size ( c , 1 ), size ( c , 2 )) return end if ! Process if ( intercept ) then c (:, 1 ) = one c (:, 2 ) = x start = 3 else c (:, 1 ) = x start = 2 end if if ( start >= ncols ) return do i = start , ncols c (:, i ) = c (:, i - 1 ) * x end do end subroutine ! ------------------------------------------------------------------------------ subroutine covariance_matrix ( x , c , err ) !! Computes the covariance matrix C where !! C = \\left( X^{T} X \\right)^{-1} and X is computed !! by coefficient_matrix. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Covariance_matrix) !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) real ( real64 ), intent ( in ) :: x (:,:) !! An M-by-N matrix containing the formatted independent data !! matrix X as computed by coefficient_matrix. real ( real64 ), intent ( out ) :: c (:,:) !! The N-by-N covariance matrix. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not !! sized correctly. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr integer ( int32 ) :: npts , ncoeffs , flag real ( real64 ), allocatable :: xtx (:,:) ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x , 1 ) ncoeffs = size ( x , 2 ) ! Input Checking if ( size ( c , 1 ) /= ncoeffs . or . size ( c , 2 ) /= ncoeffs ) then call report_matrix_size_error ( errmgr , \"covariance_matrix\" , & \"c\" , ncoeffs , ncoeffs , size ( c , 1 ), size ( c , 2 )) return end if ! Local Memory Allocation allocate ( xtx ( ncoeffs , ncoeffs ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"covariance_matrix\" , flag ) return end if ! Compute X**T * X call DGEMM ( \"T\" , \"N\" , ncoeffs , ncoeffs , npts , one , x , npts , x , npts , & zero , xtx , ncoeffs ) ! Compute the inverse of X**T * X to obtain the covariance matrix call mtx_pinverse ( xtx , c , err = errmgr ) if ( errmgr % has_error_occurred ()) return end subroutine ! ------------------------------------------------------------------------------ subroutine linear_least_squares ( order , intercept , x , y , coeffs , & ymod , resid , stats , alpha , err ) !! Computes a linear least-squares regression to fit a set of data. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be at !! least one (linear equation), but can be higher as desired, !! as long as there is sufficient data. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed as part of !! the regression; else, false. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( in ) :: y (:) !! An N-element array containing the dependent variable !! measurement points. real ( real64 ), intent ( out ) :: coeffs (:) !! An ORDER+1 element array where the coefficients will be written. real ( real64 ), intent ( out ) :: ymod (:) !! An N-element array where the modeled data will be written. real ( real64 ), intent ( out ) :: resid (:) !! An N-element array where the residual error data will be !! written (modeled - actual). type ( regression_statistics ), intent ( out ), optional :: stats (:) !! An M-element array of regression_statistics items where !! M = ORDER + 1 when intercept is set to true; however, if !! intercept is set to false, M = ORDER. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , npts , ncols , ncoeffs , flag real ( real64 ) :: alph , var , df , ssr , talpha real ( real64 ), allocatable :: a (:,:), c (:,:), cxt (:,:) type ( t_distribution ) :: dist class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x ) ncoeffs = order + 1 ncols = order if ( intercept ) ncols = ncols + 1 alph = 0.05d0 if ( present ( alpha )) alph = alpha ! Input Check if ( order < 1 ) then call errmgr % report_error ( \"linear_least_squares\" , & \"The model order must be at least one.\" , FS_INVALID_INPUT_ERROR ) return end if if ( size ( y ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"y\" , npts , size ( y )) return end if if ( size ( coeffs ) /= ncoeffs ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"coeffs\" , ncoeffs , size ( coeffs )) return end if if ( size ( ymod ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"ymod\" , npts , size ( ymod )) return end if if ( size ( resid ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"resid\" , npts , size ( resid )) return end if if ( present ( stats )) then if ( size ( stats ) /= ncols ) then call report_array_size_error ( errmgr , & \"linear_least_squares\" , \"stats\" , ncols , size ( stats )) return end if end if ! Memory Allocation allocate ( a ( npts , ncols ), stat = flag ) if ( flag == 0 ) allocate ( c ( ncols , ncols ), stat = flag ) if ( flag == 0 ) allocate ( cxt ( ncols , npts ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"linear_least_squares\" , flag ) return end if ! Compute the coefficient matrix call coefficient_matrix ( order , intercept , x , a , errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the covariance matrix call covariance_matrix ( a , c , errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the coefficients (NCOLS-by-1) call DGEMM ( \"N\" , \"T\" , ncols , npts , ncols , one , c , ncols , a , npts , zero , & cxt , ncols ) ! C * X**T i = 2 coeffs ( 1 ) = zero if ( intercept ) i = 1 call DGEMM ( \"N\" , \"N\" , ncols , 1 , npts , one , cxt , ncols , y , npts , zero , & coeffs ( i :), ncols ) ! (C * X**T) * Y ! Evaluate the model and compute the residuals call DGEMM ( \"N\" , \"N\" , npts , 1 , ncols , one , a , npts , coeffs ( i :), & ncols , zero , ymod , npts ) resid = ymod - y ! If the user doesn't want the statistics calculations we can stop now if (. not . present ( stats )) return ! Start the process of computing statistics stats = calculate_regression_statistics ( resid , coeffs ( i :), c , alph , & errmgr ) end subroutine ! ------------------------------------------------------------------------------ function calculate_regression_statistics ( resid , params , c , alpha , err ) & result ( rst ) !! Computes statistics for the quality of fit for a regression !! model. real ( real64 ), intent ( in ) :: resid (:) !! An M-element array containing the model residual errors. real ( real64 ), intent ( in ) :: params (:) !! An N-element array containing the model parameters. real ( real64 ), intent ( in ) :: c (:,:) !! The N-by-N covariance matrix. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. type ( regression_statistics ), allocatable :: rst (:) !! A regression_statistics object containing the analysis results. ! Parameters real ( real64 ), parameter :: p05 = 0.05d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , m , n , dof , flag real ( real64 ) :: a , ssr , var , talpha type ( t_distribution ) :: dist class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Initialization m = size ( resid ) n = size ( params ) dof = m - n if ( present ( alpha )) then a = alpha else a = p05 end if allocate ( rst ( n ), stat = flag ) if ( flag /= 0 ) then end if ! Input Checking if ( size ( c , 1 ) /= n . or . size ( c , 2 ) /= n ) then end if ! Process ssr = norm2 ( resid ) ** 2 ! sum of the squares of the residual var = ssr / dof dist % dof = real ( dof , real64 ) talpha = confidence_interval ( dist , a , one , 1 ) do i = 1 , n rst ( i )% standard_error = sqrt ( var * c ( i , i )) rst ( i )% t_statistic = params ( i ) / rst ( i )% standard_error rst ( i )% probability = regularized_beta ( & half * dof , & half , & real ( dof , real64 ) / ( dof + ( rst ( i )% t_statistic ) ** 2 ) & ) rst ( i )% confidence_interval = talpha * rst ( i )% standard_error end do end function ! ------------------------------------------------------------------------------ subroutine jacobian ( fun , xdata , params , & jac , stop , f0 , f1 , step , err ) !! Computes the Jacobian matrix for a nonlinear regression problem. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: xdata (:) !! The M-element array containing x-coordinate data. real ( real64 ), intent ( in ) :: params (:) !! The N-element array containing the model parameters. real ( real64 ), intent ( out ) :: jac (:,:) !! The M-by-N matrix where the Jacobian will be written. logical , intent ( out ) :: stop !! A value that the user can set in fun forcing the !! evaluation process to stop prior to completion. real ( real64 ), intent ( in ), optional , target :: f0 (:) !! An optional M-element array containing the model values !! using the current parameters as defined in m. This input !! can be used to prevent the routine from performing a !! function evaluation at the model parameter state defined in !! params. real ( real64 ), intent ( out ), optional , target :: f1 (:) !! An optional M-element workspace array used for function !! evaluations. real ( real64 ), intent ( in ), optional :: step !! The differentiation step size. The default is the square !! root of machine precision. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Local Variables real ( real64 ) :: h integer ( int32 ) :: m , n , flag , expected , actual real ( real64 ), pointer :: f1p (:), f0p (:) real ( real64 ), allocatable , target :: f1a (:), f0a (:), work (:) class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( step )) then h = step else h = sqrt ( epsilon ( h )) end if m = size ( xdata ) n = size ( params ) ! Input Size Checking if ( size ( jac , 1 ) /= m . or . size ( jac , 2 ) /= n ) then call report_matrix_size_error ( errmgr , \"jacobian\" , & \"JAC\" , m , n , size ( jac , 1 ), size ( jac , 2 )) return end if if ( present ( f0 )) then ! Check Size if ( size ( f0 ) /= m ) then call report_array_size_error ( errmgr , \"jacobian\" , & \"F0\" , m , size ( f0 )) return end if f0p ( 1 : m ) => f0 else ! Allocate space, and fill the array with the current function ! results allocate ( f0a ( m ), stat = flag ) if ( flag /= 0 ) go to 20 f0p ( 1 : m ) => f0a call fun ( xdata , params , f0p , stop ) if ( stop ) return end if if ( present ( f1 )) then ! Check Size if ( size ( f1 ) /= m ) then call report_array_size_error ( errmgr , \"jacobian\" , & \"F1\" , m , size ( f1 )) return end if f1p ( 1 : m ) => f1 else ! Allocate space allocate ( f1a ( m ), stat = flag ) if ( flag /= 0 ) go to 20 f1p ( 1 : m ) => f1a end if ! Allocate a workspace array the same size as params allocate ( work ( n ), stat = flag ) if ( flag /= 0 ) go to 20 ! Compute the Jacobian call jacobian_finite_diff ( fun , xdata , params , f0p , jac , f1p , & stop , h , work ) ! End return ! Memroy Allocation Error Handling 20 continue call report_memory_error ( errmgr , \"jacobian\" , flag ) return end subroutine ! ------------------------------------------------------------------------------ subroutine nonlinear_least_squares ( fun , x , y , params , ymod , & resid , weights , maxp , minp , stats , alpha , controls , settings , info , & status , err ) !! Performs a nonlinear regression to fit a model using a version !! of the Levenberg-Marquardt algorithm. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: x (:) !! The M-element array containing independent data. real ( real64 ), intent ( in ) :: y (:) !! The M-element array containing dependent data. real ( real64 ), intent ( inout ) :: params (:) !! On input, the N-element array containing the initial estimate !! of the model parameters. On output, the computed model !! parameters. real ( real64 ), intent ( out ) :: ymod (:) !! An M-element array where the modeled dependent data will !! be written. real ( real64 ), intent ( out ) :: resid (:) !! An M-element array where the model residuals will be !! written. real ( real64 ), intent ( in ), optional , target :: weights (:) !! An optional M-element array allowing the weighting of !! individual points. real ( real64 ), intent ( in ), optional , target :: maxp (:) !! An optional N-element array that can be used as upper limits !! on the parameter values. If no upper limit is requested for !! a particular parameter, utilize a very large value. The !! internal default is to utilize huge() as a value. real ( real64 ), intent ( in ), optional , target :: minp (:) !! An optional N-element array that can be used as lower limits !! on the parameter values. If no lower limit is requested for !! a particalar parameter, utilize a very large magnitude, but !! negative, value. The internal default is to utilize -huge() !! as a value. type ( regression_statistics ), intent ( out ), optional :: stats (:) !! An optional N-element array that, if supplied, will be used !! to return statistics about the fit for each parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. type ( iteration_controls ), intent ( in ), optional :: controls !! An optional input providing custom iteration controls. type ( lm_solver_options ), intent ( in ), optional :: settings !! An optional input providing custom settings for the solver. type ( convergence_info ), intent ( out ), optional , target :: info !! An optional output that can be used to gain information about !! the iterative solution and the nature of the convergence. procedure ( iteration_update ), intent ( in ), pointer , optional :: status !! An optional pointer to a routine that can be used to extract !! iteration information. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed !! is underdetetermined (M < N). !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied !! tolerances are too small to be practical. !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations !! are allowed. ! Parameters real ( real64 ), parameter :: too_small = 1.0d-14 integer ( int32 ), parameter :: min_iter_count = 2 integer ( int32 ), parameter :: min_fun_count = 10 integer ( int32 ), parameter :: min_update_count = 1 ! Local Variables logical :: stop integer ( int32 ) :: m , n , actual , expected , flag real ( real64 ), pointer :: w (:), pmax (:), pmin (:) real ( real64 ), allocatable , target :: defaultWeights (:), maxparam (:), & minparam (:), JtWJ (:,:) type ( iteration_controls ) :: tol type ( lm_solver_options ) :: opt type ( convergence_info ) :: cInfo class ( errors ), pointer :: errmgr type ( errors ), target :: deferr type ( convergence_info ), target :: defaultinfo type ( convergence_info ), pointer :: inf ! Initialization stop = . false . m = size ( x ) n = size ( params ) if ( present ( info )) then inf => info else inf => defaultinfo end if if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( controls )) then tol = controls else call tol % set_to_default () end if if ( present ( settings )) then opt = settings else call opt % set_to_default () end if ! Input Checking if ( size ( y ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"y\" , m , size ( y )) return end if if ( size ( ymod ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"ymod\" , m , size ( ymod )) return end if if ( size ( resid ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"resid\" , m , size ( resid )) return end if if ( m < n ) then call report_underdefined_error ( errmgr , & \"nonlinear_least_squares\" , n , m ) return end if ! Tolerance Checking if ( tol % gradient_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The gradient tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % change_in_solution_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The change in solution tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % residual_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The residual error tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % iteration_improvement_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The iteration improvement tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if ! Iteration Count Checking if ( tol % max_iteration_count < min_iter_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few iterations were specified.\" , & min_iter_count ) return end if if ( tol % max_function_evaluations < min_fun_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few function evaluations were specified.\" , & min_fun_count ) return end if if ( tol % max_iteration_between_updates < min_update_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few iterations between updates were specified.\" , & min_update_count ) return end if ! Optional Array Arguments (weights, parameter limits, etc.) if ( present ( weights )) then if ( size ( weights ) < m ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"weights\" , m , size ( weights )) return end if w ( 1 : m ) => weights ( 1 : m ) else allocate ( defaultWeights ( m ), source = 1.0d0 , stat = flag ) if ( flag /= 0 ) go to 50 w ( 1 : m ) => defaultWeights ( 1 : m ) end if if ( present ( maxp )) then if ( size ( maxp ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"maxp\" , n , size ( maxp )) return end if pmax ( 1 : n ) => maxp ( 1 : n ) else allocate ( maxparam ( n ), source = huge ( 1.0d0 ), stat = flag ) if ( flag /= 0 ) go to 50 pmax ( 1 : n ) => maxparam ( 1 : n ) end if if ( present ( minp )) then if ( size ( minp ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"minp\" , n , size ( minp )) return end if pmin ( 1 : n ) => minp ( 1 : n ) else allocate ( minparam ( n ), source = - huge ( 1.0d0 ), stat = flag ) if ( flag /= 0 ) go to 50 pmin ( 1 : n ) => minparam ( 1 : n ) end if ! Local Memory Allocations allocate ( JtWJ ( n , n ), stat = flag ) if ( flag /= 0 ) go to 50 ! Process call lm_solve ( fun , x , y , params , w , pmax , pmin , tol , opt , ymod , & resid , JtWJ , inf , stop , errmgr , status ) ! Statistical Parameters if ( present ( stats )) then if ( size ( stats ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"stats\" , n , size ( stats )) return end if ! Compute the covariance matrix call mtx_inverse ( JtWJ , err = errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the statistics stats = calculate_regression_statistics ( resid , params , JtWJ , & alpha , errmgr ) end if ! End return ! Memory Error Handler 50 continue call report_memory_error ( errmgr , \"nonlinear_least_squares\" , flag ) return end subroutine ! ****************************************************************************** ! SETTINGS DEFAULTS ! ------------------------------------------------------------------------------ ! Sets up default tolerances. subroutine lm_set_default_tolerances ( x ) ! Arguments class ( iteration_controls ), intent ( inout ) :: x ! Set defaults x % max_iteration_count = 500 x % max_function_evaluations = 5000 x % max_iteration_between_updates = 10 x % gradient_tolerance = 1.0d-8 x % residual_tolerance = 0.5d-2 x % change_in_solution_tolerance = 1.0d-6 x % iteration_improvement_tolerance = 1.0d-1 end subroutine ! ------------------------------------------------------------------------------ ! Sets up default solver settings. subroutine lm_set_default_settings ( x ) ! Arguments class ( lm_solver_options ), intent ( inout ) :: x ! Set defaults x % method = FS_LEVENBERG_MARQUARDT_UPDATE x % finite_difference_step_size = sqrt ( epsilon ( 1.0d0 )) x % damping_increase_factor = 1 1.0d0 x % damping_decrease_factor = 9.0d0 end subroutine ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ ! Computes the Jacobian matrix via a forward difference. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - params: The model parameters (N-by-1) ! - f0: The current model estimate (M-by-1) ! - step: The differentiation step size ! ! Outputs: ! - jac: The Jacobian matrix (M-by-N) ! - f1: A workspace array for the model output (M-by-1) ! - stop: A flag allowing the user to terminate model execution ! - work: A workspace array for the model parameters (N-by-1) subroutine jacobian_finite_diff ( fun , xdata , params , f0 , jac , f1 , & stop , step , work ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), params (:) real ( real64 ), intent ( in ) :: f0 (:) real ( real64 ), intent ( out ) :: jac (:,:) real ( real64 ), intent ( out ) :: f1 (:), work (:) logical , intent ( out ) :: stop real ( real64 ), intent ( in ) :: step ! Local Variables integer ( int32 ) :: i , n ! Initialization n = size ( params ) ! Cycle over each column of the Jacobian and calculate the derivative ! via a forward difference scheme ! ! J(i,j) = df(i) / dx(j) work = params do i = 1 , n work ( i ) = work ( i ) + step call fun ( xdata , work , f1 , stop ) if ( stop ) return jac (:, i ) = ( f1 - f0 ) / step work ( i ) = params ( i ) end do end subroutine ! ------------------------------------------------------------------------------ ! Computes a rank-1 update to the Jacobian matrix ! ! Inputs: ! - pOld: previous set of parameters (N-by-1) ! - yOld: model evaluation at previous set of parameters (M-by-1) ! - jac: current Jacobian estimate (M-by-N) ! - p: current set of parameters (N-by-1) ! - y: model evaluation at current set of parameters (M-by-1) ! ! Outputs: ! - jac: updated Jacobian matrix (M-by-N) (dy * dp**T + J) ! - dp: p - pOld (N-by-1) ! - dy: (y - yOld - J * dp) / (dp' * dp) (M-by-1) subroutine broyden_update ( pOld , yOld , jac , p , y , dp , dy ) ! Arguments real ( real64 ), intent ( in ) :: pOld (:), yOld (:), p (:), y (:) real ( real64 ), intent ( inout ) :: jac (:,:) real ( real64 ), intent ( out ) :: dp (:), dy (:) ! Local Variables real ( real64 ) :: h2 ! Process dp = p - pOld h2 = dot_product ( dp , dp ) dy = y - yOld - matmul ( jac , dp ) dy = dy / h2 call rank1_update ( 1.0d0 , dy , dp , jac ) end subroutine ! ------------------------------------------------------------------------------ ! Updates the Levenberg-Marquardt matrix by either computing a new Jacobian ! matrix or performing a rank-1 update to the existing Jacobian matrix. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - pOld: previous set of parameters (N-by-1) ! - yOld: model evaluation at previous set of parameters (M-by-1) ! - dX2: The previous change in the Chi-squared criteria ! - jac: current Jacobian estimate (M-by-N) ! - p: current set of parameters (N-by-1) ! - weights: A weighting vector (M-by-1) ! - neval: Current number of function evaluations ! - update: Set to true to force an update of the Jacobian; else, set to ! false to let the program choose based upon the change in the ! Chi-squared parameter. ! - step: The differentiation step size ! ! Outputs: ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - JtWdy: linearized fitting vector (N-by-1) ! - X2: Updated Chi-squared criteria ! - yNew: model evaluated with parameters of p (M-by-1) ! - jac: updated Jacobian matrix (M-by-N) ! - neval: updated count of function evaluations ! - stop: A flag allowing the user to terminate model execution ! - work: A workspace array (N+M-by-1) ! - mwork: A workspace matrix (N-by-M) ! - update: Reset to false if a Jacobian evaluation was performed. subroutine lm_matrix ( fun , xdata , ydata , pOld , yOld , dX2 , jac , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , yNew , stop , work , mwork ) ! Arguments procedure ( regression_function ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), pOld (:), yOld (:), & p (:), weights (:) real ( real64 ), intent ( in ) :: dX2 , step real ( real64 ), intent ( inout ) :: jac (:,:) integer ( int32 ), intent ( inout ) :: neval logical , intent ( inout ) :: update real ( real64 ), intent ( out ) :: JtWJ (:,:), JtWdy (:) real ( real64 ), intent ( out ) :: X2 , mwork (:,:), yNew (:) logical , intent ( out ) :: stop real ( real64 ), intent ( out ), target :: work (:) ! Local Variables integer ( int32 ) :: m , n real ( real64 ), pointer :: w1 (:), w2 (:) ! Initialization m = size ( xdata ) n = size ( p ) w1 ( 1 : m ) => work ( 1 : m ) w2 ( 1 : n ) => work ( m + 1 : n + m ) ! Perform the next function evaluation call fun ( xdata , p , yNew , stop ) neval = neval + 1 if ( stop ) return ! Update or recompute the Jacobian matrix if ( dX2 > 0 . or . update ) then ! Recompute the Jacobian call jacobian_finite_diff ( fun , xdata , p , yNew , jac , w1 , & stop , step , w2 ) neval = neval + n if ( stop ) return update = . false . else ! Simply perform a rank-1 update to the Jacobian call broyden_update ( pOld , yOld , jac , p , yNew , w2 , w1 ) end if ! Update the Chi-squared estimate w1 = ydata - yNew X2 = dot_product ( w1 , w1 * weights ) ! Compute J**T * (W .* dY) w1 = w1 * weights call mtx_mult (. true ., 1.0d0 , jac , w1 , 0.0d0 , JtWdy ) ! Update the Hessian ! First: J**T * W = MWORK ! Second: (J**T * W) * J call diag_mtx_mult (. false ., . true ., 1.0d0 , weights , jac , 0.0d0 , mwork ) call mtx_mult (. false ., . false ., 1.0d0 , mwork , jac , 0.0d0 , JtWJ ) end subroutine ! ------------------------------------------------------------------------------ ! Performs a single iteration of the Levenberg-Marquardt algorithm. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - p: current set of parameters (N-by-1) ! - neval: current number of function evaluations ! - niter: current iteration number ! - update: set to 1 to use Marquardt's modification; else, ! - step: the differentiation step size ! - lambda: LM damping parameter ! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) ! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) ! - weights: a weighting vector (M-by-1) ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - JtWdy: linearized fitting vector (N-by-1) ! ! Outputs: ! - JtWJ: overwritten LU factorization of the original matrix (N-by-N) ! - h: The new estimate of the change in parameter (N-by-1) ! - pNew: The new parameter estimates (N-by-1) ! - deltaY: The new difference between data and model (M-by-1) ! - yNew: model evaluated with parameters of pNew (M-by-1) ! - neval: updated count of function evaluations ! - niter: updated current iteration number ! - X2: updated Chi-squared criteria ! - stop: A flag allowing the user to terminate model execution ! - iwork: A workspace array (N-by-1) ! - err: An error handling mechanism subroutine lm_iter ( fun , xdata , ydata , p , neval , niter , update , lambda , & maxP , minP , weights , JtWJ , JtWdy , h , pNew , deltaY , yNew , X2 , X2Old , & alpha , stop , iwork , err , status ) ! Arguments procedure ( regression_function ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), p (:), maxP (:), & minP (:), weights (:), JtWdy (:) real ( real64 ), intent ( in ) :: lambda , X2Old integer ( int32 ), intent ( inout ) :: neval , niter integer ( int32 ), intent ( in ) :: update real ( real64 ), intent ( inout ) :: JtWJ (:,:) real ( real64 ), intent ( out ) :: h (:), pNew (:), deltaY (:), yNew (:) real ( real64 ), intent ( out ) :: X2 , alpha logical , intent ( out ) :: stop integer ( int32 ), intent ( out ) :: iwork (:) class ( errors ), intent ( inout ) :: err procedure ( iteration_update ), intent ( in ), pointer , optional :: status ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: dpJh ! Initialization n = size ( p ) ! Increment the iteration counter niter = niter + 1 ! Solve the linear system to determine the change in parameters ! A is N-by-N and is stored in JtWJ ! b is N-by-1 if ( update == FS_LEVENBERG_MARQUARDT_UPDATE ) then ! Compute: h = A \\ b ! A = J**T * W * J + lambda * diag(J**T * W * J) ! b = J**T * W * dy do i = 1 , n JtWJ ( i , i ) = JtWJ ( i , i ) * ( 1.0d0 + lambda ) h ( i ) = JtWdy ( i ) end do else ! Compute: h = A \\ b ! A = J**T * W * J + lambda * I ! b = J**T * W * dy do i = 1 , n JtWJ ( i , i ) = JtWJ ( i , i ) + lambda h ( i ) = JtWdy ( i ) end do end if call lu_factor ( JtWJ , iwork , err ) ! overwrites JtWJ with [L\\U] if ( err % has_error_occurred ()) return ! if JtWJ is singular call solve_lu ( JtWJ , iwork , h ) ! solution stored in h ! Compute the new attempted solution, and apply any constraints do i = 1 , n pNew ( i ) = min ( max ( minP ( i ), h ( i ) + p ( i )), maxP ( i )) end do ! Update the residual error call fun ( xdata , pNew , yNew , stop ) neval = neval + 1 deltaY = ydata - yNew if ( stop ) return ! Update the Chi-squared estimate X2 = dot_product ( deltaY , deltaY * weights ) ! Perform a quadratic line update in the H direction, if necessary if ( update == FS_QUADRATIC_UPDATE ) then dpJh = dot_product ( JtWdy , h ) alpha = abs ( dpJh / ( 0.5d0 * ( X2 - X2Old ) + 2.0d0 * dpJh )) h = alpha * h do i = 1 , n pNew ( i ) = min ( max ( minP ( i ), p ( i ) + h ( i )), maxP ( i )) end do call fun ( xdata , pNew , yNew , stop ) if ( stop ) return neval = neval + 1 deltaY = ydata - yNew X2 = dot_product ( deltaY , deltaY * weights ) end if ! Update the status of the iteration, if needed if ( present ( status )) then call status ( niter , yNew , deltaY , pNew , h ) end if end subroutine ! ------------------------------------------------------------------------------ ! A Levenberg-Marquardt solver. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - p: current set of parameters (N-by-1) ! - weights: a weighting vector (M-by-1) ! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) ! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) ! - controls: an iteration_controls instance containing solution tolerances ! ! Outputs: ! - p: solution (N-by-1) ! - y: model results at p (M-by-1) ! - resid: residual (ydata - y) (M-by-1) ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - opt: a convergence_info object containing information regarding ! convergence of the iteration ! - stop: A flag allowing the user to terminate model execution ! - err: An error handling object subroutine lm_solve ( fun , xdata , ydata , p , weights , maxP , minP , controls , & opt , y , resid , JtWJ , info , stop , err , status ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), weights (:), maxP (:), & minP (:) real ( real64 ), intent ( inout ) :: p (:) class ( iteration_controls ), intent ( in ) :: controls class ( lm_solver_options ), intent ( in ) :: opt real ( real64 ), intent ( out ) :: y (:), resid (:), JtWJ (:,:) class ( convergence_info ), intent ( out ) :: info logical , intent ( out ) :: stop class ( errors ), intent ( inout ) :: err procedure ( iteration_update ), intent ( in ), pointer , optional :: status ! Local Variables logical :: update integer ( int32 ) :: i , m , n , dof , flag , neval , niter , nupdate real ( real64 ) :: dX2 , X2 , X2Old , X2Try , lambda , alpha , nu , step real ( real64 ), allocatable :: pOld (:), yOld (:), J (:,:), JtWdy (:), & work (:), mwork (:,:), pTry (:), yTemp (:), JtWJc (:,:), h (:) integer ( int32 ), allocatable :: iwork (:) character ( len = :), allocatable :: errmsg ! Initialization update = . true . m = size ( xdata ) n = size ( p ) dof = m - n niter = 0 step = opt % finite_difference_step_size stop = . false . info % user_requested_stop = . false . nupdate = 0 ! Local Memory Allocation allocate ( pOld ( n ), source = 0.0d0 , stat = flag ) if ( flag == 0 ) allocate ( yOld ( m ), source = 0.0d0 , stat = flag ) if ( flag == 0 ) allocate ( J ( m , n ), stat = flag ) if ( flag == 0 ) allocate ( JtWdy ( n ), stat = flag ) if ( flag == 0 ) allocate ( work ( m + n ), stat = flag ) if ( flag == 0 ) allocate ( mwork ( n , m ), stat = flag ) if ( flag == 0 ) allocate ( pTry ( n ), stat = flag ) if ( flag == 0 ) allocate ( h ( n ), stat = flag ) if ( flag == 0 ) allocate ( yTemp ( m ), stat = flag ) if ( flag == 0 ) allocate ( JtWJc ( n , n ), stat = flag ) if ( flag == 0 ) allocate ( iwork ( n ), stat = flag ) if ( flag /= 0 ) go to 10 ! Perform an initial function evaluation call fun ( xdata , p , y , stop ) neval = 1 ! Evaluate the problem matrices call lm_matrix ( fun , xdata , ydata , pOld , yOld , 1.0d0 , J , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , y , stop , work , mwork ) if ( stop ) go to 5 X2Old = X2 JtWJc = JtWJ ! Determine an initial value for lambda if ( opt % method == FS_LEVENBERG_MARQUARDT_UPDATE ) then lambda = 1.0d-2 else call extract_diagonal ( JtWJ , work ( 1 : n )) lambda = 1.0d-2 * maxval ( work ( 1 : n )) nu = 2.0d0 end if ! Main Loop main : do while ( niter < controls % max_iteration_count ) ! Compute the linear solution at the current solution estimate and ! update the new parameter estimates call lm_iter ( fun , xdata , ydata , p , neval , niter , opt % method , & lambda , maxP , minP , weights , JtWJc , JtWdy , h , pTry , resid , & yTemp , X2Try , X2Old , alpha , stop , iwork , err , status ) if ( stop ) go to 5 if ( err % has_error_occurred ()) return ! Update the Chi-squared estimate, update the damping parameter ! lambda, and, if necessary, update the matrices call lm_update ( fun , xdata , ydata , pOld , p , pTry , yOld , y , h , dX2 , & X2Old , X2 , X2Try , lambda , alpha , nu , JtWdy , JtWJ , J , weights , & niter , neval , update , step , work , mwork , controls , opt , stop ) if ( stop ) go to 5 JtWJc = JtWJ ! Determine the matrix update scheme nupdate = nupdate + 1 if ( opt % method == FS_QUADRATIC_UPDATE ) then update = mod ( niter , 2 * n ) > 0 else if ( nupdate >= controls % max_iteration_between_updates ) then update = . true . nupdate = 0 end if ! Test for convergence if ( lm_check_convergence ( controls , dof , resid , niter , neval , & JtWdy , h , p , X2 , info )) & then exit main end if end do main ! End return ! User Requested End 5 continue info % user_requested_stop = . true . return ! Memory Error Handling 10 continue allocate ( character ( len = 512 ) :: errmsg ) write ( errmsg , 100 ) \"Memory allocation error code \" , flag , \".\" call err % report_error ( \"lm_solve\" , & trim ( errmsg ), FS_MEMORY_ERROR ) return ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ ! subroutine lm_update ( fun , xdata , ydata , pOld , p , pTry , yOld , y , h , dX2 , & X2old , X2 , X2try , lambda , alpha , nu , JtWdy , JtWJ , J , weights , niter , & neval , update , step , work , mwork , controls , opt , stop ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), X2try , h (:), step , & pTry (:), weights (:), alpha real ( real64 ), intent ( inout ) :: pOld (:), p (:), yOld (:), y (:), lambda , & JtWdy (:), dX2 , X2 , X2old , JtWJ (:,:), J (:,:), nu real ( real64 ), intent ( out ) :: work (:), mwork (:,:) integer ( int32 ), intent ( in ) :: niter integer ( int32 ), intent ( inout ) :: neval logical , intent ( inout ) :: update class ( iteration_controls ), intent ( in ) :: controls class ( lm_solver_options ), intent ( in ) :: opt logical , intent ( out ) :: stop ! Local Variables integer ( int32 ) :: n real ( real64 ) :: rho ! Initialization n = size ( p ) ! Process if ( opt % method == FS_LEVENBERG_MARQUARDT_UPDATE ) then call extract_diagonal ( JtWJ , work ( 1 : n )) work ( 1 : n ) = lambda * work ( 1 : n ) * h + JtWdy else work ( 1 : n ) = lambda * h + JtWdy end if rho = ( X2 - X2try ) / abs ( dot_product ( h , work ( 1 : n ))) if ( rho > controls % iteration_improvement_tolerance ) then ! Things are getting better at an acceptable rate dX2 = X2 - X2old X2old = X2 pOld = p yOld = y p = pTry ! Recompute the matrices call lm_matrix ( fun , xdata , ydata , pOld , yOld , dX2 , J , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , y , stop , work , mwork ) if ( stop ) return ! Decrease lambda select case ( opt % method ) case ( FS_LEVENBERG_MARQUARDT_UPDATE ) lambda = max ( lambda / opt % damping_decrease_factor , 1.0d-7 ) case ( FS_QUADRATIC_UPDATE ) lambda = max ( lambda / ( 1.0d0 + alpha ), 1.0d-7 ) case ( FS_NIELSEN_UPDATE ) lambda = lambda * max ( 1.0d0 / 3.0d0 , & 1.0d0 - ( 2.0d0 * rho - 1.0d0 ** 3 )) nu = 2.0d0 end select else ! The iteration is not improving in a satisfactory manner X2 = X2old if ( mod ( niter , 2 * n ) /= 0 ) then call lm_matrix ( fun , xdata , ydata , pOld , yOld , - 1.0d0 , J , p , & weights , neval , update , step , JtWJ , JtWdy , dX2 , y , stop , & work , mwork ) if ( stop ) return end if ! Increase lambda select case ( opt % method ) case ( FS_LEVENBERG_MARQUARDT_UPDATE ) lambda = min ( lambda * opt % damping_increase_factor , 1.0d7 ) case ( FS_QUADRATIC_UPDATE ) lambda = lambda + abs (( X2try - X2 ) / 2.0d0 / alpha ) case ( FS_NIELSEN_UPDATE ) lambda = lambda * nu nu = 2.0d0 * nu end select end if end subroutine ! ------------------------------------------------------------------------------ ! Checks the Levenberg-Marquardt solution against the convergence criteria. ! ! Inputs: ! - controls: the solution controls and convergence criteria ! - dof: the statistical degrees of freedom of the system (M - N) ! - resid: the residual error (M-by-1) ! - niter: the number of iterations ! - neval: the number of function evaluations ! - JtWdy: linearized fitting vector (N-by-1) ! - h: the change in parameter (solution) values (N-by-1) ! - p: the parameter (solution) values (N-by-1) ! - X2: the Chi-squared estimate ! ! Outputs: ! - info: The convergence information. ! - rst: True if convergence was achieved; else, false. function lm_check_convergence ( controls , dof , resid , niter , neval , & JtWdy , h , p , X2 , info ) result ( rst ) ! Arguments class ( iteration_controls ), intent ( in ) :: controls real ( real64 ), intent ( in ) :: resid (:), JtWdy (:), h (:), p (:), X2 integer ( int32 ), intent ( in ) :: dof , niter , neval class ( convergence_info ), intent ( out ) :: info logical :: rst ! Initialization rst = . false . ! Iteration Checks info % iteration_count = niter if ( niter >= controls % max_iteration_count ) then info % reach_iteration_limit = . true . rst = . true . else info % reach_iteration_limit = . false . end if info % function_evaluation_count = neval if ( neval >= controls % max_function_evaluations ) then info % reach_function_evaluation_limit = . true . rst = . true . else info % reach_function_evaluation_limit = . false . end if info % gradient_value = maxval ( abs ( JtWdy )) if ( info % gradient_value < controls % gradient_tolerance . and . niter > 2 ) & then info % converge_on_gradient = . true . rst = . true . else info % converge_on_gradient = . false . end if info % solution_change_value = maxval ( abs ( h ) / ( abs ( p ) + 1.0d-12 )) if ( info % solution_change_value < & controls % change_in_solution_tolerance . and . niter > 2 ) & then info % converge_on_solution_change = . true . rst = . true . else info % converge_on_solution_change = . false . end if info % residual_value = X2 / dof if ( info % residual_value < controls % residual_tolerance . and . niter > 2 ) & then info % converge_on_residual_parameter = . true . rst = . true . else info % converge_on_residual_parameter = . false . end if end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_regression.f90.html"},{"title":"fstats_allan.f90 – FSTATS","text":"Source Code module fstats_allan use iso_fortran_env use fstats_errors implicit none private public :: allan_variance contains ! ------------------------------------------------------------------------------ ! REF: Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, ! Viraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm for ! Fully Overlapped Allan Variance and Total Variance for Analysis and Modeling ! of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. ! 10.1109/LSENS.2018.2829799. ! ! https://www.researchgate.net/publication/324738301_A_Fast_Parallel_Algorithm_for_Fully_Overlapped_Allan_Variance_and_Total_Variance_for_Analysis_and_Modeling_of_Noise_in_Inertial_Sensors ! https://github.com/shrikanth95/Fast-Parallel-Fully-Overlapped-Allan-Variance-and-Total-Variance/blob/master/fast_FOAV.m function allan_variance ( x , dt , err ) result ( rst ) !! Computes the Allan variance of a data set. !! !! Remarks !! !! This implementation computes the fully overlapped Allan variance !! using the method presented by Yadav et. al. !! !! Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, !! Viraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm !! for Fully Overlapped Allan Variance and Total Variance for Analysis and !! Modeling of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. !! 10.1109/LSENS.2018.2829799. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element data set to analyze. real ( real64 ), intent ( in ), optional :: dt !! An optional input specifying the time increment between !! samples in x. If not specified, this value is set to 1. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. real ( real64 ), allocatable , dimension (:,:) :: rst !! An M-by-2 array containing the results where M is N / 2 - 1 !! if N is even; else, M is (N - 1) / 2 - 1 if N is odd. The !! first column contains the averaging times associated with !! the M results stored in the second column. ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr integer ( int32 ) :: flag , j , m , n , limit , nr real ( real64 ), allocatable , dimension (:) :: tall1 , tall2 real ( real64 ) :: temp , deltaT ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( dt )) then deltaT = dt else deltaT = 1.0d0 end if ! Initialization n = size ( x ) limit = n nr = floor ( 0.5 * n ) - 1 allocate ( tall1 ( n - 1 ), source = x (: n - 1 ), stat = flag ) if ( flag == 0 ) allocate ( tall2 ( n - 1 ), source = x ( 2 : n )) if ( flag == 0 ) allocate ( rst ( nr , 2 ), source = 0.0d0 ) if ( flag /= 0 ) go to 10 ! Process do m = 1 , nr temp = 0.0d0 do j = 1 , limit - 1 temp = temp + ( tall2 ( j ) - tall1 ( j )) ** 2 tall1 ( j ) = tall1 ( j ) + x ( min ( n , m + j )) tall2 ( j ) = tall2 ( min ( n - 1 , j + 1 )) + x ( min ( n , 2 * m + j + 1 )) end do limit = limit - 2 rst ( m , 1 ) = dt * m rst ( m , 2 ) = temp / ( 2.0d0 * ( n - 2 * m + 1 ) * m ** 2 ) end do ! End return ! Memory Error Handling 10 continue call report_memory_error ( errmgr , \"allan_variance\" , flag ) return end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_allan.f90.html"},{"title":"fstats_helper_routines.f90 – FSTATS","text":"Source Code module fstats_helper_routines use iso_fortran_env implicit none private public :: difference public :: factorial contains ! ------------------------------------------------------------------------------ pure function difference ( x ) result ( rst ) !! Computes the difference between elements in an array. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array on which to operate. real ( real64 ), allocatable , dimension (:) :: rst !! The (N-1)-element array containing the differences between adjacent !! elements. ! Local Variables integer ( int32 ) :: i , n ! Process n = size ( x ) allocate ( rst ( n - 1 )) do i = 1 , n - 1 rst ( i ) = x ( i + 1 ) - x ( i ) end do end function ! ------------------------------------------------------------------------------ pure elemental function factorial ( x ) result ( rst ) !! Computes the factorial of X. real ( real64 ), intent ( in ) :: x !! The value whose factorial is to be computed. real ( real64 ) :: rst !! The result. rst = gamma ( x + 1.0d0 ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_helper_routines.f90.html"},{"title":"fstats_hypothesis.f90 – FSTATS","text":"Source Code module fstats_hypothesis use iso_fortran_env use ieee_arithmetic use fstats_errors use fstats_special_functions use fstats_distributions use fstats_descriptive_statistics private public :: confidence_interval public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test interface confidence_interval !! Computes the confidence interval for the specified distribution. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Confidence_interval) module procedure :: confidence_interval_scalar module procedure :: confidence_interval_array end interface contains ! ------------------------------------------------------------------------------ pure function confidence_interval_scalar ( dist , alpha , s , n ) result ( rst ) !! Computes the confidence interval for the specified distribution. class ( distribution ), intent ( in ) :: dist !! The distribution object defining the probability distribution !! to establish the confidence level. real ( real64 ), intent ( in ) :: alpha !! The probability value of interest. For instance, use a value of 0.05 !! for a confidence level of 95%. real ( real64 ), intent ( in ) :: s !! The sample standard deviation. integer ( int32 ), intent ( in ) :: n !! The number of samples in the data set. real ( real64 ) :: rst !! The result. ! Local Variables integer ( int32 ), parameter :: maxiter = 100 real ( real64 ), parameter :: tol = 1.0d-6 integer ( int32 ) :: i real ( real64 ) :: x , f , df , h , twoh , dy ! Process ! ! We use a simplified Newton's method to solve for the independent variable ! of the CDF function where it equals 1 - alpha / 2. h = 1.0d-6 twoh = 2.0d0 * h x = 1.0d0 - alpha / 2.0d0 rst = 0.5d0 do i = 1 , maxiter ! Compute the CDF and its derivative at y f = dist % cdf ( rst ) - x df = ( dist % cdf ( rst + h ) - dist % cdf ( rst - h )) / twoh dy = f / df rst = rst - dy if ( abs ( dy ) < tol ) exit end do ! Determine the actual interval rst = rst * s / sqrt ( real ( n , real64 )) end function ! ------------------------------------------------------------------------------ pure function confidence_interval_array ( dist , alpha , x ) result ( rst ) !! Computes the confidence interval for the specified distribution. class ( distribution ), intent ( in ) :: dist !! The distribution object defining the probability distribution !! to establish the confidence level. real ( real64 ), intent ( in ) :: alpha !! The probability value of interest. For instance, use a value of 0.05 !! for a confidence level of 95%. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the data to analyze. real ( real64 ) :: rst !! The result. ! Process rst = confidence_interval ( dist , alpha , standard_deviation ( x ), size ( x )) end function ! ------------------------------------------------------------------------------ subroutine t_test_equal_variance ( x1 , x2 , stat , p , dof ) !! Computes the 2-tailed Student's T-Test for two data sets of !! assumed equivalent variances. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables real ( real64 ) :: v1 , v2 , m1 , m2 , sv , a , b , x integer ( int32 ) :: n1 , n2 ! Compute the T-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = n1 + n2 - two sv = (( n1 - one ) * v1 + ( n2 - one ) * v2 ) / dof stat = abs ( m1 - m2 ) / sqrt ( sv * ( one / real ( n1 ) + one / real ( n2 ))) ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine t_test_unequal_variance ( x1 , x2 , stat , p , dof ) !! Computes the 2-tailed Student's T-Test for two data sets of !! assumed non-equivalent variances. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables real ( real64 ) :: v1 , v2 , m1 , m2 , sv , a , b , x integer ( int32 ) :: n1 , n2 ! Compute the T-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = ( v1 / real ( n1 ) + v2 / real ( n2 )) ** 2 / (( v1 / n1 ) ** 2 / ( n1 - one ) + & ( v2 / n2 ) ** 2 / ( n2 - one )) sv = sqrt ( v1 / n1 + v2 / n2 ) stat = ( m1 - m2 ) / sv ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine t_test_paired ( x1 , x2 , stat , p , dof , err ) !! Computes the 2-tailed Student's T-Test for two paired data sets. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An N-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same !! length. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr real ( real64 ) :: v1 , v2 , m1 , m2 , sd , cov , a , b , x integer ( int32 ) :: i , n1 , n2 , n ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n1 = size ( x1 ) n2 = size ( x2 ) n = min ( n1 , n2 ) ! Input Checking if ( n1 /= n2 ) then call report_arrays_not_same_size_error ( errmgr , \"t_test_paired_real64\" , & \"X1\" , \"X2\" , n1 , n2 ) return end if ! Compute the T-statistic m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = real ( n1 ) - one cov = zero do i = 1 , n cov = cov + ( x1 ( i ) - m1 ) * ( x2 ( i ) - m2 ) end do cov = cov / dof sd = sqrt (( v1 + v2 - two * cov ) / n ) stat = ( m1 - m2 ) / sd ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine f_test ( x1 , x2 , stat , p , dof1 , dof2 ) !! Computes the F-test and returns the probability (two-tailed) that !! the variances of two data sets are not significantly different. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/F-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The F-statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from the two underlying populations that !! have the same variance. real ( real64 ), intent ( out ) :: dof1 !! A measure of the degrees of freedom. real ( real64 ), intent ( out ) :: dof2 !! A measure of the degrees of freedom. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables integer ( int32 ) :: n1 , n2 real ( real64 ) :: v1 , v2 , m1 , m2 , a , b , x ! Compute the F-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) if ( v1 > v2 ) then stat = v1 / v2 dof1 = n1 - one dof2 = n2 - one else stat = v2 / v1 dof1 = n2 - one dof2 = n1 - one end if ! Compute the probability a = half * dof2 b = half * dof1 x = dof2 / ( dof2 + dof1 * stat ) p = two * regularized_beta ( a , b , x ) if ( p > one ) p = two - p end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_hypothesis.f90.html"},{"title":"fstats_errors.f90 – FSTATS","text":"Source Code ! A module providing a set of routines to handle errors for the FSTATS library. module fstats_errors use ferror use iso_fortran_env , only : int32 implicit none ! ****************************************************************************** ! ERROR CODES ! ------------------------------------------------------------------------------ integer ( int32 ), parameter :: FS_NO_ERROR = 0 integer ( int32 ), parameter :: FS_ARRAY_SIZE_ERROR = 10000 integer ( int32 ), parameter :: FS_MATRIX_SIZE_ERROR = 10001 integer ( int32 ), parameter :: FS_INVALID_INPUT_ERROR = 10002 integer ( int32 ), parameter :: FS_MEMORY_ERROR = 10003 integer ( int32 ), parameter :: FS_UNDERDEFINED_PROBLEM_ERROR = 10004 integer ( int32 ), parameter :: FS_TOLERANCE_TOO_SMALL_ERROR = 10005 integer ( int32 ), parameter :: FS_TOO_FEW_ITERATION_ERROR = 10006 ! ------------------------------------------------------------------------------ integer ( int32 ), private , parameter :: MESSAGE_SIZE = 1024 contains ! ------------------------------------------------------------------------------ subroutine report_memory_error ( err , fname , code ) !! Reports a memory allocation related error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. integer ( int32 ), intent ( in ) :: code !! The error code returned by the allocation routine. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) & \"A memory allocation error occurred with code \" , code , \".\" call err % report_error ( fname , trim ( msg ), FS_MEMORY_ERROR ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_array_size_error ( err , fname , name , expect , actual ) !! Reports an array size error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name !! The name of the array. integer ( int32 ), intent ( in ) :: expect !! The expected size of the array. integer ( int32 ), intent ( in ) :: actual !! The actual size of the array. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Expected array \" // name // \" to be of length \" , & expect , \", but found it to be of length \" , actual , \".\" call err % report_error ( fname , trim ( msg ), FS_ARRAY_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_matrix_size_error ( err , fname , name , expect_rows , & expect_cols , actual_rows , actual_cols ) !! Reports a matrix size error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name !! The name of the matrix. integer ( int32 ), intent ( in ) :: expect_rows !! The expected number of rows. integer ( int32 ), intent ( in ) :: expect_cols !! The expected number of columns. integer ( int32 ), intent ( in ) :: actual_rows !! The actual number of rows. integer ( int32 ), intent ( in ) :: actual_cols !! The actual number of columns. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Expected matrix \" // name // \" to be of size (\" , & expect_rows , \", \" , expect_cols , \"), but found it to be of size (\" , & actual_rows , \", \" , actual_cols , \").\" call err % report_error ( fname , trim ( msg ), FS_MATRIX_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_arrays_not_same_size_error ( err , fname , name1 , name2 , & size1 , size2 ) !! Reports an error relating to two arrays not being the same size !! when they should be the same size. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name1 !! The name of the first array. character ( len = * ), intent ( in ) :: name2 !! The name of the second array. integer ( int32 ), intent ( in ) :: size1 !! The size of the first array. integer ( int32 ), intent ( in ) :: size2 !! The size of the second array. ! Local Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Array \" // name1 // \" and array \" // name2 // & \"were expected to be the same size, but instead were found \" // & \"to be sized \" , size1 , \" and \" , size2 , \" respectively.\" call err % report_error ( fname , trim ( msg ), FS_ARRAY_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_underdefined_error ( err , fname , expect , actual ) !! Reports an underdefined problem error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. integer ( int32 ), intent ( in ) :: expect !! The expected minimum number of equations. integer ( int32 ), intent ( in ) :: actual !! The actual number of equations. ! Local Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"The problem is underdefined. The number of \" // & \"equations was found to be \" , actual , & \", but must be at least equal to the number of unknowns \" , & expect , \".\" call err % report_error ( fname , trim ( msg ), FS_UNDERDEFINED_PROBLEM_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_iteration_count_error ( err , fname , msg , mincount ) !! Reports an iteration count error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ) :: fname !! The name of the routine in which the error occurred. character ( len = * ) :: msg !! The error message. integer ( int32 ), intent ( in ) :: mincount !! The minimum iteration count expected. ! Local Variables character ( len = MESSAGE_SIZE ) :: emsg ! Process write ( emsg , 100 ) msg // \" A minimum of \" , mincount , \" is expected.\" call err % report_error ( fname , trim ( emsg ), FS_TOO_FEW_ITERATION_ERROR ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_errors.f90.html"},{"title":"fstats_smoothing.f90 – FSTATS","text":"Source Code module fstats_smoothing use iso_fortran_env use ferror use fstats_errors use linalg , only : sort implicit none private public :: lowess contains ! ------------------------------------------------------------------------------ subroutine lowess ( x , y , ys , fsmooth , nstps , del , rweights , resid , err ) !! Computes the smoothing of a data set using a robust locally weighted !! scatterplot smoothing (LOWESS) algorithm. Fitted values are computed at !! each of the supplied x values. !! !! Remarks !! !! The code is a reimplementation of the LOWESS library. For a detailed !! understanding, see [this] !! (http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf) !! paper by William Cleveland. real ( real64 ), intent ( in ), dimension (:) :: x !! An N-element array containing the independent variable data. This !! array must be monotonically increasing. real ( real64 ), intent ( in ), dimension (:) :: y !! An N-element array containing the dependent variable data. real ( real64 ), intent ( out ), dimension (:) :: ys !! An N-element array where the smoothed results will be written. real ( real64 ), intent ( in ), optional :: fsmooth !! An optional input that specifies the amount of smoothing. !! Specifically, this value is the fraction of points used to compute !! each value. As this value increases, the output becomes smoother. !! Choosing a value in the range of 0.2 to 0.8 typically results in a !! good fit. The default value is 0.2. integer ( int32 ), intent ( in ), optional :: nstps !! An optional input that specifies the numb of iterations. If set to !! zero, a non-robust fit is returned. The default value is set to 2. real ( real64 ), intent ( in ), optional :: del !! real ( real64 ), intent ( out ), optional , dimension (:), target :: rweights !! An optional N-element array, that if supplied, will be used to !! return the weights given to each data point. real ( real64 ), intent ( out ), optional , dimension (:), target :: resid !! An optional N-element array, that if supplied, will be used to !! return the residual. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p2 = 2.0d-1 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: three = 3.0d0 real ( real64 ), parameter :: p001 = 1.0d-3 real ( real64 ), parameter :: p999 = 0.999d0 ! Local Variables logical :: ok integer ( int32 ) :: iter , i , j , nleft , nright , ns , last , m1 , m2 , n , nsteps , flag real ( real64 ) :: f , delta , d1 , d2 , denom , alpha , cut , eps , cmad , c1 , c9 , r real ( real64 ), allocatable , target , dimension (:) :: rwdef , rsdef real ( real64 ), pointer , dimension (:) :: rw , res class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n = size ( x ) if ( present ( fsmooth )) then f = fsmooth else f = p2 end if if ( present ( nstps )) then nsteps = nstps else nsteps = 2 end if if ( present ( del )) then delta = del else delta = 0.0d0 end if if ( present ( rweights )) then if ( size ( rweights ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"rweights\" , n , & size ( rweights )) return end if rw => rweights else allocate ( rwdef ( n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"lowess\" , flag ) return end if rw => rwdef end if if ( present ( resid )) then if ( size ( resid ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"resid\" , n , & size ( resid )) return end if res => resid else allocate ( rsdef ( n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"lowess\" , flag ) return end if res => rsdef end if ns = max ( min ( int ( f * real ( n ), int32 ), n ), 2 ) eps = epsilon ( eps ) ! Input Checking if ( size ( y ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"y\" , n , size ( y )) return end if if ( size ( ys ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"ys\" , n , size ( ys )) return end if ! Quick Return if ( n < 2 ) then ys = y return end if ! Process do iter = 1 , nsteps + 1 nleft = 1 nright = ns last = 0 i = 1 do do while ( nright < n ) d1 = x ( i ) - x ( nleft ) d2 = x ( nright + 1 ) - x ( i ) if ( d1 <= d2 ) exit nleft = nleft + 1 nright = nright + 1 end do call lowest ( x , y , x ( i ), ys ( i ), nleft , nright , res , iter > 1 , & rw , ok ) if (. not . ok ) ys ( i ) = y ( i ) if ( last < i - 1 ) then denom = x ( i ) - x ( last ) do j = last + 1 , i - 1 alpha = ( x ( j ) - x ( last )) / denom ys ( j ) = alpha * ys ( i ) + ( one - alpha ) * ys ( last ) end do end if last = i cut = x ( last ) + delta do i = last + 1 , n if ( x ( i ) > cut ) exit if ( abs ( x ( i ) - x ( last )) < eps ) then ys ( i ) = ys ( last ) last = i end if end do i = max ( last + 1 , i - 1 ) if ( last >= n ) exit end do res = y - ys if ( iter > nsteps ) exit rw = abs ( res ) call sort ( rw , . true .) m1 = 1 + n / 2 m2 = n - m1 + 1 cmad = three * ( rw ( m1 ) + rw ( m2 )) c9 = p999 * cmad c1 = p001 * cmad do i = 1 , n r = abs ( res ( i )) if ( r <= c1 ) then rw ( i ) = one else if ( r > c9 ) then rw ( i ) = zero else rw ( i ) = ( one - ( r / cmad ) ** 2 ) ** 2 end if end do end do end subroutine ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ ! REF: ! - https://en.wikipedia.org/wiki/Local_regression ! - http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf subroutine lowest ( x , y , xs , ys , nleft , nright , w , userw , rw , ok ) ! Arguments real ( real64 ), intent ( in ), dimension (:) :: x , y , rw ! N ELEMENT real ( real64 ), intent ( in ) :: xs real ( real64 ), intent ( out ) :: ys integer ( int32 ), intent ( in ) :: nleft , nright real ( real64 ), intent ( out ), dimension (:) :: w ! N ELEMENT logical , intent ( in ) :: userw logical , intent ( out ) :: ok ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: p001 = 1.0d-3 real ( real64 ), parameter :: p999 = 0.999d0 ! Local Variables integer ( int32 ) :: j , n , nrt real ( real64 ) :: range , h , h9 , h1 , a , b , c , r ! Initialization n = size ( x ) range = x ( n ) - x ( 1 ) h = max ( xs - x ( nleft ), x ( nright ) - xs ) h9 = p999 * h h1 = p001 * h a = zero ! Process do j = nleft , n w ( j ) = zero r = abs ( x ( j ) - xs ) if ( r <= h9 ) then if ( r > h1 ) then w ( j ) = ( one - ( r / h ) ** 3 ) ** 3 else w ( j ) = one end if if ( userw ) w ( j ) = rw ( j ) * w ( j ) a = a + w ( j ) else if ( x ( j ) > xs ) then exit end if end do nrt = j - 1 if ( a <= zero ) then ok = . false . else ok = . true . w ( nleft : nrt ) = w ( nleft : nrt ) / a if ( h > zero ) then a = zero do j = nleft , nrt a = a + w ( j ) * x ( j ) end do b = xs - a c = zero do j = nleft , nrt c = c + w ( j ) * ( x ( j ) - a ) ** 2 end do if ( sqrt ( c ) > p001 * range ) then b = b / c do j = nleft , nrt w ( j ) = w ( j ) * ( one + b * ( x ( j ) - a )) end do end if end if ys = zero do j = nleft , nrt ys = ys + w ( j ) * y ( j ) end do end if end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_smoothing.f90.html"},{"title":"fstats.f90 – FSTATS","text":"Source Code module fstats !! FSTATS is a modern Fortran statistical library containing routines for !! computing basic statistical properties, hypothesis testing, regression, !! special functions, and experimental design. use iso_fortran_env use fstats_special_functions use fstats_descriptive_statistics use fstats_hypothesis use fstats_distributions use fstats_anova use fstats_helper_routines use fstats_regression use fstats_experimental_design use fstats_allan use fstats_bootstrap use fstats_sampling use fstats_smoothing implicit none private public :: distribution public :: distribution_function public :: distribution_property public :: t_distribution public :: normal_distribution public :: f_distribution public :: chi_squared_distribution public :: binomial_distribution public :: mean public :: variance public :: standard_deviation public :: median public :: covariance public :: r_squared public :: adjusted_r_squared public :: correlation public :: quantile public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test public :: anova public :: anova_factor public :: single_factor_anova_table public :: two_factor_anova_table public :: confidence_interval public :: beta public :: regularized_beta public :: incomplete_beta public :: digamma public :: incomplete_gamma_upper public :: incomplete_gamma_lower public :: coefficient_matrix public :: covariance_matrix public :: linear_least_squares public :: regression_statistics public :: get_full_factorial_matrix_size public :: full_factorial public :: iteration_controls public :: lm_solver_options public :: convergence_info public :: regression_function public :: iteration_update public :: jacobian public :: nonlinear_least_squares public :: allan_variance public :: trimmed_mean public :: difference public :: factorial public :: bootstrap_resampling_routine public :: bootstrap_statistic_routine public :: random_resample public :: scaled_random_resample public :: bootstrap_statistics public :: bootstrap public :: bootstrap_regression_statistics public :: bootstrap_linear_least_squares public :: bootstrap_nonlinear_least_squares public :: box_muller_sample public :: rejection_sample public :: lowess public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE end module","tags":"","loc":"sourcefile\\fstats.f90.html"},{"title":"fstats_experimental_design.f90 – FSTATS","text":"Source Code module fstats_experimental_design use iso_fortran_env use fstats_errors implicit none private public :: get_full_factorial_matrix_size public :: full_factorial contains ! ------------------------------------------------------------------------------ subroutine get_full_factorial_matrix_size ( vars , m , n , err ) !! Computes the appropriate size for a full-factorial design table. integer ( int32 ), intent ( in ) :: vars (:) !! An M-element array containing the M factors to study. Each !! of the M entries to the array is expected to contain the !! number of options for that particular factor to explore. !! This value must be greater than or equal to 1. integer ( int32 ), intent ( out ) :: m !! The number of rows for the table. integer ( int32 ), intent ( out ) :: n !! The number of columns for the table. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_INVALID_INPUT_ERROR: Occurs if any items in vars are !! less than 1. ! Local Variables integer ( int32 ) :: i class ( errors ), pointer :: errmgr type ( errors ), target :: deferr character ( len = 256 ) :: errmsg ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if m = 0 n = 0 ! Ensure every value is greater than 1 do i = 1 , size ( vars ) if ( vars ( i ) < 1 ) then write ( errmsg , 100 ) \"A value less than 1 was found at index \" , & i , \" of the input array. All values must be greater \" // & \"than or equal to 1.\" call errmgr % report_error ( \"get_full_factorial_matrix_size\" , & trim ( errmsg ), FS_INVALID_INPUT_ERROR ) return end if end do ! Process m = product ( vars ) n = size ( vars ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine full_factorial ( vars , tbl , err ) !! Computes a table with values scaled from 1 to N describing a !! full-factorial design. !! !! ```fortran !! program example !! use iso_fortran_env !! use fstats !! implicit none !! !! ! Local Variables !! integer(int32) :: i, vars(3), tbl(24, 3) !! !! ! Define the number of design points for each of the 3 factors to study !! vars = [2, 4, 3] !! !! ! Determine the design table !! call full_factorial(vars, tbl) !! !! ! Display the table !! do i = 1, size(tbl, 1) !! print *, tbl(i,:) !! end do !! end program !! ``` !! The above program produces the following output. !! ```text !! 1 1 1 !! 1 1 2 !! 1 1 3 !! 1 2 1 !! 1 2 2 !! 1 2 3 !! 1 3 1 !! 1 3 2 !! 1 3 3 !! 1 4 1 !! 1 4 2 !! 1 4 3 !! 2 1 1 !! 2 1 2 !! 2 1 3 !! 2 2 1 !! 2 2 2 !! 2 2 3 !! 2 3 1 !! 2 3 2 !! 2 3 3 !! 2 4 1 !! 2 4 2 !! 2 4 3 !! ``` integer ( int32 ), intent ( in ) :: vars (:) !! An M-element array containing the M factors to study. !! Each of the M entries to the array is expected to contain !! the number of options for that particular factor to explore. !! This value must be greater than or equal to 1. integer ( int32 ), intent ( out ) :: tbl (:,:) !! A table where the design will be written. Use !! get_full_factorial_matrix_size to determine the appropriate !! table size. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_INVALID_INPUT_ERROR: Occurs if any items in vars are !! less than 1. !! - FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized. ! Local Variables integer ( int32 ) :: i , col , stride , last , val , m , n class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Verify the size of the input table call get_full_factorial_matrix_size ( vars , m , n , errmgr ) if ( errmgr % has_error_occurred ()) return if ( size ( tbl , 1 ) /= m . or . size ( tbl , 2 ) /= n ) then call report_matrix_size_error ( errmgr , \"full_factorial\" , & \"tbl\" , m , n , size ( tbl , 1 ), size ( tbl , 2 )) return end if ! Process do col = 1 , n stride = 1 if ( col /= n ) stride = product ( vars ( col + 1 : n )) val = 1 do i = 1 , m , stride last = i + stride - 1 tbl ( i : last , col ) = val val = val + 1 if ( val > vars ( col )) val = 1 end do end do end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_experimental_design.f90.html"},{"title":"fstats_anova.f90 – FSTATS","text":"Source Code module fstats_anova use iso_fortran_env use ieee_arithmetic use fstats_special_functions use fstats_descriptive_statistics use ferror use fstats_errors implicit none private public :: anova_factor public :: single_factor_anova_table public :: two_factor_anova_table public :: anova type anova_factor !! Defines an ANOVA factor result. real ( real64 ) :: dof !! The number of degrees of freedome. real ( real64 ) :: variance !! The estimate of variance. real ( real64 ) :: sum_of_squares !! The sum of the squares. real ( real64 ) :: f_statistic !! The F-statistic. real ( real64 ) :: probability !! The variance probability term. end type type single_factor_anova_table !! Defines a single-factor ANOVA results table. type ( anova_factor ) :: main_factor !! The main, or main factor, results. type ( anova_factor ) :: within_factor !! The within-treatement (error) results. real ( real64 ) :: total_dof !! The total number of degrees of freedom. real ( real64 ) :: total_sum_of_squares !! The total sum of squares. real ( real64 ) :: total_variance !! The total variance estimate. real ( real64 ) :: overall_mean !! The overall mean value. end type type two_factor_anova_table !! Defines a two-factor ANOVA results table. type ( anova_factor ) :: main_factor_1 !! The first main-factor results. type ( anova_factor ) :: main_factor_2 !! The second main-factor results. type ( anova_factor ) :: interaction !! The interaction effects. type ( anova_factor ) :: within_factor !! The within (error) factor results. real ( real64 ) :: total_dof !! The total number of degrees of freedom. real ( real64 ) :: total_sum_of_squares !! The total sum of squares. real ( real64 ) :: total_variance !! The total variance estimate. real ( real64 ) :: overall_mean !! The overall mean value. end type interface anova !! Performs an analysis of variance (ANOVA) on the supplied data !! set. !! !! The following example illustrates a single-factor ANOVA on a !! data set. !! ```fortran !! program example !! use iso_fortran_env !! use fstats !! implicit none !! !! ! Local Variables !! character, parameter :: tab = achar(9) !! real(real64) :: x(10, 2) !! type(single_factor_anova_table) :: tbl !! !! ! Define the data !! x = reshape( & !! [ & !! 3.086d3, 3.082d3, 3.069d3, 3.072d3, 3.045d3, 3.070d3, 3.079d3, & !! 3.050d3, 3.062d3, 3.062d3, 3.075d3, 3.061d3, 3.063d3, 3.038d3, & !! 3.070d3, 3.062d3, 3.070d3, 3.049d3, 3.042d3, 3.063d3 & !! ], & !! [10, 2] & !! ) !! !! ! Perform the ANOVA !! tbl = anova(x) !! !! ! Print out the table !! print '(A)', \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & !! tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" !! print '(AF2.0AF5.1AF5.1AF5.3AF5.3)', \"Main Factor: \" // tab, & !! tbl%main_factor%dof, tab, & !! tbl%main_factor%sum_of_squares, tab // tab, & !! tbl%main_factor%variance, tab // tab, & !! tbl%main_factor%f_statistic, tab, & !! tbl%main_factor%probability !! !! print '(AF3.0AF6.1AF5.1)', \"Within: \" // tab, & !! tbl%within_factor%dof, tab, & !! tbl%within_factor%sum_of_squares, tab // tab, & !! tbl%within_factor%variance !! !! print '(AF3.0AF6.1AF5.1)', \"Total: \" // tab // tab, & !! tbl%total_dof, tab, & !! tbl%total_sum_of_squares, tab // tab, & !! tbl%total_variance !! !! print '(AF6.1)', \"Overall Mean: \", tbl%overall_mean !! end program !! ``` !! The above program produces the following output. !! ```text !! Description DOF Sum of Sq. Variance F-Stat P-Value !! Main Factor: 1. 352.8 352.8 2.147 0.160 !! Within: 18. 2958.2 164.3 !! Total: 19. 3311.0 174.3 !! Overall Mean: 3063.5 !! ``` !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Analysis_of_variance) !! - [SPC Excel Single Factor ANOVA](https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova) !! - [SPC Excel Gage R&R](https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1) !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) !! - [NIST - Two Way ANOVA](https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm) module procedure :: anova_1_factor module procedure :: anova_2_factor module procedure :: anova_model_fit end interface contains ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova function anova_1_factor ( x ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. real ( real64 ), intent ( in ) :: x (:,:) !! An M-by-N matrix containing the M replications of the N test !! points of interest. type ( single_factor_anova_table ) :: rst !! A single_factor_anova_table instance containing the ANOVA results. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 ! Local Variables integer ( int32 ) :: j , a , n , nt real ( real64 ) :: sum_all , tssq , essq , bssq ! Initialization a = size ( x , 2 ) nt = size ( x , 1 ) n = nt * a rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Determine the degrees of freedom rst % main_factor % dof = a - 1 rst % within_factor % dof = n - a rst % total_dof = n - 1 ! Quick Return if ( a == 1 . or . nt == 1 ) then rst % main_factor % sum_of_squares = zero rst % main_factor % variance = zero rst % main_factor % f_statistic = zero rst % main_factor % probability = zero rst % within_factor % sum_of_squares = zero rst % within_factor % variance = zero rst % total_variance = variance ( pack ( x , . true .)) rst % total_sum_of_squares = rst % total_variance * rst % total_dof rst % overall_mean = mean ( pack ( x , . true .)) return end if ! Compute the sum of squares for all factors sum_all = sum ( x ) tssq = sum ( x ** 2 ) - ( sum_all ** 2 / n ) bssq = zero do j = 1 , a bssq = bssq + sum ( x (:, j )) ** 2 end do bssq = ( bssq / nt ) - ( sum_all ** 2 / n ) essq = tssq - bssq rst % main_factor % sum_of_squares = bssq rst % within_factor % sum_of_squares = essq rst % total_sum_of_squares = tssq ! Compute the variance terms rst % main_factor % variance = bssq / rst % main_factor % dof rst % within_factor % variance = essq / rst % within_factor % dof rst % total_variance = tssq / rst % total_dof ! Compute the overall mean rst % overall_mean = mean ( pack ( x , . true .)) ! Compute the F-statistic and probability term call anova_probability ( & rst % main_factor % variance , & rst % within_factor % variance , & rst % main_factor % dof , & rst % within_factor % dof , & rst % main_factor % f_statistic , & rst % main_factor % probability & ) end function ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1 ! REF: https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm ! Data set is expected as a 3D array with each of the K pages containing the R ! treatments of N tests such that the array size is N-by-R-by-K function anova_2_factor ( x ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. real ( real64 ), intent ( in ) :: x (:,:,:) !! An M-by-N-by-K array containing the M replications of the !! N first factor results, and the K second factor results. type ( two_factor_anova_table ) :: rst !! A two_factor_anova_table instance containing the ANOVA results. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , j , jj , k , r , n real ( real64 ) :: factorMean , sum_all real ( real64 ), allocatable :: xpack (:) ! Initialization n = size ( x , 3 ) k = size ( x , 2 ) r = size ( x , 1 ) rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Quick Return if ( k == 1 ) then ! This is a one-factor anova end if ! Determine the number of DOF rst % main_factor_1 % dof = k - one rst % main_factor_2 % dof = n - 1 rst % interaction % dof = ( k - 1 ) * ( n - 1 ) rst % within_factor % dof = n * k * ( r - 1 ) rst % total_dof = n * k * r - 1 ! Compute the overall mean, sum of squares, and variance xpack = pack ( x , . true .) rst % overall_mean = mean ( xpack ) rst % total_sum_of_squares = sum (( xpack - rst % overall_mean ) ** 2 ) rst % total_variance = rst % total_sum_of_squares / rst % total_dof ! Compute factor 1 results rst % main_factor_1 % sum_of_squares = zero do i = 1 , k factorMean = mean ( pack ( x (:, i ,:), . true .)) rst % main_factor_1 % sum_of_squares = rst % main_factor_1 % sum_of_squares + & ( factorMean - rst % overall_mean ) ** 2 end do rst % main_factor_1 % sum_of_squares = n * r * rst % main_factor_1 % sum_of_squares rst % main_factor_1 % variance = rst % main_factor_1 % sum_of_squares / & rst % main_factor_1 % dof ! Compute factor 2 results rst % main_factor_2 % sum_of_squares = zero do i = 1 , n factorMean = mean ( pack ( x (:,:, i ), . true .)) rst % main_factor_2 % sum_of_squares = rst % main_factor_2 % sum_of_squares + & ( factorMean - rst % overall_mean ) ** 2 end do rst % main_factor_2 % sum_of_squares = k * r * rst % main_factor_2 % sum_of_squares rst % main_factor_2 % variance = rst % main_factor_2 % sum_of_squares / & rst % main_factor_2 % dof ! Compute the within (error) term rst % within_factor % sum_of_squares = zero do j = 1 , k do i = 1 , n factorMean = mean ( x (:, j , i )) do jj = 1 , r rst % within_factor % sum_of_squares = & rst % within_factor % sum_of_squares + & ( x ( jj , j , i ) - factorMean ) ** 2 end do end do end do rst % within_factor % variance = rst % within_factor % sum_of_squares / & rst % within_factor % dof ! Compute the interaction term rst % interaction % sum_of_squares = rst % total_sum_of_squares - ( & rst % main_factor_1 % sum_of_squares + & rst % main_factor_2 % sum_of_squares + & rst % within_factor % sum_of_squares & ) rst % interaction % variance = rst % interaction % sum_of_squares / & rst % interaction % dof ! Compute the F-statistics call anova_probability ( & rst % main_factor_1 % variance , & rst % within_factor % variance , & rst % main_factor_1 % dof , & rst % within_factor % dof , & rst % main_factor_1 % f_statistic , & rst % main_factor_1 % probability & ) call anova_probability ( & rst % main_factor_2 % variance , & rst % within_factor % variance , & rst % main_factor_2 % dof , & rst % within_factor % dof , & rst % main_factor_2 % f_statistic , & rst % main_factor_2 % probability & ) call anova_probability ( & rst % interaction % variance , & rst % within_factor % variance , & rst % interaction % dof , & rst % within_factor % dof , & rst % interaction % f_statistic , & rst % interaction % probability & ) end function ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1 function anova_model_fit ( nmodelparams , ymeas , ymod , err ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. integer ( int32 ), intent ( in ) :: nmodelparams !! The number of model parameters. real ( real64 ), intent ( in ) :: ymeas (:) !! An N-element array containing the measured dependent variable data. real ( real64 ), intent ( in ) :: ymod (:) !! An N-element array containing the modeled dependent variable data. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the !! same length. !! - FS_MEMORY_ERROR: Occurs if a memory error is encountered. type ( single_factor_anova_table ) :: rst !! A single_factor_anova_table instance containing the ANOVA results. ! Local Variables integer ( int32 ) :: n , flag real ( real64 ), allocatable :: ypack (:) real ( real64 ) :: sum_all class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization n = size ( ymeas ) if ( present ( err )) then errmgr => err else errmgr => deferr end if rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Input Checking if ( size ( ymod ) /= n ) then call report_arrays_not_same_size_error ( errmgr , \"anova_model_fit\" , & \"YMEAS\" , \"YMOD\" , n , size ( ymod )) return end if ! Memory Allocation allocate ( ypack ( 2 * n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"anova_model_fit\" , flag ) return end if ! Determine the number of DOF rst % main_factor % dof = nmodelparams - 1 rst % within_factor % dof = n - rst % main_factor % dof - 1 rst % total_dof = n - 1 ! Process ypack ( 1 : n ) = ymeas ypack ( n + 1 : 2 * n ) = ymod rst % overall_mean = mean ( ypack ) rst % total_sum_of_squares = sum (( ymeas - rst % overall_mean ) ** 2 ) rst % main_factor % sum_of_squares = sum (( ymod - rst % overall_mean ) ** 2 ) rst % within_factor % sum_of_squares = sum (( ymeas - ymod ) ** 2 ) rst % total_variance = rst % total_sum_of_squares / rst % total_dof rst % main_factor % variance = rst % main_factor % sum_of_squares / & rst % main_factor % dof rst % within_factor % variance = rst % within_factor % sum_of_squares / & rst % within_factor % dof ! Compute the F-statistic and probability term call anova_probability ( & rst % main_factor % variance , & rst % within_factor % variance , & rst % main_factor % dof , & rst % within_factor % dof , & rst % main_factor % f_statistic , & rst % main_factor % probability & ) ! Formatting 100 format ( A , I0 , A , I0 , A ) 101 format ( A , I0 , A ) end function ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ subroutine anova_probability ( v1 , v2 , dof1 , dof2 , f , p ) ! Arguments real ( real64 ), intent ( in ) :: v1 , v2 , dof1 , dof2 real ( real64 ), intent ( out ) :: f , p ! Local Variables real ( real64 ) :: d1 , d2 , a , b , x ! Process f = v1 / v2 d1 = dof1 d2 = dof2 a = 0.5d0 * d2 b = 0.5d0 * d1 x = d2 / ( d2 + d1 * f ) p = regularized_beta ( a , b , x ) if ( p > 1.0d0 ) then p = 2.0d0 - p end if end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_anova.f90.html"}]} \ No newline at end of file +var tipuesearch = {"pages":[{"title":" FSTATS ","text":"FSTATS Developer Info Jason Christopherson","tags":"home","loc":"index.html"},{"title":"bootstrap_regression_statistics – FSTATS ","text":"type, public :: bootstrap_regression_statistics A container for regression-related statistical information as \ncomputed in a bootstrap, or equivalent, calculation. Components Type Visibility Attributes Name Initial real(kind=real64), public :: lower_confidence_interval The lower limit of the confidence interval for the parameter. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. real(kind=real64), public :: upper_confidence_interval The upper limit of the confidence interval for the parameter.","tags":"","loc":"type\\bootstrap_regression_statistics.html"},{"title":"bootstrap_statistics – FSTATS ","text":"type, public :: bootstrap_statistics A collection of statistics resulting from the bootstrap process. Components Type Visibility Attributes Name Initial real(kind=real64), public :: bias The bias in the statistic. real(kind=real64), public :: lower_confidence_interval The lower confidence limit on the statistic. real(kind=real64), public, allocatable, dimension(:) :: population An array of the population values generated by the bootstrap\nprocess. real(kind=real64), public :: standard_error The standard error of the statistic. real(kind=real64), public :: statistic_value The value of the statistic of interest. real(kind=real64), public :: upper_confidence_interval The upper confidence limit on the statistic.","tags":"","loc":"type\\bootstrap_statistics.html"},{"title":"binomial_distribution – FSTATS ","text":"type, public, extends( distribution ) :: binomial_distribution Defines a binomial distribution. The binomial distribution describes\nthe probability p of getting k successes in n independent trials. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: n The number of independent trials. real(kind=real64), public :: p The success probability for each trial. This parameter must\nexist on the set [0, 1]. Type-Bound Procedures procedure, public :: cdf => bd_cdf private pure elemental function bd_cdf(this, x) result(rst) Computes the cumulative distribution funtion. The CDF for a binomial distribution is given as , which is simply\nthe regularized incomplete beta function. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. This parameter\nis the number k successes in the n independent trials. As\nsuch, this parameter must exist on the set [0, n]. Return Value real(kind=real64) The value of the function. procedure, public :: mean => bd_mean private pure function bd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => bd_median private pure function bd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => bd_mode private pure function bd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => bd_pdf private pure elemental function bd_pdf(this, x) result(rst) Computes the probability mass function. The PMF for a binomial distribution is given as . Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. This parameter\nis the number k successes in the n independent trials. As\nsuch, this parameter must exist on the set [0, n]. Return Value real(kind=real64) The value of the function. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure, public :: variance => bd_variance private pure function bd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( binomial_distribution ), intent(in) :: this The binomial_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\binomial_distribution.html"},{"title":"chi_squared_distribution – FSTATS ","text":"type, public, extends( distribution ) :: chi_squared_distribution Defines a Chi-squared distribution. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => cs_cdf private pure elemental function cs_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a Chi-squared distribution is given as . Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => cs_mean private pure function cs_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => cs_median private pure function cs_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => cs_mode private pure function cs_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => cs_pdf private pure elemental function cs_pdf(this, x) result(rst) Computes the probability density function. The PDF for a Chi-squared distribution is given as . Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure, public :: variance => cs_variance private pure function cs_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( chi_squared_distribution ), intent(in) :: this The chi_squared_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\chi_squared_distribution.html"},{"title":"distribution – FSTATS ","text":"type, public :: distribution Defines a probability distribution. Type-Bound Procedures procedure( distribution_function ), public, deferred, pass :: cdf Computes the cumulative distribution function. pure elemental function distribution_function(this, x) result(rst) Prototype Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure( distribution_property ), public, deferred, pass :: mean Computes the mean of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_property ), public, deferred, pass :: median Computes the median of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_property ), public, deferred, pass :: mode Computes the mode of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. procedure( distribution_function ), public, deferred, pass :: pdf Computes the probability density function. pure elemental function distribution_function(this, x) result(rst) Prototype Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure( distribution_property ), public, deferred, pass :: variance Computes the variance of the distribution. pure function distribution_property(this) result(rst) Prototype Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value.","tags":"","loc":"type\\distribution.html"},{"title":"f_distribution – FSTATS ","text":"type, public, extends( distribution ) :: f_distribution Defines an F-distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: d1 The measure of degrees of freedom for the first data set. real(kind=real64), public :: d2 The measure of degrees of freedom for the second data set. Type-Bound Procedures procedure, public :: cdf => fd_cdf private pure elemental function fd_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a F distribution is given as . Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => fd_mean private pure function fd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => fd_median private pure function fd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => fd_mode private pure function fd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => fd_pdf private pure elemental function fd_pdf(this, x) result(rst) Computes the probability density function. The PDF for a F distribution is given as . Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure, public :: variance => fd_variance private pure function fd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( f_distribution ), intent(in) :: this The f_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\f_distribution.html"},{"title":"normal_distribution – FSTATS ","text":"type, public, extends( distribution ) :: normal_distribution Defines a normal distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: mean_value The mean value of the distribution. real(kind=real64), public :: standard_deviation The standard deviation of the distribution. Type-Bound Procedures procedure, public :: cdf => nd_cdf private pure elemental function nd_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for a normal distribution is given as . Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => nd_mean private pure function nd_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The mean procedure, public :: median => nd_median private pure function nd_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The median. procedure, public :: mode => nd_mode private pure function nd_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => nd_pdf private pure elemental function nd_pdf(this, x) result(rst) Computes the probability density function. The PDF for a normal distribution is given as . Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardize => nd_standardize private subroutine nd_standardize(this) Standardizes the normal distribution to a mean of 0 and a \nstandard deviation of 1. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(inout) :: this The normal_distribution object. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure, public :: variance => nd_variance private pure function nd_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( normal_distribution ), intent(in) :: this The normal_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\normal_distribution.html"},{"title":"t_distribution – FSTATS ","text":"type, public, extends( distribution ) :: t_distribution Defines Student's T-Distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => td_cdf private pure elemental function td_cdf(this, x) result(rst) Computes the cumulative distribution function. The CDF for Student's T-Distribution is given as where . Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: mean => td_mean private pure function td_mean(this) result(rst) Computes the mean of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The mean. procedure, public :: median => td_median private pure function td_median(this) result(rst) Computes the median of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) procedure, public :: mode => td_mode private pure function td_mode(this) result(rst) Computes the mode of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The mode. procedure, public :: pdf => td_pdf private pure elemental function td_pdf(this, x) result(rst) Computes the probability density function. The PDF for Student's T-Distribution is given as . Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. procedure, public :: standardized_variable => dist_std_var Computes the standardized variable for the distribution. private pure elemental function dist_std_var(this, x) result(rst) Computes the standardized variable for the distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value of interest. Return Value real(kind=real64) The result. procedure, public :: variance => td_variance private pure function td_variance(this) result(rst) Computes the variance of the distribution. Arguments Type Intent Optional Attributes Name class( t_distribution ), intent(in) :: this The t_distribution object. Return Value real(kind=real64) The variance.","tags":"","loc":"type\\t_distribution.html"},{"title":"array_container – FSTATS ","text":"type, public :: array_container Provides a container for a real-valued array. A practical use of\nthis construct is in the construction of jagged arrays. Components Type Visibility Attributes Name Initial real(kind=real64), public, allocatable, dimension(:) :: x The array.","tags":"","loc":"type\\array_container.html"},{"title":"convergence_info – FSTATS ","text":"type, public :: convergence_info Provides information regarding convergence status. Components Type Visibility Attributes Name Initial logical, public :: converge_on_gradient True if convergence on the gradient was achieved; else, false. logical, public :: converge_on_residual_parameter True if convergence on the residual error parameter was achieved; \nelse, false. logical, public :: converge_on_solution_change True if convergence on the change in solution was achieved; else,\nfalse. integer(kind=int32), public :: function_evaluation_count The function evaluation count. real(kind=real64), public :: gradient_value The value of the gradient test parameter. integer(kind=int32), public :: iteration_count The iteration count. logical, public :: reach_function_evaluation_limit True if the solution did not converge in the allowed number of\nfunction evaluations. logical, public :: reach_iteration_limit True if the solution did not converge in the allowed number of \niterations. real(kind=real64), public :: residual_value The value of the residual error parameter. real(kind=real64), public :: solution_change_value The value of the change in solution parameter. logical, public :: user_requested_stop True if the user requested the stop; else, false.","tags":"","loc":"type\\convergence_info.html"},{"title":"iteration_controls – FSTATS ","text":"type, public :: iteration_controls Provides a collection of iteration control parameters. Components Type Visibility Attributes Name Initial real(kind=real64), public :: change_in_solution_tolerance Defines a tolerance on the change in parameter values. real(kind=real64), public :: gradient_tolerance Defines a tolerance on the gradient of the fitted function. real(kind=real64), public :: iteration_improvement_tolerance Defines a tolerance to ensure adequate improvement on each \niteration. integer(kind=int32), public :: max_function_evaluations Defines the maximum number of function evaluations allowed. integer(kind=int32), public :: max_iteration_between_updates Defines how many iterations can pass before a re-evaluation of \nthe Jacobian matrix is forced. integer(kind=int32), public :: max_iteration_count Defines the maximum number of iterations allowed. real(kind=real64), public :: residual_tolerance Defines a tolerance on the metric associated with the residual \nerror. Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_tolerances private subroutine lm_set_default_tolerances(x) Arguments Type Intent Optional Attributes Name class( iteration_controls ), intent(inout) :: x","tags":"","loc":"type\\iteration_controls.html"},{"title":"lm_solver_options – FSTATS ","text":"type, public :: lm_solver_options Options to control the Levenberg-Marquardt solver. Components Type Visibility Attributes Name Initial real(kind=real64), public :: damping_decrease_factor The factor to use when decreasing the damping parameter. real(kind=real64), public :: damping_increase_factor The factor to use when increasing the damping parameter. real(kind=real64), public :: finite_difference_step_size The step size used for the finite difference calculations of the\nJacobian matrix. integer(kind=int32), public :: method The solver method to utilize.\n- FS_LEVENBERG_MARQUARDT_UPDATE:\n- FS_QUADRATIC_UPDATE:\n- FS_NIELSEN_UDPATE: Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_settings private subroutine lm_set_default_settings(x) Arguments Type Intent Optional Attributes Name class( lm_solver_options ), intent(inout) :: x","tags":"","loc":"type\\lm_solver_options.html"},{"title":"regression_statistics – FSTATS ","text":"type, public :: regression_statistics A container for regression-related statistical information. Components Type Visibility Attributes Name Initial real(kind=real64), public :: confidence_interval The confidence interval for the parameter at the level \ndetermined by the regression process. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient.","tags":"","loc":"type\\regression_statistics.html"},{"title":"anova_factor – FSTATS ","text":"type, public :: anova_factor Defines an ANOVA factor result. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedome. real(kind=real64), public :: f_statistic The F-statistic. real(kind=real64), public :: probability The variance probability term. real(kind=real64), public :: sum_of_squares The sum of the squares. real(kind=real64), public :: variance The estimate of variance.","tags":"","loc":"type\\anova_factor.html"},{"title":"single_factor_anova_table – FSTATS ","text":"type, public :: single_factor_anova_table Defines a single-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: main_factor The main, or main factor, results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within-treatement (error) results.","tags":"","loc":"type\\single_factor_anova_table.html"},{"title":"two_factor_anova_table – FSTATS ","text":"type, public :: two_factor_anova_table Defines a two-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: interaction The interaction effects. type( anova_factor ), public :: main_factor_1 The first main-factor results. type( anova_factor ), public :: main_factor_2 The second main-factor results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within (error) factor results.","tags":"","loc":"type\\two_factor_anova_table.html"},{"title":"difference – FSTATS","text":"public pure function difference(x) result(rst) Computes the difference between elements in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array on which to operate. Return Value real(kind=real64), allocatable, dimension(:) The (N-1)-element array containing the differences between adjacent\nelements.","tags":"","loc":"proc\\difference.html"},{"title":"factorial – FSTATS","text":"public pure elemental function factorial(x) result(rst) Computes the factorial of X. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value whose factorial is to be computed. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\factorial.html"},{"title":"bootstrap – FSTATS","text":"public function bootstrap(stat, x, method, nsamples, alpha) result(rst) Performs a bootstrap calculation on the supplied data set for the given\nstatistic. The default implementation utlizes a random resampling with \nreplacement. Other resampling methods may be defined by specifying an \nappropriate routine by means of the method input. Arguments Type Intent Optional Attributes Name procedure( bootstrap_statistic_routine ), intent(in), pointer :: stat The routine used to compute the desired statistic. real(kind=real64), intent(in), dimension(:) :: x The N-element data set. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. integer(kind=int32), intent(in), optional :: nsamples An optional input, that if supplied, specifies the number of \nresampling runs to perform. The default is 10 000. real(kind=real64), intent(in), optional :: alpha An optional input, that if supplied, defines the significance level\nto use for the analysis. The default is 0.05. Return Value type( bootstrap_statistics ) The resulting bootstrap_statistics type containing the confidence\nintervals, bias, standard error, etc. for the analyzed statistic.","tags":"","loc":"proc\\bootstrap.html"},{"title":"bootstrap_linear_least_squares – FSTATS","text":"public subroutine bootstrap_linear_least_squares(order, intercept, x, y, coeffs, ymod, resid, nsamples, stats, bias, alpha, method, bscoeffs, err) Computes a linear least-squares regression to fit a set of data.\nBootstrapping is utilized to gain insight into the quality of \nthe fit. Resampling for the bootstrap process is a random resampling \nwith replacement process with the range of values limited by the \nstandard deviation of the original data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out), dimension(:) :: coeffs An ORDER+1 element array where the coefficients will\nbe written. real(kind=real64), intent(out), dimension(:) :: ymod An N-element array where the modeled data will be written. real(kind=real64), intent(out), dimension(:) :: resid An N-element array where the residual error data will be \nwritten (modeled - actual). integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. type( bootstrap_regression_statistics ), intent(out), optional, dimension(:) :: stats An M-element array of bootstrap_regression_statistics items \nwhere M = ORDER + 1 when intercept is set to true; however, \nif intercept is set to false, M = ORDER. real(kind=real64), intent(out), optional, dimension(:) :: bias An ORDER+1 element array where an estimate of the bias of\neach coefficient is returned based upon the results of the\nbootstrapping analysis. The bias is computed as the difference \nbetween the mean of the boostrap population results for the given \nparameter and the original estimate of the given parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\bootstrap_linear_least_squares.html"},{"title":"bootstrap_nonlinear_least_squares – FSTATS","text":"public subroutine bootstrap_nonlinear_least_squares(fun, x, y, params, ymod, resid, nsamples, weights, maxp, minp, stats, alpha, controls, settings, info, bias, method, bscoeffs, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain \ninsight into the quality of the fit. Resampling for the bootstrap \nprocess is a random resampling with replacement process with the \nrange of values limited by the standard deviation of the original \ndata set. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( bootstrap_regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. real(kind=real64), intent(out), optional, dimension(:) :: bias An optional N-element array that, if supplied, will be used to \nprovide an estimate of the bias of each model parameter based upon\nthe results of the bootstrapping analysis. The bias is computed as \nthe difference between the mean of the boostrap population results \nfor the given parameter and the original estimate of the given \nparameter. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"proc\\bootstrap_nonlinear_least_squares.html"},{"title":"random_resample – FSTATS","text":"public subroutine random_resample(x, xn) Random resampling, with replacement, based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"proc\\random_resample.html"},{"title":"scaled_random_resample – FSTATS","text":"public subroutine scaled_random_resample(x, xn) A random resampling, scaled by the standard deviation of the original\ndata, but based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"proc\\scaled_random_resample.html"},{"title":"bootstrap_resampling_routine – FSTATS","text":"interface public subroutine bootstrap_resampling_routine(x, xn) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be \nwritten. Description Defines the signature of a subroutine used to compute a \nresampling of data for bootstrapping purposes.","tags":"","loc":"interface\\bootstrap_resampling_routine.html"},{"title":"bootstrap_statistic_routine – FSTATS","text":"interface public function bootstrap_statistic_routine(x) result(rst) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The array of data to analyze. Return Value real(kind=real64) The resulting statistic. Description Defines the signature of a function for computing the desired\nbootstrap statistic.","tags":"","loc":"interface\\bootstrap_statistic_routine.html"},{"title":"full_factorial – FSTATS","text":"public subroutine full_factorial(vars, tbl, err) Computes a table with values scaled from 1 to N describing a \nfull-factorial design. program example use iso_fortran_env use fstats implicit none ! Local Variables integer ( int32 ) :: i , vars ( 3 ), tbl ( 24 , 3 ) ! Define the number of design points for each of the 3 factors to study vars = [ 2 , 4 , 3 ] ! Determine the design table call full_factorial ( vars , tbl ) ! Display the table do i = 1 , size ( tbl , 1 ) print * , tbl ( i ,:) end do end program The above program produces the following output. 1 1 1\n1 1 2\n1 1 3\n1 2 1\n1 2 2\n1 2 3\n1 3 1\n1 3 2\n1 3 3\n1 4 1\n1 4 2\n1 4 3\n2 1 1\n2 1 2\n2 1 3\n2 2 1\n2 2 2\n2 2 3\n2 3 1\n2 3 2\n2 3 3\n2 4 1\n2 4 2\n2 4 3 Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each of the M entries to the array is expected to contain \nthe number of options for that particular factor to explore. \nThis value must be greater than or equal to 1. integer(kind=int32), intent(out) :: tbl (:,:) A table where the design will be written. Use \nget_full_factorial_matrix_size to determine the appropriate \ntable size. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.\n- FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized.","tags":"","loc":"proc\\full_factorial.html"},{"title":"get_full_factorial_matrix_size – FSTATS","text":"public subroutine get_full_factorial_matrix_size(vars, m, n, err) Computes the appropriate size for a full-factorial design table. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each \nof the M entries to the array is expected to contain the \nnumber of options for that particular factor to explore. This value must be greater than or equal to 1. integer(kind=int32), intent(out) :: m The number of rows for the table. integer(kind=int32), intent(out) :: n The number of columns for the table. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.","tags":"","loc":"proc\\get_full_factorial_matrix_size.html"},{"title":"allan_variance – FSTATS","text":"public function allan_variance(x, dt, err) result(rst) Computes the Allan variance of a data set. Remarks This implementation computes the fully overlapped Allan variance \nusing the method presented by Yadav et. al. Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, \nViraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm \nfor Fully Overlapped Allan Variance and Total Variance for Analysis and \nModeling of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. \n10.1109/LSENS.2018.2829799. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element data set to analyze. real(kind=real64), intent(in), optional :: dt An optional input specifying the time increment between \nsamples in x. If not specified, this value is set to 1. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value real(kind=real64), allocatable, dimension(:,:) An M-by-2 array containing the results where M is N / 2 - 1\nif N is even; else, M is (N - 1) / 2 - 1 if N is odd. The \nfirst column contains the averaging times associated with \nthe M results stored in the second column.","tags":"","loc":"proc\\allan_variance.html"},{"title":"distribution_function – FSTATS","text":"interface public pure elemental function distribution_function(this, x) result(rst) Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. Description Defines the interface for a probability distribution function.","tags":"","loc":"interface\\distribution_function.html"},{"title":"distribution_property – FSTATS","text":"interface public pure function distribution_property(this) result(rst) Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. Description Computes the value of a distribution property.","tags":"","loc":"interface\\distribution_property.html"},{"title":"adjusted_r_squared – FSTATS","text":"public function adjusted_r_squared(p, x, xm, err) result(rst) Computes the adjusted R-squared value for a data set. The adjusted R-squared provides a mechanism for tempering the effects\nof extra explanatory variables on the traditional R-squared \ncalculation. It is computed by noting the sample size and \nthe number of variables . . See Also: Wikipedia Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: p The number of variables. real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\adjusted_r_squared.html"},{"title":"calculate_regression_statistics – FSTATS","text":"public function calculate_regression_statistics(resid, params, c, alpha, err) result(rst) Computes statistics for the quality of fit for a regression \nmodel. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: resid (:) An M-element array containing the model residual errors. real(kind=real64), intent(in) :: params (:) An N-element array containing the model parameters. real(kind=real64), intent(in) :: c (:,:) The N-by-N covariance matrix. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value type( regression_statistics ), allocatable, (:) A regression_statistics object containing the analysis results.","tags":"","loc":"proc\\calculate_regression_statistics.html"},{"title":"correlation – FSTATS","text":"public pure function correlation(x, y) result(rst) Computes the sample correlation coefficient (an estimate to the \npopulation Pearson correlation) as follows. . Where, & are the sample standard deviations of\nx and y respectively. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The correlation coefficient.","tags":"","loc":"proc\\correlation.html"},{"title":"r_squared – FSTATS","text":"public function r_squared(x, xm, err) result(rst) Computes the R-squared value for a data set. The R-squared value is computed by determining the sum of the squares\nof the residuals: The total sum of the squares: . \nThe R-squared value is then: . See Also: Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\r_squared.html"},{"title":"covariance_matrix – FSTATS","text":"public subroutine covariance_matrix(x, c, err) Computes the covariance matrix where and is computed\nby design_matrix. See Also Wikipedia Wikipedia - Regression Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the formatted independent data\n matrix as computed by design_matrix. real(kind=real64), intent(out) :: c (:,:) The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not \n sized correctly.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\covariance_matrix.html"},{"title":"design_matrix – FSTATS","text":"public subroutine design_matrix(order, intercept, x, c, err) Computes the design matrix for the linear \nleast-squares regression problem of , where is the matrix computed here, is \nthe vector of coefficients to be determined, and is the \nvector of measured dependent variables. See Also Wikipedia Wikipedia Wikipedia Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be\nat least one (linear equation), but can be higher as desired. logical, intent(in) :: intercept Set to true if the intercept is being computed\nas part of the regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(out) :: c (:,:) An N-by-K matrix where the results will be written. K\nmust equal order + 1 in the event intercept is true; \nhowever, if intercept is false, K must equal order. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.","tags":"","loc":"proc\\design_matrix.html"},{"title":"jacobian – FSTATS","text":"public subroutine jacobian(fun, xdata, params, jac, stop, f0, f1, step, err) Computes the Jacobian matrix for a nonlinear regression problem. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: xdata (:) The M-element array containing x-coordinate data. real(kind=real64), intent(in) :: params (:) The N-element array containing the model parameters. real(kind=real64), intent(out) :: jac (:,:) The M-by-N matrix where the Jacobian will be written. logical, intent(out) :: stop A value that the user can set in fun forcing the\nevaluation process to stop prior to completion. real(kind=real64), intent(in), optional, target :: f0 (:) An optional M-element array containing the model values\n using the current parameters as defined in m. This input \ncan be used to prevent the routine from performing a \nfunction evaluation at the model parameter state defined in \nparams. real(kind=real64), intent(out), optional, target :: f1 (:) An optional M-element workspace array used for function\nevaluations. real(kind=real64), intent(in), optional :: step The differentiation step size. The default is the square \nroot of machine precision. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\jacobian.html"},{"title":"linear_least_squares – FSTATS","text":"public subroutine linear_least_squares(order, intercept, x, y, coeffs, ymod, resid, stats, alpha, err) Computes a linear least-squares regression to fit a set of data. See Also Wikipedia SPC Excel Understanding Regression Statistics Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in) :: y (:) An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out) :: coeffs (:) An ORDER+1 element array where the coefficients will be written. real(kind=real64), intent(out) :: ymod (:) An N-element array where the modeled data will be written. real(kind=real64), intent(out) :: resid (:) An N-element array where the residual error data will be \nwritten (modeled - actual). type( regression_statistics ), intent(out), optional :: stats (:) An M-element array of regression_statistics items where \nM = ORDER + 1 when intercept is set to true; however, if \nintercept is set to false, M = ORDER. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.","tags":"","loc":"proc\\linear_least_squares.html"},{"title":"nonlinear_least_squares – FSTATS","text":"public subroutine nonlinear_least_squares(fun, x, y, params, ymod, resid, weights, maxp, minp, stats, alpha, controls, settings, info, status, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. procedure( iteration_update ), intent(in), optional, pointer :: status An optional pointer to a routine that can be used to extract\niteration information. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"proc\\nonlinear_least_squares.html"},{"title":"iteration_update – FSTATS","text":"interface public subroutine iteration_update(iter, funvals, resid, params, step) Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: iter real(kind=real64), intent(in) :: funvals (:) real(kind=real64), intent(in) :: resid (:) real(kind=real64), intent(in) :: params (:) real(kind=real64), intent(in) :: step (:)","tags":"","loc":"interface\\iteration_update.html"},{"title":"regression_function – FSTATS","text":"interface public subroutine regression_function(xdata, params, resid, stop) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: xdata real(kind=real64), intent(in), dimension(:) :: params real(kind=real64), intent(out), dimension(:) :: resid logical, intent(out) :: stop","tags":"","loc":"interface\\regression_function.html"},{"title":"anova – FSTATS","text":"public interface anova Performs an analysis of variance (ANOVA) on the supplied data \nset. The following example illustrates a single-factor ANOVA on a \ndata set. program example use iso_fortran_env use fstats implicit none ! Local Variables character , parameter :: tab = achar ( 9 ) real ( real64 ) :: x ( 10 , 2 ) type ( single_factor_anova_table ) :: tbl ! Define the data x = reshape ( & [ & 3.086d3 , 3.082d3 , 3.069d3 , 3.072d3 , 3.045d3 , 3.070d3 , 3.079d3 , & 3.050d3 , 3.062d3 , 3.062d3 , 3.075d3 , 3.061d3 , 3.063d3 , 3.038d3 , & 3.070d3 , 3.062d3 , 3.070d3 , 3.049d3 , 3.042d3 , 3.063d3 & ], & [ 10 , 2 ] & ) ! Perform the ANOVA tbl = anova ( x ) ! Print out the table print '(A)' , \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" print '(AF2.0AF5.1AF5.1AF5.3AF5.3)' , \"Main Factor: \" // tab , & tbl % main_factor % dof , tab , & tbl % main_factor % sum_of_squares , tab // tab , & tbl % main_factor % variance , tab // tab , & tbl % main_factor % f_statistic , tab , & tbl % main_factor % probability print '(AF3.0AF6.1AF5.1)' , \"Within: \" // tab , & tbl % within_factor % dof , tab , & tbl % within_factor % sum_of_squares , tab // tab , & tbl % within_factor % variance print '(AF3.0AF6.1AF5.1)' , \"Total: \" // tab // tab , & tbl % total_dof , tab , & tbl % total_sum_of_squares , tab // tab , & tbl % total_variance print '(AF6.1)' , \"Overall Mean: \" , tbl % overall_mean end program The above program produces the following output. Description DOF Sum of Sq. Variance F-Stat P-Value\nMain Factor: 1. 352.8 352.8 2.147 0.160\nWithin: 18. 2958.2 164.3\nTotal: 19. 3311.0 174.3\nOverall Mean: 3063.5 See Also Wikipedia SPC Excel Single Factor ANOVA SPC Excel Gage R&R SPC Excel Understanding Regression Statistics NIST - Two Way ANOVA Module Procedures private function anova_1_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the M replications of the N test \npoints of interest. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. private function anova_2_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:,:) An M-by-N-by-K array containing the M replications of the\nN first factor results, and the K second factor results. Return Value type( two_factor_anova_table ) A two_factor_anova_table instance containing the ANOVA results. private function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: nmodelparams The number of model parameters. real(kind=real64), intent(in) :: ymeas (:) An N-element array containing the measured dependent variable data. real(kind=real64), intent(in) :: ymod (:) An N-element array containing the modeled dependent variable data. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the \n same length.\n- FS_MEMORY_ERROR: Occurs if a memory error is encountered. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results.","tags":"","loc":"interface\\anova.html"},{"title":"covariance – FSTATS","text":"public pure function covariance(x, y) result(rst) Computes the sample covariance of two data sets. The covariance computed is the sample covariance such that . Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The covariance.","tags":"","loc":"proc\\covariance.html"},{"title":"mean – FSTATS","text":"public pure function mean(x) result(rst) Computes the mean of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\mean.html"},{"title":"median – FSTATS","text":"public function median(x) result(rst) Computes the median of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout) :: x (:) The array of values to analyze. On output, this array is sorted into\nascending order. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\median.html"},{"title":"quantile – FSTATS","text":"public pure function quantile(x, q) result(rst) Computes the specified quantile of a data set using the SAS \nMethod 4. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the data. real(kind=real64), intent(in) :: q The quantile to compute (e.g. 0.25 computes the 25% quantile). Return Value real(kind=real64) The result.","tags":"","loc":"proc\\quantile.html"},{"title":"standard_deviation – FSTATS","text":"public pure function standard_deviation(x) result(rst) Computes the sample standard deviation of the values in an array. The value computed is the sample standard deviation. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"proc\\standard_deviation.html"},{"title":"trimmed_mean – FSTATS","text":"public function trimmed_mean(x, p) result(rst) Computes the trimmed mean of a data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout), dimension(:) :: x An N-element array containing the data. On output, the\narray is sorted into ascending order. real(kind=real64), intent(in), optional :: p An optional parameter specifying the percentage of values\nfrom either end of the distribution to remove. The default\nis 0.05 such that the bottom 5% and top 5% are removed. Return Value real(kind=real64) The trimmed mean.","tags":"","loc":"proc\\trimmed_mean.html"},{"title":"variance – FSTATS","text":"public pure function variance(x) result(rst) Computes the sample variance of the values in an array. The variance computed is the sample variance such that . Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64)","tags":"","loc":"proc\\variance.html"},{"title":"pooled_variance – FSTATS","text":"public interface pooled_variance Computes the pooled estimate of variance. Module Procedures private pure function pooled_variance_1(si, ni) result(rst) Computes the pooled estimate of variance. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: si An N-element array containing the estimates for each of the N\nvariances. integer(kind=int32), intent(in), dimension(size(si)) :: ni An N-element array containing the number of data points in each\nof the data sets used to compute the variances in si. Return Value real(kind=real64) The pooled variance. private pure function pooled_variance_2(x) result(rst) Computes the pooled estimate of variance. Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x An array of arrays of data. Return Value real(kind=real64) The pooled variance.","tags":"","loc":"interface\\pooled_variance.html"},{"title":"report_array_size_error – FSTATS","text":"public subroutine report_array_size_error(err, fname, name, expect, actual) Reports an array size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the array. integer(kind=int32), intent(in) :: expect The expected size of the array. integer(kind=int32), intent(in) :: actual The actual size of the array. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_array_size_error.html"},{"title":"report_arrays_not_same_size_error – FSTATS","text":"public subroutine report_arrays_not_same_size_error(err, fname, name1, name2, size1, size2) Reports an error relating to two arrays not being the same size\nwhen they should be the same size. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name1 The name of the first array. character(len=*), intent(in) :: name2 The name of the second array. integer(kind=int32), intent(in) :: size1 The size of the first array. integer(kind=int32), intent(in) :: size2 The size of the second array. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_arrays_not_same_size_error.html"},{"title":"report_iteration_count_error – FSTATS","text":"public subroutine report_iteration_count_error(err, fname, msg, mincount) Reports an iteration count error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*) :: fname The name of the routine in which the error occurred. character(len=*) :: msg The error message. integer(kind=int32), intent(in) :: mincount The minimum iteration count expected. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: emsg","tags":"","loc":"proc\\report_iteration_count_error.html"},{"title":"report_matrix_size_error – FSTATS","text":"public subroutine report_matrix_size_error(err, fname, name, expect_rows, expect_cols, actual_rows, actual_cols) Reports a matrix size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the matrix. integer(kind=int32), intent(in) :: expect_rows The expected number of rows. integer(kind=int32), intent(in) :: expect_cols The expected number of columns. integer(kind=int32), intent(in) :: actual_rows The actual number of rows. integer(kind=int32), intent(in) :: actual_cols The actual number of columns. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_matrix_size_error.html"},{"title":"report_memory_error – FSTATS","text":"public subroutine report_memory_error(err, fname, code) Reports a memory allocation related error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: code The error code returned by the allocation routine. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_memory_error.html"},{"title":"report_underdefined_error – FSTATS","text":"public subroutine report_underdefined_error(err, fname, expect, actual) Reports an underdefined problem error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: expect The expected minimum number of equations. integer(kind=int32), intent(in) :: actual The actual number of equations. Variables Type Visibility Attributes Name Initial character(len=MESSAGE_SIZE), public :: msg","tags":"","loc":"proc\\report_underdefined_error.html"},{"title":"lowess – FSTATS","text":"public subroutine lowess(x, y, ys, fsmooth, nstps, del, rweights, resid, err) Computes the smoothing of a data set using a robust locally weighted\nscatterplot smoothing (LOWESS) algorithm. Fitted values are computed at\neach of the supplied x values. Remarks The code is a reimplementation of the LOWESS library. For a detailed\nunderstanding, see [this]\n(http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf) \npaper by William Cleveland. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable data. This\narray must be monotonically increasing. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable data. real(kind=real64), intent(out), dimension(:) :: ys An N-element array where the smoothed results will be written. real(kind=real64), intent(in), optional :: fsmooth An optional input that specifies the amount of smoothing. Specifically, this value is the fraction of points used to compute\neach value. As this value increases, the output becomes smoother.\nChoosing a value in the range of 0.2 to 0.8 typically results in a\ngood fit. The default value is 0.2. integer(kind=int32), intent(in), optional :: nstps An optional input that specifies the numb of iterations. If set to\nzero, a non-robust fit is returned. The default value is set to 2. real(kind=real64), intent(in), optional :: del real(kind=real64), intent(out), optional, dimension(:), target :: rweights An optional N-element array, that if supplied, will be used to\nreturn the weights given to each data point. real(kind=real64), intent(out), optional, dimension(:), target :: resid An optional N-element array, that if supplied, will be used to \nreturn the residual. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation error.","tags":"","loc":"proc\\lowess.html"},{"title":"beta – FSTATS","text":"public pure elemental function beta(a, b) result(rst) Computes the beta function. The beta function is related to the gamma function\nby the following relationship. . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. Return Value real(kind=real64) The value of the beta function at and .","tags":"","loc":"proc\\beta.html"},{"title":"digamma – FSTATS","text":"public pure elemental function digamma(x) result(rst) Computes the digamma function. The digamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\digamma.html"},{"title":"incomplete_beta – FSTATS","text":"public pure elemental function incomplete_beta(a, b, x) result(rst) Computes the incomplete beta function. The incomplete beta function is defind as: . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the incomplete beta function.","tags":"","loc":"proc\\incomplete_beta.html"},{"title":"incomplete_gamma_lower – FSTATS","text":"public pure elemental function incomplete_gamma_lower(a, x) result(rst) Computes the lower incomplete gamma function. The lower incomplete gamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\incomplete_gamma_lower.html"},{"title":"incomplete_gamma_upper – FSTATS","text":"public pure elemental function incomplete_gamma_upper(a, x) result(rst) Computes the upper incomplete gamma function. The upper incomplete gamma function is defined as: See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value.","tags":"","loc":"proc\\incomplete_gamma_upper.html"},{"title":"regularized_beta – FSTATS","text":"public pure elemental function regularized_beta(a, b, x) result(rst) Computes the regularized beta function. The regularized beta function is defined as the ratio between\nthe incomplete beta function and the beta function. . See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the regularized beta function.","tags":"","loc":"proc\\regularized_beta.html"},{"title":"rejection_sample – FSTATS","text":"public function rejection_sample(tdist, n, xmin, xmax) result(rst) Uses rejection sampling to randomly sample a target distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: tdist The distribution to sample integer(kind=int32), intent(in) :: n The number of samples to make. real(kind=real64), intent(in) :: xmin The minimum range to explore. real(kind=real64), intent(in) :: xmax The maximum range to explore. Return Value real(kind=real64), allocatable, dimension(:) An N-element array containing the N samples from the \ndistribution.","tags":"","loc":"proc\\rejection_sample.html"},{"title":"box_muller_sample – FSTATS","text":"public interface box_muller_sample Generates random, normally distributed values via the Box-Muller \ntransform. Module Procedures private function box_muller_sample_scalar(mu, sigma) result(rst) Generates a pair of independent, standard, normally distributed\nrandom values using the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. Return Value real(kind=real64), (2) The pair of random values. private function box_muller_array(mu, sigma, n) result(rst) Generates an array of normally distributed random values sampled\nby the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. integer(kind=int32), intent(in) :: n The number of Box-Muller pairs to generate. Return Value real(kind=real64), allocatable, dimension(:) A 2N-element array containing the N Box-Muller pairs.","tags":"","loc":"interface\\box_muller_sample.html"},{"title":"sample_size – FSTATS","text":"public pure function sample_size(dist, var, delta, bet, alpha) result(rst) Estimates the sample size required to achieve an experiment with the\ndesired power and significance levels to ascertain the desired \ndifference in parameter. See Also Wikipedia Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution to utilize as a measure. real(kind=real64), intent(in) :: var An estimate of the population variance. real(kind=real64), intent(in) :: delta The parameter difference that is desired. real(kind=real64), intent(in), optional :: bet The desired power level. The default for this value is 0.2, for a \npower of 80%. real(kind=real64), intent(in), optional :: alpha The desired significance level. The default for this value is 0.05\nfor a confidence level of 95%. Return Value real(kind=real64) The minimum sample size requried to achieve the desired experimental\noutcome.","tags":"","loc":"proc\\sample_size.html"},{"title":"bartletts_test – FSTATS","text":"public subroutine bartletts_test(x, stat, p) Computes Bartlett's test statistic and associated probability. The statistic is calculated as follows. Where and is the pooled\nvariance. The probability is calculated as the right-tail probability of the\nchi-squared distribution. Bartlett's test is most relevant for distributions showing strong \nnormality. For distributions lacking strong normality, consider \nLevene's test instead. See Also Wikipedia Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x The arrays of data to analyze. real(kind=real64), intent(out) :: stat The Bartlett's test statistic. real(kind=real64), intent(out) :: p The probability value that the variances of each data set are\nequivalent. A low p-value, less than some significance level,\nindicates a non-equivalance of variances.","tags":"","loc":"proc\\bartletts_test.html"},{"title":"f_test – FSTATS","text":"public subroutine f_test(x1, x2, stat, p, dof1, dof2) Computes the F-test and returns the probability (two-tailed) that\nthe variances of two data sets are not significantly different. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The F-statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from the two underlying populations that \nhave the same variance. real(kind=real64), intent(out) :: dof1 A measure of the degrees of freedom. real(kind=real64), intent(out) :: dof2 A measure of the degrees of freedom.","tags":"","loc":"proc\\f_test.html"},{"title":"levenes_test – FSTATS","text":"public subroutine levenes_test(x, stat, p, err) Computes Levene's test statistic and associated probability. The statistic is calculated as follows. Where: As the test statistic is approximately F-distributed, the F-distribution\nis used to calculate the probability term. See Also Wikipedia Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x The arrays of data to analyze. real(kind=real64), intent(out) :: stat The Bartlett's test statistic. real(kind=real64), intent(out) :: p The probability value that the variances of each data set are\nequivalent. A low p-value, less than some significance level,\nindicates a non-equivalance of variances. class(errors), intent(inout), optional, target :: err","tags":"","loc":"proc\\levenes_test.html"},{"title":"t_test_equal_variance – FSTATS","text":"public subroutine t_test_equal_variance(x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed equivalent variances. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"proc\\t_test_equal_variance.html"},{"title":"t_test_paired – FSTATS","text":"public subroutine t_test_paired(x1, x2, stat, p, dof, err) Computes the 2-tailed Student's T-Test for two paired data sets. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An N-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same \n length.","tags":"","loc":"proc\\t_test_paired.html"},{"title":"t_test_unequal_variance – FSTATS","text":"public subroutine t_test_unequal_variance(x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed non-equivalent variances. See Also Wikipedia Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"proc\\t_test_unequal_variance.html"},{"title":"confidence_interval – FSTATS","text":"public interface confidence_interval Computes the confidence interval for the specified distribution. See Also Wikipedia Module Procedures private pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: s The sample standard deviation. integer(kind=int32), intent(in) :: n The number of samples in the data set. Return Value real(kind=real64) The result. private pure function confidence_interval_array(dist, alpha, x) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: x (:) An N-element array containing the data to analyze. Return Value real(kind=real64) The result.","tags":"","loc":"interface\\confidence_interval.html"},{"title":"fstats_helper_routines – FSTATS","text":"Uses iso_fortran_env Functions public pure function difference (x) result(rst) Computes the difference between elements in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array on which to operate. Return Value real(kind=real64), allocatable, dimension(:) The (N-1)-element array containing the differences between adjacent\nelements. public pure elemental function factorial (x) result(rst) Computes the factorial of X. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value whose factorial is to be computed. Return Value real(kind=real64) The result.","tags":"","loc":"module\\fstats_helper_routines.html"},{"title":"fstats_bootstrap – FSTATS","text":"Uses fstats_distributions iso_fortran_env fstats_regression linalg omp_lib fstats_descriptive_statistics fstats_errors fstats_special_functions Interfaces interface public subroutine bootstrap_resampling_routine(x, xn) Defines the signature of a subroutine used to compute a \nresampling of data for bootstrapping purposes. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be \nwritten. interface public function bootstrap_statistic_routine(x) result(rst) Defines the signature of a function for computing the desired\nbootstrap statistic. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The array of data to analyze. Return Value real(kind=real64) The resulting statistic. Derived Types type, public :: bootstrap_regression_statistics A container for regression-related statistical information as \ncomputed in a bootstrap, or equivalent, calculation. Components Type Visibility Attributes Name Initial real(kind=real64), public :: lower_confidence_interval The lower limit of the confidence interval for the parameter. real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. Read more… real(kind=real64), public :: standard_error The standard error for the model coefficient. real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. Read more… real(kind=real64), public :: upper_confidence_interval The upper limit of the confidence interval for the parameter. type, public :: bootstrap_statistics A collection of statistics resulting from the bootstrap process. Components Type Visibility Attributes Name Initial real(kind=real64), public :: bias The bias in the statistic. real(kind=real64), public :: lower_confidence_interval The lower confidence limit on the statistic. real(kind=real64), public, allocatable, dimension(:) :: population An array of the population values generated by the bootstrap\nprocess. real(kind=real64), public :: standard_error The standard error of the statistic. real(kind=real64), public :: statistic_value The value of the statistic of interest. real(kind=real64), public :: upper_confidence_interval The upper confidence limit on the statistic. Functions public function bootstrap (stat, x, method, nsamples, alpha) result(rst) Performs a bootstrap calculation on the supplied data set for the given\nstatistic. The default implementation utlizes a random resampling with \nreplacement. Other resampling methods may be defined by specifying an \nappropriate routine by means of the method input. Arguments Type Intent Optional Attributes Name procedure( bootstrap_statistic_routine ), intent(in), pointer :: stat The routine used to compute the desired statistic. real(kind=real64), intent(in), dimension(:) :: x The N-element data set. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. integer(kind=int32), intent(in), optional :: nsamples An optional input, that if supplied, specifies the number of \nresampling runs to perform. The default is 10 000. real(kind=real64), intent(in), optional :: alpha An optional input, that if supplied, defines the significance level\nto use for the analysis. The default is 0.05. Return Value type( bootstrap_statistics ) The resulting bootstrap_statistics type containing the confidence\nintervals, bias, standard error, etc. for the analyzed statistic. Subroutines public subroutine bootstrap_linear_least_squares (order, intercept, x, y, coeffs, ymod, resid, nsamples, stats, bias, alpha, method, bscoeffs, err) Computes a linear least-squares regression to fit a set of data.\nBootstrapping is utilized to gain insight into the quality of \nthe fit. Resampling for the bootstrap process is a random resampling \nwith replacement process with the range of values limited by the \nstandard deviation of the original data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out), dimension(:) :: coeffs An ORDER+1 element array where the coefficients will\nbe written. real(kind=real64), intent(out), dimension(:) :: ymod An N-element array where the modeled data will be written. real(kind=real64), intent(out), dimension(:) :: resid An N-element array where the residual error data will be \nwritten (modeled - actual). integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. type( bootstrap_regression_statistics ), intent(out), optional, dimension(:) :: stats An M-element array of bootstrap_regression_statistics items \nwhere M = ORDER + 1 when intercept is set to true; however, \nif intercept is set to false, M = ORDER. real(kind=real64), intent(out), optional, dimension(:) :: bias An ORDER+1 element array where an estimate of the bias of\neach coefficient is returned based upon the results of the\nbootstrapping analysis. The bias is computed as the difference \nbetween the mean of the boostrap population results for the given \nparameter and the original estimate of the given parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine bootstrap_nonlinear_least_squares (fun, x, y, params, ymod, resid, nsamples, weights, maxp, minp, stats, alpha, controls, settings, info, bias, method, bscoeffs, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain \ninsight into the quality of the fit. Resampling for the bootstrap \nprocess is a random resampling with replacement process with the \nrange of values limited by the standard deviation of the original \ndata set. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. integer(kind=int32), intent(in), optional :: nsamples The number of bootstrapping samples to utilize. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( bootstrap_regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. real(kind=real64), intent(out), optional, dimension(:) :: bias An optional N-element array that, if supplied, will be used to \nprovide an estimate of the bias of each model parameter based upon\nthe results of the bootstrapping analysis. The bias is computed as \nthe difference between the mean of the boostrap population results \nfor the given parameter and the original estimate of the given \nparameter. procedure( bootstrap_resampling_routine ), intent(in), optional, pointer :: method An optional pointer to the method to use for resampling of the data.\nIf no method is supplied, a random resampling is utilized. real(kind=real64), intent(out), optional, allocatable, target, dimension(:,:) :: bscoeffs An optional, allocatable matrix, containing the bootstrap \ndistributions for each parameter stored in each row of the matrix\nsuch that the resulting matrix is NCOEFFS -by- NSAMPLES. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed. public subroutine random_resample (x, xn) Random resampling, with replacement, based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written. public subroutine scaled_random_resample (x, xn) A random resampling, scaled by the standard deviation of the original\ndata, but based upon a normal distribution. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element array to resample. real(kind=real64), intent(out), dimension(size(x)) :: xn An N-element array where the resampled data set will be written.","tags":"","loc":"module\\fstats_bootstrap.html"},{"title":"fstats_experimental_design – FSTATS","text":"Uses fstats_errors iso_fortran_env Subroutines public subroutine full_factorial (vars, tbl, err) Computes a table with values scaled from 1 to N describing a \nfull-factorial design. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each of the M entries to the array is expected to contain \nthe number of options for that particular factor to explore. \nThis value must be greater than or equal to 1. integer(kind=int32), intent(out) :: tbl (:,:) A table where the design will be written. Use \nget_full_factorial_matrix_size to determine the appropriate \ntable size. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.\n- FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized. public subroutine get_full_factorial_matrix_size (vars, m, n, err) Computes the appropriate size for a full-factorial design table. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: vars (:) An M-element array containing the M factors to study. Each \nof the M entries to the array is expected to contain the \nnumber of options for that particular factor to explore. This value must be greater than or equal to 1. integer(kind=int32), intent(out) :: m The number of rows for the table. integer(kind=int32), intent(out) :: n The number of columns for the table. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_INVALID_INPUT_ERROR: Occurs if any items in vars are \n less than 1.","tags":"","loc":"module\\fstats_experimental_design.html"},{"title":"fstats_allan – FSTATS","text":"Uses fstats_errors iso_fortran_env Functions public function allan_variance (x, dt, err) result(rst) Computes the Allan variance of a data set. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The N-element data set to analyze. real(kind=real64), intent(in), optional :: dt An optional input specifying the time increment between \nsamples in x. If not specified, this value is set to 1. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value real(kind=real64), allocatable, dimension(:,:) An M-by-2 array containing the results where M is N / 2 - 1\nif N is even; else, M is (N - 1) / 2 - 1 if N is odd. The \nfirst column contains the averaging times associated with \nthe M results stored in the second column.","tags":"","loc":"module\\fstats_allan.html"},{"title":"fstats_distributions – FSTATS","text":"Uses ieee_arithmetic fstats_helper_routines fstats_special_functions iso_fortran_env Interfaces interface public pure elemental function distribution_function(this, x) result(rst) Defines the interface for a probability distribution function. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The value of the function. interface public pure function distribution_property(this) result(rst) Computes the value of a distribution property. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: this The distribution object. Return Value real(kind=real64) The property value. Derived Types type, public, extends( distribution ) :: binomial_distribution Defines a binomial distribution. The binomial distribution describes\nthe probability p of getting k successes in n independent trials. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: n The number of independent trials. real(kind=real64), public :: p The success probability for each trial. This parameter must\nexist on the set [0, 1]. Type-Bound Procedures procedure, public :: cdf => bd_cdf procedure, public :: mean => bd_mean procedure, public :: median => bd_median procedure, public :: mode => bd_mode procedure, public :: pdf => bd_pdf procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure, public :: variance => bd_variance type, public, extends( distribution ) :: chi_squared_distribution Defines a Chi-squared distribution. Components Type Visibility Attributes Name Initial integer(kind=int32), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => cs_cdf procedure, public :: mean => cs_mean procedure, public :: median => cs_median procedure, public :: mode => cs_mode procedure, public :: pdf => cs_pdf procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure, public :: variance => cs_variance type, public :: distribution Defines a probability distribution. Type-Bound Procedures procedure( distribution_function ), public, deferred, pass :: cdf ..\\..\\ Computes the cumulative distribution function.<\\p> procedure( distribution_property ), public, deferred, pass :: mean ..\\..\\ Computes the mean of the distribution.<\\p> procedure( distribution_property ), public, deferred, pass :: median ..\\..\\ Computes the median of the distribution.<\\p> procedure( distribution_property ), public, deferred, pass :: mode ..\\..\\ Computes the mode of the distribution.<\\p> procedure( distribution_function ), public, deferred, pass :: pdf ..\\..\\ Computes the probability density function.<\\p> procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure( distribution_property ), public, deferred, pass :: variance ..\\..\\ Computes the variance of the distribution.<\\p> type, public, extends( distribution ) :: f_distribution Defines an F-distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: d1 The measure of degrees of freedom for the first data set. real(kind=real64), public :: d2 The measure of degrees of freedom for the second data set. Type-Bound Procedures procedure, public :: cdf => fd_cdf procedure, public :: mean => fd_mean procedure, public :: median => fd_median procedure, public :: mode => fd_mode procedure, public :: pdf => fd_pdf procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure, public :: variance => fd_variance type, public, extends( distribution ) :: normal_distribution Defines a normal distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: mean_value The mean value of the distribution. real(kind=real64), public :: standard_deviation The standard deviation of the distribution. Type-Bound Procedures procedure, public :: cdf => nd_cdf procedure, public :: mean => nd_mean procedure, public :: median => nd_median procedure, public :: mode => nd_mode procedure, public :: pdf => nd_pdf procedure, public :: standardize => nd_standardize procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure, public :: variance => nd_variance type, public, extends( distribution ) :: t_distribution Defines Student's T-Distribution. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedom. Type-Bound Procedures procedure, public :: cdf => td_cdf procedure, public :: mean => td_mean procedure, public :: median => td_median procedure, public :: mode => td_mode procedure, public :: pdf => td_pdf procedure, public :: standardized_variable => dist_std_var ..\\..\\ Computes the standardized variable for the distribution.<\\p> procedure, public :: variance => td_variance","tags":"","loc":"module\\fstats_distributions.html"},{"title":"fstats_types – FSTATS","text":"Uses iso_fortran_env Derived Types type, public :: array_container Provides a container for a real-valued array. A practical use of\nthis construct is in the construction of jagged arrays. Components Type Visibility Attributes Name Initial real(kind=real64), public, allocatable, dimension(:) :: x The array.","tags":"","loc":"module\\fstats_types.html"},{"title":"fstats_regression – FSTATS","text":"Uses fstats_distributions iso_fortran_env blas linalg fstats_hypothesis fstats_descriptive_statistics fstats_errors fstats_special_functions ferror Variables Type Visibility Attributes Name Initial integer(kind=int32), public, parameter :: FS_LEVENBERG_MARQUARDT_UPDATE = 1 integer(kind=int32), public, parameter :: FS_NIELSEN_UPDATE = 3 integer(kind=int32), public, parameter :: FS_QUADRATIC_UPDATE = 2 Interfaces interface public subroutine iteration_update(iter, funvals, resid, params, step) Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: iter real(kind=real64), intent(in) :: funvals (:) real(kind=real64), intent(in) :: resid (:) real(kind=real64), intent(in) :: params (:) real(kind=real64), intent(in) :: step (:) interface public subroutine regression_function(xdata, params, resid, stop) Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: xdata real(kind=real64), intent(in), dimension(:) :: params real(kind=real64), intent(out), dimension(:) :: resid logical, intent(out) :: stop Derived Types type, public :: convergence_info Provides information regarding convergence status. Components Type Visibility Attributes Name Initial logical, public :: converge_on_gradient True if convergence on the gradient was achieved; else, false. logical, public :: converge_on_residual_parameter True if convergence on the residual error parameter was achieved; \nelse, false. logical, public :: converge_on_solution_change True if convergence on the change in solution was achieved; else,\nfalse. integer(kind=int32), public :: function_evaluation_count The function evaluation count. real(kind=real64), public :: gradient_value The value of the gradient test parameter. integer(kind=int32), public :: iteration_count The iteration count. logical, public :: reach_function_evaluation_limit True if the solution did not converge in the allowed number of\nfunction evaluations. logical, public :: reach_iteration_limit True if the solution did not converge in the allowed number of \niterations. real(kind=real64), public :: residual_value The value of the residual error parameter. real(kind=real64), public :: solution_change_value The value of the change in solution parameter. logical, public :: user_requested_stop True if the user requested the stop; else, false. type, public :: iteration_controls Provides a collection of iteration control parameters. Components Type Visibility Attributes Name Initial real(kind=real64), public :: change_in_solution_tolerance Defines a tolerance on the change in parameter values. real(kind=real64), public :: gradient_tolerance Defines a tolerance on the gradient of the fitted function. real(kind=real64), public :: iteration_improvement_tolerance Defines a tolerance to ensure adequate improvement on each \niteration. integer(kind=int32), public :: max_function_evaluations Defines the maximum number of function evaluations allowed. integer(kind=int32), public :: max_iteration_between_updates Defines how many iterations can pass before a re-evaluation of \nthe Jacobian matrix is forced. integer(kind=int32), public :: max_iteration_count Defines the maximum number of iterations allowed. real(kind=real64), public :: residual_tolerance Defines a tolerance on the metric associated with the residual \nerror. Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_tolerances type, public :: lm_solver_options Options to control the Levenberg-Marquardt solver. Components Type Visibility Attributes Name Initial real(kind=real64), public :: damping_decrease_factor The factor to use when decreasing the damping parameter. real(kind=real64), public :: damping_increase_factor The factor to use when increasing the damping parameter. real(kind=real64), public :: finite_difference_step_size The step size used for the finite difference calculations of the\nJacobian matrix. integer(kind=int32), public :: method The solver method to utilize.\n- FS_LEVENBERG_MARQUARDT_UPDATE:\n- FS_QUADRATIC_UPDATE:\n- FS_NIELSEN_UDPATE: Type-Bound Procedures procedure, public :: set_to_default => lm_set_default_settings type, public :: regression_statistics A container for regression-related statistical information. Components Type Visibility Attributes Name Initial real(kind=real64), public :: confidence_interval The confidence interval for the parameter at the level \ndetermined by the regression process. Read more… real(kind=real64), public :: probability The probability that the coefficient is not statistically \nimportant. A statistically important coefficient will have a \nlow probability (p-value), typically 0.05 or lower; however, a \np-value of up to ~0.2 may be acceptable dependent upon the \nproblem. Typically any p-value larger than ~0.2 indicates the \nparameter is not statistically important for the model. Read more… real(kind=real64), public :: standard_error The standard error for the model coefficient. Read more… real(kind=real64), public :: t_statistic The T-statistic for the model coefficient. Read more… Functions public function adjusted_r_squared (p, x, xm, err) result(rst) Computes the adjusted R-squared value for a data set. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: p The number of variables. real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result. public function calculate_regression_statistics (resid, params, c, alpha, err) result(rst) Computes statistics for the quality of fit for a regression \nmodel. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: resid (:) An M-element array containing the model residual errors. real(kind=real64), intent(in) :: params (:) An N-element array containing the model parameters. real(kind=real64), intent(in) :: c (:,:) The N-by-N covariance matrix. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. Return Value type( regression_statistics ), allocatable, (:) A regression_statistics object containing the analysis results. public pure function correlation (x, y) result(rst) Computes the sample correlation coefficient (an estimate to the \npopulation Pearson correlation) as follows. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The correlation coefficient. public function r_squared (x, xm, err) result(rst) Computes the R-squared value for a data set. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the dependent variables from \nthe data set. real(kind=real64), intent(in) :: xm (:) An N-element array containing the corresponding modeled \nvalues. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings\nto the caller. Possible warning and error codes are as \nfollows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the \n same size. Return Value real(kind=real64) The result. Subroutines public subroutine covariance_matrix (x, c, err) Computes the covariance matrix where and is computed\nby design_matrix. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the formatted independent data\n matrix as computed by design_matrix. real(kind=real64), intent(out) :: c (:,:) The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not \n sized correctly.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine design_matrix (order, intercept, x, c, err) Computes the design matrix for the linear \nleast-squares regression problem of , where is the matrix computed here, is \nthe vector of coefficients to be determined, and is the \nvector of measured dependent variables. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be\nat least one (linear equation), but can be higher as desired. logical, intent(in) :: intercept Set to true if the intercept is being computed\nas part of the regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(out) :: c (:,:) An N-by-K matrix where the results will be written. K\nmust equal order + 1 in the event intercept is true; \nhowever, if intercept is false, K must equal order. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. public subroutine jacobian (fun, xdata, params, jac, stop, f0, f1, step, err) Computes the Jacobian matrix for a nonlinear regression problem. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: xdata (:) The M-element array containing x-coordinate data. real(kind=real64), intent(in) :: params (:) The N-element array containing the model parameters. real(kind=real64), intent(out) :: jac (:,:) The M-by-N matrix where the Jacobian will be written. logical, intent(out) :: stop A value that the user can set in fun forcing the\nevaluation process to stop prior to completion. real(kind=real64), intent(in), optional, target :: f0 (:) An optional M-element array containing the model values\n using the current parameters as defined in m. This input \ncan be used to prevent the routine from performing a \nfunction evaluation at the model parameter state defined in \nparams. real(kind=real64), intent(out), optional, target :: f1 (:) An optional M-element workspace array used for function\nevaluations. real(kind=real64), intent(in), optional :: step The differentiation step size. The default is the square \nroot of machine precision. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine linear_least_squares (order, intercept, x, y, coeffs, ymod, resid, stats, alpha, err) Computes a linear least-squares regression to fit a set of data. Read more… Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: order The order of the equation to fit. This value must be at \nleast one (linear equation), but can be higher as desired, \nas long as there is sufficient data. logical, intent(in) :: intercept Set to true if the intercept is being computed as part of \nthe regression; else, false. real(kind=real64), intent(in) :: x (:) An N-element array containing the independent variable\nmeasurement points. real(kind=real64), intent(in) :: y (:) An N-element array containing the dependent variable\nmeasurement points. real(kind=real64), intent(out) :: coeffs (:) An ORDER+1 element array where the coefficients will be written. real(kind=real64), intent(out) :: ymod (:) An N-element array where the modeled data will be written. real(kind=real64), intent(out) :: resid (:) An N-element array where the residual error data will be \nwritten (modeled - actual). type( regression_statistics ), intent(out), optional :: stats (:) An M-element array of regression_statistics items where \nM = ORDER + 1 when intercept is set to true; however, if \nintercept is set to false, M = ORDER. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_INVALID_INPUT_ERROR: Occurs if order is less than 1.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error. public subroutine nonlinear_least_squares (fun, x, y, params, ymod, resid, weights, maxp, minp, stats, alpha, controls, settings, info, status, err) Performs a nonlinear regression to fit a model using a version\nof the Levenberg-Marquardt algorithm. Arguments Type Intent Optional Attributes Name procedure( regression_function ), intent(in), pointer :: fun A pointer to the regression_function to evaluate. real(kind=real64), intent(in) :: x (:) The M-element array containing independent data. real(kind=real64), intent(in) :: y (:) The M-element array containing dependent data. real(kind=real64), intent(inout) :: params (:) On input, the N-element array containing the initial estimate\nof the model parameters. On output, the computed model \nparameters. real(kind=real64), intent(out) :: ymod (:) An M-element array where the modeled dependent data will\nbe written. real(kind=real64), intent(out) :: resid (:) An M-element array where the model residuals will be\nwritten. real(kind=real64), intent(in), optional, target :: weights (:) An optional M-element array allowing the weighting of\nindividual points. real(kind=real64), intent(in), optional, target :: maxp (:) An optional N-element array that can be used as upper limits \non the parameter values. If no upper limit is requested for\na particular parameter, utilize a very large value. The \ninternal default is to utilize huge() as a value. real(kind=real64), intent(in), optional, target :: minp (:) An optional N-element array that can be used as lower limits \non the parameter values. If no lower limit is requested for\na particalar parameter, utilize a very large magnitude, but \nnegative, value. The internal default is to utilize -huge() \nas a value. type( regression_statistics ), intent(out), optional :: stats (:) An optional N-element array that, if supplied, will be used \nto return statistics about the fit for each parameter. real(kind=real64), intent(in), optional :: alpha The significance level at which to evaluate the confidence \nintervals. The default value is 0.05 such that a 95% \nconfidence interval is calculated. type( iteration_controls ), intent(in), optional :: controls An optional input providing custom iteration controls. type( lm_solver_options ), intent(in), optional :: settings An optional input providing custom settings for the solver. type( convergence_info ), intent(out), optional, target :: info An optional output that can be used to gain information about\nthe iterative solution and the nature of the convergence. procedure( iteration_update ), intent(in), optional, pointer :: status An optional pointer to a routine that can be used to extract\niteration information. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n properly sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation \n error.\n- FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed \n is underdetetermined (M < N).\n- FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied \n tolerances are too small to be practical.\n- FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations \n are allowed.","tags":"","loc":"module\\fstats_regression.html"},{"title":"fstats_anova – FSTATS","text":"Uses fstats_distributions iso_fortran_env ieee_arithmetic fstats_descriptive_statistics fstats_errors fstats_special_functions ferror Interfaces public interface anova Performs an analysis of variance (ANOVA) on the supplied data \nset. The following example illustrates a single-factor ANOVA on a \ndata set. program example use iso_fortran_env use fstats implicit none ! Local Variables character , parameter :: tab = achar ( 9 ) real ( real64 ) :: x ( 10 , 2 ) type ( single_factor_anova_table ) :: tbl ! Define the data x = reshape ( & [ & 3.086d3 , 3.082d3 , 3.069d3 , 3.072d3 , 3.045d3 , 3.070d3 , 3.079d3 , & 3.050d3 , 3.062d3 , 3.062d3 , 3.075d3 , 3.061d3 , 3.063d3 , 3.038d3 , & 3.070d3 , 3.062d3 , 3.070d3 , 3.049d3 , 3.042d3 , 3.063d3 & ], & [ 10 , 2 ] & ) ! Perform the ANOVA tbl = anova ( x ) ! Print out the table print '(A)' , \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" print '(AF2.0AF5.1AF5.1AF5.3AF5.3)' , \"Main Factor: \" // tab , & tbl % main_factor % dof , tab , & tbl % main_factor % sum_of_squares , tab // tab , & tbl % main_factor % variance , tab // tab , & tbl % main_factor % f_statistic , tab , & tbl % main_factor % probability print '(AF3.0AF6.1AF5.1)' , \"Within: \" // tab , & tbl % within_factor % dof , tab , & tbl % within_factor % sum_of_squares , tab // tab , & tbl % within_factor % variance print '(AF3.0AF6.1AF5.1)' , \"Total: \" // tab // tab , & tbl % total_dof , tab , & tbl % total_sum_of_squares , tab // tab , & tbl % total_variance print '(AF6.1)' , \"Overall Mean: \" , tbl % overall_mean end program The above program produces the following output. Description DOF Sum of Sq. Variance F-Stat P-Value\nMain Factor: 1. 352.8 352.8 2.147 0.160\nWithin: 18. 2958.2 164.3\nTotal: 19. 3311.0 174.3\nOverall Mean: 3063.5 See Also Wikipedia SPC Excel Single Factor ANOVA SPC Excel Gage R&R SPC Excel Understanding Regression Statistics NIST - Two Way ANOVA private function anova_1_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:) An M-by-N matrix containing the M replications of the N test \npoints of interest. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. private function anova_2_factor(x) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:,:,:) An M-by-N-by-K array containing the M replications of the\nN first factor results, and the K second factor results. Return Value type( two_factor_anova_table ) A two_factor_anova_table instance containing the ANOVA results. private function anova_model_fit(nmodelparams, ymeas, ymod, err) result(rst) Performs an analysis of variance (ANOVA) on the supplied data set. Arguments Type Intent Optional Attributes Name integer(kind=int32), intent(in) :: nmodelparams The number of model parameters. real(kind=real64), intent(in) :: ymeas (:) An N-element array containing the measured dependent variable data. real(kind=real64), intent(in) :: ymod (:) An N-element array containing the modeled dependent variable data. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the \n same length.\n- FS_MEMORY_ERROR: Occurs if a memory error is encountered. Return Value type( single_factor_anova_table ) A single_factor_anova_table instance containing the ANOVA results. Derived Types type, public :: anova_factor Defines an ANOVA factor result. Components Type Visibility Attributes Name Initial real(kind=real64), public :: dof The number of degrees of freedome. real(kind=real64), public :: f_statistic The F-statistic. real(kind=real64), public :: probability The variance probability term. real(kind=real64), public :: sum_of_squares The sum of the squares. real(kind=real64), public :: variance The estimate of variance. type, public :: single_factor_anova_table Defines a single-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: main_factor The main, or main factor, results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within-treatement (error) results. type, public :: two_factor_anova_table Defines a two-factor ANOVA results table. Components Type Visibility Attributes Name Initial type( anova_factor ), public :: interaction The interaction effects. type( anova_factor ), public :: main_factor_1 The first main-factor results. type( anova_factor ), public :: main_factor_2 The second main-factor results. real(kind=real64), public :: overall_mean The overall mean value. real(kind=real64), public :: total_dof The total number of degrees of freedom. real(kind=real64), public :: total_sum_of_squares The total sum of squares. real(kind=real64), public :: total_variance The total variance estimate. type( anova_factor ), public :: within_factor The within (error) factor results.","tags":"","loc":"module\\fstats_anova.html"},{"title":"fstats_descriptive_statistics – FSTATS","text":"Uses fstats_types iso_fortran_env linalg fstats_errors ferror Interfaces public interface pooled_variance Computes the pooled estimate of variance. private pure function pooled_variance_1(si, ni) result(rst) Computes the pooled estimate of variance. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: si An N-element array containing the estimates for each of the N\nvariances. integer(kind=int32), intent(in), dimension(size(si)) :: ni An N-element array containing the number of data points in each\nof the data sets used to compute the variances in si. Return Value real(kind=real64) The pooled variance. private pure function pooled_variance_2(x) result(rst) Computes the pooled estimate of variance. Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x An array of arrays of data. Return Value real(kind=real64) The pooled variance. Functions public pure function covariance (x, y) result(rst) Computes the sample covariance of two data sets. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x The first N-element data set. real(kind=real64), intent(in), dimension(size(x)) :: y The second N-element data set. Return Value real(kind=real64) The covariance. public pure function mean (x) result(rst) Computes the mean of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result. public function median (x) result(rst) Computes the median of the values in an array. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout) :: x (:) The array of values to analyze. On output, this array is sorted into\nascending order. Return Value real(kind=real64) The result. public pure function quantile (x, q) result(rst) Computes the specified quantile of a data set using the SAS \nMethod 4. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) An N-element array containing the data. real(kind=real64), intent(in) :: q The quantile to compute (e.g. 0.25 computes the 25% quantile). Return Value real(kind=real64) The result. public pure function standard_deviation (x) result(rst) Computes the sample standard deviation of the values in an array. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64) The result. public function trimmed_mean (x, p) result(rst) Computes the trimmed mean of a data set. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(inout), dimension(:) :: x An N-element array containing the data. On output, the\narray is sorted into ascending order. real(kind=real64), intent(in), optional :: p An optional parameter specifying the percentage of values\nfrom either end of the distribution to remove. The default\nis 0.05 such that the bottom 5% and top 5% are removed. Return Value real(kind=real64) The trimmed mean. public pure function variance (x) result(rst) Computes the sample variance of the values in an array. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x (:) The array of values to analyze. Return Value real(kind=real64)","tags":"","loc":"module\\fstats_descriptive_statistics.html"},{"title":"fstats_errors – FSTATS","text":"Uses iso_fortran_env ferror Variables Type Visibility Attributes Name Initial integer(kind=int32), public, parameter :: FS_ARRAY_SIZE_ERROR = 10000 integer(kind=int32), public, parameter :: FS_INVALID_INPUT_ERROR = 10002 integer(kind=int32), public, parameter :: FS_MATRIX_SIZE_ERROR = 10001 integer(kind=int32), public, parameter :: FS_MEMORY_ERROR = 10003 integer(kind=int32), public, parameter :: FS_NO_ERROR = 0 integer(kind=int32), public, parameter :: FS_TOLERANCE_TOO_SMALL_ERROR = 10005 integer(kind=int32), public, parameter :: FS_TOO_FEW_ITERATION_ERROR = 10006 integer(kind=int32), public, parameter :: FS_UNDERDEFINED_PROBLEM_ERROR = 10004 Subroutines public subroutine report_array_size_error (err, fname, name, expect, actual) Reports an array size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the array. integer(kind=int32), intent(in) :: expect The expected size of the array. integer(kind=int32), intent(in) :: actual The actual size of the array. public subroutine report_arrays_not_same_size_error (err, fname, name1, name2, size1, size2) Reports an error relating to two arrays not being the same size\nwhen they should be the same size. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name1 The name of the first array. character(len=*), intent(in) :: name2 The name of the second array. integer(kind=int32), intent(in) :: size1 The size of the first array. integer(kind=int32), intent(in) :: size2 The size of the second array. public subroutine report_iteration_count_error (err, fname, msg, mincount) Reports an iteration count error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*) :: fname The name of the routine in which the error occurred. character(len=*) :: msg The error message. integer(kind=int32), intent(in) :: mincount The minimum iteration count expected. public subroutine report_matrix_size_error (err, fname, name, expect_rows, expect_cols, actual_rows, actual_cols) Reports a matrix size error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. character(len=*), intent(in) :: name The name of the matrix. integer(kind=int32), intent(in) :: expect_rows The expected number of rows. integer(kind=int32), intent(in) :: expect_cols The expected number of columns. integer(kind=int32), intent(in) :: actual_rows The actual number of rows. integer(kind=int32), intent(in) :: actual_cols The actual number of columns. public subroutine report_memory_error (err, fname, code) Reports a memory allocation related error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: code The error code returned by the allocation routine. public subroutine report_underdefined_error (err, fname, expect, actual) Reports an underdefined problem error. Arguments Type Intent Optional Attributes Name class(errors), intent(inout) :: err The error handling object. character(len=*), intent(in) :: fname The name of the routine in which the error occurred. integer(kind=int32), intent(in) :: expect The expected minimum number of equations. integer(kind=int32), intent(in) :: actual The actual number of equations.","tags":"","loc":"module\\fstats_errors.html"},{"title":"fstats_smoothing – FSTATS","text":"Uses linalg fstats_errors iso_fortran_env ferror Subroutines public subroutine lowess (x, y, ys, fsmooth, nstps, del, rweights, resid, err) Computes the smoothing of a data set using a robust locally weighted\nscatterplot smoothing (LOWESS) algorithm. Fitted values are computed at\neach of the supplied x values. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in), dimension(:) :: x An N-element array containing the independent variable data. This\narray must be monotonically increasing. real(kind=real64), intent(in), dimension(:) :: y An N-element array containing the dependent variable data. real(kind=real64), intent(out), dimension(:) :: ys An N-element array where the smoothed results will be written. real(kind=real64), intent(in), optional :: fsmooth An optional input that specifies the amount of smoothing. Specifically, this value is the fraction of points used to compute\neach value. As this value increases, the output becomes smoother.\nChoosing a value in the range of 0.2 to 0.8 typically results in a\ngood fit. The default value is 0.2. integer(kind=int32), intent(in), optional :: nstps An optional input that specifies the numb of iterations. If set to\nzero, a non-robust fit is returned. The default value is set to 2. real(kind=real64), intent(in), optional :: del real(kind=real64), intent(out), optional, dimension(:), target :: rweights An optional N-element array, that if supplied, will be used to\nreturn the weights given to each data point. real(kind=real64), intent(out), optional, dimension(:), target :: resid An optional N-element array, that if supplied, will be used to \nreturn the residual. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not \n approriately sized.\n- FS_MEMORY_ERROR: Occurs if there is a memory allocation error.","tags":"","loc":"module\\fstats_smoothing.html"},{"title":"fstats_special_functions – FSTATS","text":"Uses ieee_arithmetic iso_fortran_env Functions public pure elemental function beta (a, b) result(rst) Computes the beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. Return Value real(kind=real64) The value of the beta function at and . public pure elemental function digamma (x) result(rst) Computes the digamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function incomplete_beta (a, b, x) result(rst) Computes the incomplete beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the incomplete beta function. public pure elemental function incomplete_gamma_lower (a, x) result(rst) Computes the lower incomplete gamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function incomplete_gamma_upper (a, x) result(rst) Computes the upper incomplete gamma function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The coefficient value. real(kind=real64), intent(in) :: x The value at which to evaluate the function. Return Value real(kind=real64) The function value. public pure elemental function regularized_beta (a, b, x) result(rst) Computes the regularized beta function. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: a The first argument of the function. real(kind=real64), intent(in) :: b The second argument of the function. real(kind=real64), intent(in) :: x The upper limit of the integration. Return Value real(kind=real64) The value of the regularized beta function.","tags":"","loc":"module\\fstats_special_functions.html"},{"title":"fstats – FSTATS","text":"FSTATS is a modern Fortran statistical library containing routines for \ncomputing basic statistical properties, hypothesis testing, regression, \nspecial functions, and experimental design. Uses fstats_distributions fstats_bootstrap iso_fortran_env fstats_anova fstats_smoothing fstats_regression fstats_allan fstats_sampling fstats_experimental_design fstats_hypothesis fstats_descriptive_statistics fstats_helper_routines fstats_special_functions","tags":"","loc":"module\\fstats.html"},{"title":"fstats_sampling – FSTATS","text":"Uses fstats_distributions linalg iso_fortran_env Interfaces public interface box_muller_sample Generates random, normally distributed values via the Box-Muller \ntransform. private function box_muller_sample_scalar(mu, sigma) result(rst) Generates a pair of independent, standard, normally distributed\nrandom values using the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. Return Value real(kind=real64), (2) The pair of random values. private function box_muller_array(mu, sigma, n) result(rst) Generates an array of normally distributed random values sampled\nby the Box-Muller transform. Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: mu The mean of the distribution. real(kind=real64), intent(in) :: sigma The standard deviation of the distribution. integer(kind=int32), intent(in) :: n The number of Box-Muller pairs to generate. Return Value real(kind=real64), allocatable, dimension(:) A 2N-element array containing the N Box-Muller pairs. Functions public function rejection_sample (tdist, n, xmin, xmax) result(rst) Uses rejection sampling to randomly sample a target distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: tdist The distribution to sample integer(kind=int32), intent(in) :: n The number of samples to make. real(kind=real64), intent(in) :: xmin The minimum range to explore. real(kind=real64), intent(in) :: xmax The maximum range to explore. Return Value real(kind=real64), allocatable, dimension(:) An N-element array containing the N samples from the \ndistribution.","tags":"","loc":"module\\fstats_sampling.html"},{"title":"fstats_hypothesis – FSTATS","text":"Uses fstats_distributions fstats_types iso_fortran_env ieee_arithmetic fstats_descriptive_statistics fstats_errors fstats_special_functions Interfaces public interface confidence_interval Computes the confidence interval for the specified distribution. See Also Wikipedia private pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: s The sample standard deviation. integer(kind=int32), intent(in) :: n The number of samples in the data set. Return Value real(kind=real64) The result. private pure function confidence_interval_array(dist, alpha, x) result(rst) Computes the confidence interval for the specified distribution. Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution object defining the probability distribution\nto establish the confidence level. real(kind=real64), intent(in) :: alpha The probability value of interest. For instance, use a value of 0.05\nfor a confidence level of 95%. real(kind=real64), intent(in) :: x (:) An N-element array containing the data to analyze. Return Value real(kind=real64) The result. Functions public pure function sample_size (dist, var, delta, bet, alpha) result(rst) Estimates the sample size required to achieve an experiment with the\ndesired power and significance levels to ascertain the desired \ndifference in parameter. Read more… Arguments Type Intent Optional Attributes Name class( distribution ), intent(in) :: dist The distribution to utilize as a measure. real(kind=real64), intent(in) :: var An estimate of the population variance. real(kind=real64), intent(in) :: delta The parameter difference that is desired. real(kind=real64), intent(in), optional :: bet The desired power level. The default for this value is 0.2, for a \npower of 80%. real(kind=real64), intent(in), optional :: alpha The desired significance level. The default for this value is 0.05\nfor a confidence level of 95%. Return Value real(kind=real64) The minimum sample size requried to achieve the desired experimental\noutcome. Subroutines public subroutine bartletts_test (x, stat, p) Computes Bartlett's test statistic and associated probability. Read more… Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x The arrays of data to analyze. real(kind=real64), intent(out) :: stat The Bartlett's test statistic. real(kind=real64), intent(out) :: p The probability value that the variances of each data set are\nequivalent. A low p-value, less than some significance level,\nindicates a non-equivalance of variances. public subroutine f_test (x1, x2, stat, p, dof1, dof2) Computes the F-test and returns the probability (two-tailed) that\nthe variances of two data sets are not significantly different. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The F-statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from the two underlying populations that \nhave the same variance. real(kind=real64), intent(out) :: dof1 A measure of the degrees of freedom. real(kind=real64), intent(out) :: dof2 A measure of the degrees of freedom. public subroutine levenes_test (x, stat, p, err) Computes Levene's test statistic and associated probability. Read more… Arguments Type Intent Optional Attributes Name type( array_container ), intent(in), dimension(:) :: x The arrays of data to analyze. real(kind=real64), intent(out) :: stat The Bartlett's test statistic. real(kind=real64), intent(out) :: p The probability value that the variances of each data set are\nequivalent. A low p-value, less than some significance level,\nindicates a non-equivalance of variances. class(errors), intent(inout), optional, target :: err public subroutine t_test_equal_variance (x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed equivalent variances. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. public subroutine t_test_paired (x1, x2, stat, p, dof, err) Computes the 2-tailed Student's T-Test for two paired data sets. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An N-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom. class(errors), intent(inout), optional, target :: err A mechanism for communicating errors and warnings to the \ncaller. Possible warning and error codes are as follows.\n- FS_NO_ERROR: No errors encountered.\n- FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same \n length. public subroutine t_test_unequal_variance (x1, x2, stat, p, dof) Computes the 2-tailed Student's T-Test for two data sets of \nassumed non-equivalent variances. Read more… Arguments Type Intent Optional Attributes Name real(kind=real64), intent(in) :: x1 (:) An N-element array containing the first data set. real(kind=real64), intent(in) :: x2 (:) An M-element array containing the second data set. real(kind=real64), intent(out) :: stat The Student-'s T-Test statistic. real(kind=real64), intent(out) :: p The probability value that the two samples are likely to\nhave come from two underlying populations that \nhave the same mean. real(kind=real64), intent(out) :: dof The degrees of freedom.","tags":"","loc":"module\\fstats_hypothesis.html"},{"title":"fstats_helper_routines.f90 – FSTATS","text":"Source Code module fstats_helper_routines use iso_fortran_env implicit none private public :: difference public :: factorial contains ! ------------------------------------------------------------------------------ pure function difference ( x ) result ( rst ) !! Computes the difference between elements in an array. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array on which to operate. real ( real64 ), allocatable , dimension (:) :: rst !! The (N-1)-element array containing the differences between adjacent !! elements. ! Local Variables integer ( int32 ) :: i , n ! Process n = size ( x ) allocate ( rst ( n - 1 )) do i = 1 , n - 1 rst ( i ) = x ( i + 1 ) - x ( i ) end do end function ! ------------------------------------------------------------------------------ pure elemental function factorial ( x ) result ( rst ) !! Computes the factorial of X. real ( real64 ), intent ( in ) :: x !! The value whose factorial is to be computed. real ( real64 ) :: rst !! The result. rst = gamma ( x + 1.0d0 ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_helper_routines.f90.html"},{"title":"fstats_bootstrap.f90 – FSTATS","text":"Source Code module fstats_bootstrap use iso_fortran_env use fstats_errors use omp_lib use fstats_distributions use fstats_descriptive_statistics use fstats_special_functions use fstats_regression use linalg , only : sort implicit none private public :: bootstrap_resampling_routine public :: bootstrap_statistic_routine public :: random_resample public :: scaled_random_resample public :: bootstrap_statistics public :: bootstrap public :: bootstrap_regression_statistics public :: bootstrap_linear_least_squares public :: bootstrap_nonlinear_least_squares ! REFERENCES: ! - https://medium.com/@m21413108/bootstrapping-maximum-entropy-non-parametric-boot-python-3b1e23ea589d ! - https://cran.r-project.org/web/packages/meboot/vignettes/meboot.pdf ! - https://gist.github.com/christianjauregui/314456688a3c2fead43a48be3a47dad6 type bootstrap_regression_statistics !! A container for regression-related statistical information as !! computed in a bootstrap, or equivalent, calculation. real ( real64 ) :: standard_error !! The standard error for the model coefficient. real ( real64 ) :: t_statistic !! The T-statistic for the model coefficient. !! !! t_o = \\frac{ \\beta_{i} }{E_{s}(\\beta_{i})} real ( real64 ) :: probability !! The probability that the coefficient is not statistically !! important. A statistically important coefficient will have a !! low probability (p-value), typically 0.05 or lower; however, a !! p-value of up to ~0.2 may be acceptable dependent upon the !! problem. Typically any p-value larger than ~0.2 indicates the !! parameter is not statistically important for the model. !! !! p = t_{|t_o|, df_{residual}} real ( real64 ) :: upper_confidence_interval !! The upper limit of the confidence interval for the parameter. real ( real64 ) :: lower_confidence_interval !! The lower limit of the confidence interval for the parameter. end type type bootstrap_statistics !! A collection of statistics resulting from the bootstrap process. real ( real64 ) :: statistic_value !! The value of the statistic of interest. real ( real64 ) :: upper_confidence_interval !! The upper confidence limit on the statistic. real ( real64 ) :: lower_confidence_interval !! The lower confidence limit on the statistic. real ( real64 ) :: bias !! The bias in the statistic. real ( real64 ) :: standard_error !! The standard error of the statistic. real ( real64 ), allocatable , dimension (:) :: population !! An array of the population values generated by the bootstrap !! process. end type interface subroutine bootstrap_resampling_routine ( x , xn ) !! Defines the signature of a subroutine used to compute a !! resampling of data for bootstrapping purposes. use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be !! written. end subroutine function bootstrap_statistic_routine ( x ) result ( rst ) !! Defines the signature of a function for computing the desired !! bootstrap statistic. use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: x !! The array of data to analyze. real ( real64 ) :: rst !! The resulting statistic. end function end interface contains ! ****************************************************************************** ! RESAMPLING ! ------------------------------------------------------------------------------ subroutine random_resample ( x , xn ) !! Random resampling, with replacement, based upon a normal distribution. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be written. ! Parameters real ( real64 ), parameter :: scale = 1.25d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: xmin , xmax , rng ! Process n = size ( x ) xmin = x ( 1 ) xmax = x ( 1 ) do i = 2 , n xmin = min ( xmin , x ( i )) xmax = max ( xmax , x ( i )) end do rng = ( xmax - xmin ) call random_number ( xn ) xn = xn * rng + xmin end subroutine ! ------------------------------------------------------------------------------ subroutine scaled_random_resample ( x , xn ) !! A random resampling, scaled by the standard deviation of the original !! data, but based upon a normal distribution. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element array to resample. real ( real64 ), intent ( out ), dimension ( size ( x )) :: xn !! An N-element array where the resampled data set will be written. ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: n real ( real64 ) :: eps ! Process n = size ( x ) eps = standard_deviation ( x ) / sqrt ( real ( n , real64 )) call random_number ( xn ) xn = eps * ( xn - half ) + x end subroutine ! ****************************************************************************** ! BOOTSTRAPPING ! ------------------------------------------------------------------------------ function bootstrap ( stat , x , method , nsamples , alpha ) result ( rst ) !! Performs a bootstrap calculation on the supplied data set for the given !! statistic. The default implementation utlizes a random resampling with !! replacement. Other resampling methods may be defined by specifying an !! appropriate routine by means of the method input. procedure ( bootstrap_statistic_routine ), pointer , intent ( in ) :: stat !! The routine used to compute the desired statistic. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element data set. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. integer ( int32 ), intent ( in ), optional :: nsamples !! An optional input, that if supplied, specifies the number of !! resampling runs to perform. The default is 10 000. real ( real64 ), intent ( in ), optional :: alpha !! An optional input, that if supplied, defines the significance level !! to use for the analysis. The default is 0.05. type ( bootstrap_statistics ) :: rst !! The resulting bootstrap_statistics type containing the confidence !! intervals, bias, standard error, etc. for the analyzed statistic. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , i1 , i2 , n , ns real ( real64 ) :: a real ( real64 ), allocatable , dimension (:) :: xn procedure ( bootstrap_resampling_routine ), pointer :: resample ! Initialization n = size ( x ) if ( present ( method )) then resample => method else resample => random_resample end if if ( present ( nsamples )) then ns = nsamples else ns = 10000 end if if ( present ( alpha )) then a = alpha else a = p05 end if allocate ( rst % population ( ns )) i1 = floor ( half * a * ns , int32 ) i2 = ns - i1 + 1 ! Analyze the basic data set rst % statistic_value = stat ( x ) rst % population ( 1 ) = rst % statistic_value ! Resampling Process #ifdef USEOPENMP ! Use OpenMP to run operations in parallel !$OMP PARALLEL DO PRIVATE(xn) SHARED(rst) do i = 2 , ns ! Per-thread memory allocation if (. not . allocated ( xn )) allocate ( xn ( n )) ! Resample the data call resample ( x , xn ) ! Compute the statistic rst % population ( i ) = stat ( xn ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( xn ( n )) do i = 2 , ns ! Resample the data call resample ( x , xn ) ! Compute the statistic for the resampled data rst % population ( i ) = stat ( xn ) end do #endif ! Compute the relevant quantities on the resampled statistic call sort ( rst % population , . true .) rst % upper_confidence_interval = rst % population ( i2 ) rst % lower_confidence_interval = rst % population ( i1 ) rst % bias = mean ( rst % population ) - rst % statistic_value rst % standard_error = standard_deviation ( rst % population ) end function ! ****************************************************************************** ! LINEAR REGRESSION ! ------------------------------------------------------------------------------ subroutine bootstrap_linear_least_squares ( order , intercept , x , y , & coeffs , ymod , resid , nsamples , stats , bias , alpha , method , bscoeffs , err ) !! Computes a linear least-squares regression to fit a set of data. !! Bootstrapping is utilized to gain insight into the quality of !! the fit. Resampling for the bootstrap process is a random resampling !! with replacement process with the range of values limited by the !! standard deviation of the original data set. integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be at !! least one (linear equation), but can be higher as desired, !! as long as there is sufficient data. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed as part of !! the regression; else, false. real ( real64 ), intent ( in ), dimension (:) :: x !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( in ), dimension (:) :: y !! An N-element array containing the dependent variable !! measurement points. real ( real64 ), intent ( out ), dimension (:) :: coeffs !! An ORDER+1 element array where the coefficients will !! be written. real ( real64 ), intent ( out ), dimension (:) :: ymod !! An N-element array where the modeled data will be written. real ( real64 ), intent ( out ), dimension (:) :: resid !! An N-element array where the residual error data will be !! written (modeled - actual). integer ( int32 ), intent ( in ), optional :: nsamples !! The number of bootstrapping samples to utilize. type ( bootstrap_regression_statistics ), intent ( out ), optional , & dimension (:) :: stats !! An M-element array of bootstrap_regression_statistics items !! where M = ORDER + 1 when intercept is set to true; however, !! if intercept is set to false, M = ORDER. real ( real64 ), intent ( out ), optional , dimension (:) :: bias !! An ORDER+1 element array where an estimate of the bias of !! each coefficient is returned based upon the results of the !! bootstrapping analysis. The bias is computed as the difference !! between the mean of the boostrap population results for the given !! parameter and the original estimate of the given parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. real ( real64 ), intent ( out ), optional , allocatable , target , dimension (:,:) :: bscoeffs !! An optional, allocatable matrix, containing the bootstrap !! distributions for each parameter stored in each row of the matrix !! such that the resulting matrix is NCOEFFS -by- NSAMPLES. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , j , n , ns , nc , ncoeffs , flag , nthreads , thread real ( real64 ) :: alph real ( real64 ), allocatable , dimension (:) :: fLocal , yLocal , rLocal real ( real64 ), allocatable , target , dimension (:,:) :: coeffstorage real ( real64 ), pointer , dimension (:,:) :: allcoeffs class ( errors ), pointer :: errmgr type ( errors ), target :: deferr procedure ( bootstrap_resampling_routine ), pointer :: resample ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( nsamples )) then ns = nsamples else ns = 1000 end if if ( present ( alpha )) then alph = alpha else alph = p05 end if if ( present ( method )) then resample => method else resample => scaled_random_resample end if n = size ( x ) ncoeffs = order + 1 nc = order if ( intercept ) nc = nc + 1 nthreads = omp_get_num_threads () ! Compute the fit call linear_least_squares ( order , intercept , x , y , coeffs , & ymod , resid , alpha = alph , err = errmgr ) if ( errmgr % has_error_occurred ()) return ! Memory Allocations if ( present ( bscoeffs )) then allocate ( bscoeffs ( ncoeffs , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"bootstrap_linear_least_squares\" , & flag ) return end if allcoeffs => bscoeffs else allocate ( coeffstorage ( ncoeffs , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"bootstrap_linear_least_squares\" , & flag ) return end if allcoeffs => coeffstorage end if allcoeffs (:, 1 ) = coeffs ! Cycle over each data set and perform the fit #ifdef USEOPENMP !$OMP PARALLEL DO PRIVATE(fLocal, yLocal, rLocal) SHARED(allcoeffs) do i = 2 , ns ! Get the current thread number ! The +1 is because OpenMP is zero-based for thread numbering thread = omp_get_thread_num () + 1 ! Allocate local arrays on a per-thread basis if (. not . allocated ( fLocal )) allocate ( fLocal ( n )) if (. not . allocated ( yLocal )) allocate ( yLocal ( n )) if (. not . allocated ( rLocal )) allocate ( rLocal ( n )) ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call linear_least_squares ( order , intercept , x , yLocal , & allcoeffs (:, i ), fLocal , rLocal , alpha = alph ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( fLocal ( n ), yLocal ( n ), rLocal ( n )) do i = 2 , ns ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call linear_least_squares ( order , intercept , x , yLocal , & allcoeffs (:, i ), fLocal , rLocal , alpha = alph ) end do #endif ! Perform statistics calculations, if needed if ( present ( stats )) then call compute_stats ( coeffs , allcoeffs , alph , intercept , stats ) end if ! Compute the bias for each parameter, if needed if ( present ( bias )) then ! Verify the size of the array if ( size ( bias ) /= ncoeffs ) then call report_array_size_error ( errmgr , & \"bootstrap_linear_least_squares\" , \"bias\" , ncoeffs , size ( bias )) return end if ! Perform the calculations do i = 1 , ncoeffs bias ( i ) = mean ( allcoeffs ( i ,:)) - coeffs ( i ) end do end if end subroutine ! ****************************************************************************** ! NONLINEAR REGRESSION ! ------------------------------------------------------------------------------ subroutine bootstrap_nonlinear_least_squares ( fun , x , y , params , ymod , resid , & nsamples , weights , maxp , minp , stats , alpha , controls , settings , info , & bias , method , bscoeffs , err ) !! Performs a nonlinear regression to fit a model using a version !! of the Levenberg-Marquardt algorithm. Bootstrapping is utilized to gain !! insight into the quality of the fit. Resampling for the bootstrap !! process is a random resampling with replacement process with the !! range of values limited by the standard deviation of the original !! data set. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: x (:) !! The M-element array containing independent data. real ( real64 ), intent ( in ) :: y (:) !! The M-element array containing dependent data. real ( real64 ), intent ( inout ) :: params (:) !! On input, the N-element array containing the initial estimate !! of the model parameters. On output, the computed model !! parameters. real ( real64 ), intent ( out ) :: ymod (:) !! An M-element array where the modeled dependent data will !! be written. real ( real64 ), intent ( out ) :: resid (:) !! An M-element array where the model residuals will be !! written. integer ( int32 ), intent ( in ), optional :: nsamples !! The number of bootstrapping samples to utilize. real ( real64 ), intent ( in ), optional , target :: weights (:) !! An optional M-element array allowing the weighting of !! individual points. real ( real64 ), intent ( in ), optional , target :: maxp (:) !! An optional N-element array that can be used as upper limits !! on the parameter values. If no upper limit is requested for !! a particular parameter, utilize a very large value. The !! internal default is to utilize huge() as a value. real ( real64 ), intent ( in ), optional , target :: minp (:) !! An optional N-element array that can be used as lower limits !! on the parameter values. If no lower limit is requested for !! a particalar parameter, utilize a very large magnitude, but !! negative, value. The internal default is to utilize -huge() !! as a value. type ( bootstrap_regression_statistics ), intent ( out ), optional :: stats (:) !! An optional N-element array that, if supplied, will be used !! to return statistics about the fit for each parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. type ( iteration_controls ), intent ( in ), optional :: controls !! An optional input providing custom iteration controls. type ( lm_solver_options ), intent ( in ), optional :: settings !! An optional input providing custom settings for the solver. type ( convergence_info ), intent ( out ), optional , target :: info !! An optional output that can be used to gain information about !! the iterative solution and the nature of the convergence. real ( real64 ), intent ( out ), optional , dimension (:) :: bias !! An optional N-element array that, if supplied, will be used to !! provide an estimate of the bias of each model parameter based upon !! the results of the bootstrapping analysis. The bias is computed as !! the difference between the mean of the boostrap population results !! for the given parameter and the original estimate of the given !! parameter. procedure ( bootstrap_resampling_routine ), pointer , intent ( in ), optional :: method !! An optional pointer to the method to use for resampling of the data. !! If no method is supplied, a random resampling is utilized. real ( real64 ), intent ( out ), optional , allocatable , target , dimension (:,:) :: bscoeffs !! An optional, allocatable matrix, containing the bootstrap !! distributions for each parameter stored in each row of the matrix !! such that the resulting matrix is NCOEFFS -by- NSAMPLES. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed !! is underdetetermined (M < N). !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied !! tolerances are too small to be practical. !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations !! are allowed. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p05 = 5.0d-2 ! Local Variables integer ( int32 ) :: i , n , ns , nparams , flag real ( real64 ) :: alph real ( real64 ), allocatable , dimension (:) :: fLocal , yLocal , rLocal real ( real64 ), allocatable , target , dimension (:,:) :: coeffstorage real ( real64 ), pointer , dimension (:,:) :: allcoeffs procedure ( bootstrap_resampling_routine ), pointer :: resample class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( nsamples )) then ns = nsamples else ns = 1000 end if if ( present ( alpha )) then alph = alpha else alph = p05 end if if ( present ( method )) then resample => method else resample => scaled_random_resample end if n = size ( x ) nparams = size ( params ) ! Compute the fit call nonlinear_least_squares ( fun , x , y , params , ymod , resid , & weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info , err = err ) ! Memory Allocations if ( present ( bscoeffs )) then allocate ( bscoeffs ( nparams , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , flag ) return end if allcoeffs => bscoeffs else allocate ( coeffstorage ( nparams , ns ), source = zero , stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , flag ) return end if allcoeffs => coeffstorage end if allcoeffs (:, 1 ) = params ! Define initial guesses for each step. Base upon the results of the ! initial analysis as this should provide a strong starting point for ! subsequent analysis do i = 1 , nparams allcoeffs ( i ,:) = params ( i ) end do ! Cycle over each data set and perform the fit #ifdef USEOPENMP !$OMP PARALLEL DO PRIVATE(fLocal, yLocal, rLocal) do i = 2 , ns ! Allocate local arrays on a per-thread basis if (. not . allocated ( fLocal )) allocate ( fLocal ( n )) if (. not . allocated ( yLocal )) allocate ( yLocal ( n )) if (. not . allocated ( rLocal )) allocate ( rLocal ( n )) ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call nonlinear_least_squares ( fun , x , yLocal , allcoeffs (:, i ), fLocal , & rLocal , weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info ) end do !$OMP END PARALLEL DO #else ! OpenMP is not available - run in a serial manner allocate ( fLocal ( n ), yLocal ( n ), rLocal ( n )) do i = 2 , ns ! Compute a random data set call resample ( y , yLocal ) ! Compute the fit of the perturbed data set call nonlinear_least_squares ( fun , x , yLocal , allcoeffs (:, i ), fLocal , & rLocal , weights = weights , maxp = maxp , minp = minp , alpha = alph , & controls = controls , settings = settings , info = info ) end do #endif ! Perform the statistics calculations, if needed if ( present ( stats )) then ! Verify the size of stats if ( size ( stats ) /= nparams ) then call report_array_size_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , \"stats\" , & nparams , size ( stats )) return end if ! Perform the calculations call compute_stats ( params , allcoeffs , alph , . true ., stats ) end if ! Compute the bias for each parameter, if needed if ( present ( bias )) then ! Verify the size of the array if ( size ( bias ) /= nparams ) then call report_array_size_error ( errmgr , & \"bootstrap_nonlinear_least_squares\" , \"bias\" , & nparams , size ( bias )) return end if ! Perform the calculations do i = 1 , nparams bias ( i ) = mean ( allcoeffs ( i ,:)) - params ( i ) end do end if end subroutine ! ****************************************************************************** ! PRIVATE HELPER ROUTINES ! ------------------------------------------------------------------------------ subroutine compute_stats ( mdl , coeffs , alpha , intercept , stats ) ! Arguments real ( real64 ), intent ( in ), dimension (:) :: mdl real ( real64 ), intent ( inout ), dimension (:,:) :: coeffs real ( real64 ), intent ( in ) :: alpha logical , intent ( in ) :: intercept type ( bootstrap_regression_statistics ), intent ( out ), dimension (:) :: stats ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: i , j , i1 , i2 , ncoeffs , nc , nsamples real ( real64 ) :: ms type ( t_distribution ) :: dist ! Initialization ncoeffs = size ( coeffs , 1 ) nsamples = size ( coeffs , 2 ) nc = ncoeffs if (. not . intercept ) nc = ncoeffs - 1 i1 = floor ( half * alpha * nsamples , int32 ) i2 = nsamples - i1 + 1 dist % dof = real ( nsamples - nc ) ! Process j = 1 if ( intercept ) j = 0 do i = 1 , nc j = j + 1 ms = trimmed_mean ( coeffs ( j ,:), p = half * alpha ) ! As we have a distribution of mean values, the standard deviation ! of this population yields the standard error estimate for the ! overall problem stats ( i )% standard_error = standard_deviation ( coeffs ( j ,:)) ! As before, this is a distribution of mean values. The CI can ! be directly estimated by considering the values of the bottom ! alpha/2 and top alpha/2 terms. stats ( i )% upper_confidence_interval = coeffs ( j , i2 ) stats ( i )% lower_confidence_interval = coeffs ( j , i1 ) ! Compute the remaining parameters stats ( i )% t_statistic = mdl ( j ) / stats ( i )% standard_error stats ( i )% probability = regularized_beta ( half * dist % dof , half , & dist % dof / ( dist % dof + ( stats ( i )% t_statistic ) ** 2 )) end do end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_bootstrap.f90.html"},{"title":"fstats_experimental_design.f90 – FSTATS","text":"Source Code module fstats_experimental_design use iso_fortran_env use fstats_errors implicit none private public :: get_full_factorial_matrix_size public :: full_factorial contains ! ------------------------------------------------------------------------------ subroutine get_full_factorial_matrix_size ( vars , m , n , err ) !! Computes the appropriate size for a full-factorial design table. integer ( int32 ), intent ( in ) :: vars (:) !! An M-element array containing the M factors to study. Each !! of the M entries to the array is expected to contain the !! number of options for that particular factor to explore. !! This value must be greater than or equal to 1. integer ( int32 ), intent ( out ) :: m !! The number of rows for the table. integer ( int32 ), intent ( out ) :: n !! The number of columns for the table. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_INVALID_INPUT_ERROR: Occurs if any items in vars are !! less than 1. ! Local Variables integer ( int32 ) :: i class ( errors ), pointer :: errmgr type ( errors ), target :: deferr character ( len = 256 ) :: errmsg ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if m = 0 n = 0 ! Ensure every value is greater than 1 do i = 1 , size ( vars ) if ( vars ( i ) < 1 ) then write ( errmsg , 100 ) \"A value less than 1 was found at index \" , & i , \" of the input array. All values must be greater \" // & \"than or equal to 1.\" call errmgr % report_error ( \"get_full_factorial_matrix_size\" , & trim ( errmsg ), FS_INVALID_INPUT_ERROR ) return end if end do ! Process m = product ( vars ) n = size ( vars ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine full_factorial ( vars , tbl , err ) !! Computes a table with values scaled from 1 to N describing a !! full-factorial design. !! !! ```fortran !! program example !! use iso_fortran_env !! use fstats !! implicit none !! !! ! Local Variables !! integer(int32) :: i, vars(3), tbl(24, 3) !! !! ! Define the number of design points for each of the 3 factors to study !! vars = [2, 4, 3] !! !! ! Determine the design table !! call full_factorial(vars, tbl) !! !! ! Display the table !! do i = 1, size(tbl, 1) !! print *, tbl(i,:) !! end do !! end program !! ``` !! The above program produces the following output. !! ```text !! 1 1 1 !! 1 1 2 !! 1 1 3 !! 1 2 1 !! 1 2 2 !! 1 2 3 !! 1 3 1 !! 1 3 2 !! 1 3 3 !! 1 4 1 !! 1 4 2 !! 1 4 3 !! 2 1 1 !! 2 1 2 !! 2 1 3 !! 2 2 1 !! 2 2 2 !! 2 2 3 !! 2 3 1 !! 2 3 2 !! 2 3 3 !! 2 4 1 !! 2 4 2 !! 2 4 3 !! ``` integer ( int32 ), intent ( in ) :: vars (:) !! An M-element array containing the M factors to study. !! Each of the M entries to the array is expected to contain !! the number of options for that particular factor to explore. !! This value must be greater than or equal to 1. integer ( int32 ), intent ( out ) :: tbl (:,:) !! A table where the design will be written. Use !! get_full_factorial_matrix_size to determine the appropriate !! table size. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_INVALID_INPUT_ERROR: Occurs if any items in vars are !! less than 1. !! - FS_ARRAY_SIZE_ERROR: Occurs if tbl is not properly sized. ! Local Variables integer ( int32 ) :: i , col , stride , last , val , m , n class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Verify the size of the input table call get_full_factorial_matrix_size ( vars , m , n , errmgr ) if ( errmgr % has_error_occurred ()) return if ( size ( tbl , 1 ) /= m . or . size ( tbl , 2 ) /= n ) then call report_matrix_size_error ( errmgr , \"full_factorial\" , & \"tbl\" , m , n , size ( tbl , 1 ), size ( tbl , 2 )) return end if ! Process do col = 1 , n stride = 1 if ( col /= n ) stride = product ( vars ( col + 1 : n )) val = 1 do i = 1 , m , stride last = i + stride - 1 tbl ( i : last , col ) = val val = val + 1 if ( val > vars ( col )) val = 1 end do end do end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_experimental_design.f90.html"},{"title":"fstats_allan.f90 – FSTATS","text":"Source Code module fstats_allan use iso_fortran_env use fstats_errors implicit none private public :: allan_variance contains ! ------------------------------------------------------------------------------ ! REF: Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, ! Viraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm for ! Fully Overlapped Allan Variance and Total Variance for Analysis and Modeling ! of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. ! 10.1109/LSENS.2018.2829799. ! ! https://www.researchgate.net/publication/324738301_A_Fast_Parallel_Algorithm_for_Fully_Overlapped_Allan_Variance_and_Total_Variance_for_Analysis_and_Modeling_of_Noise_in_Inertial_Sensors ! https://github.com/shrikanth95/Fast-Parallel-Fully-Overlapped-Allan-Variance-and-Total-Variance/blob/master/fast_FOAV.m function allan_variance ( x , dt , err ) result ( rst ) !! Computes the Allan variance of a data set. !! !! Remarks !! !! This implementation computes the fully overlapped Allan variance !! using the method presented by Yadav et. al. !! !! Yadav, Shrikanth & Shastri, Saurav & Chakravarthi, Ghanashyam & Kumar, !! Viraj & Rao, Divya & Agrawal, Vinod. (2018). A Fast, Parallel Algorithm !! for Fully Overlapped Allan Variance and Total Variance for Analysis and !! Modeling of Noise in Inertial Sensors. IEEE Sensors Letters. PP. 1-1. !! 10.1109/LSENS.2018.2829799. real ( real64 ), intent ( in ), dimension (:) :: x !! The N-element data set to analyze. real ( real64 ), intent ( in ), optional :: dt !! An optional input specifying the time increment between !! samples in x. If not specified, this value is set to 1. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. real ( real64 ), allocatable , dimension (:,:) :: rst !! An M-by-2 array containing the results where M is N / 2 - 1 !! if N is even; else, M is (N - 1) / 2 - 1 if N is odd. The !! first column contains the averaging times associated with !! the M results stored in the second column. ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr integer ( int32 ) :: flag , j , m , n , limit , nr real ( real64 ), allocatable , dimension (:) :: tall1 , tall2 real ( real64 ) :: temp , deltaT ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( dt )) then deltaT = dt else deltaT = 1.0d0 end if ! Initialization n = size ( x ) limit = n nr = floor ( 0.5 * n ) - 1 allocate ( tall1 ( n - 1 ), source = x (: n - 1 ), stat = flag ) if ( flag == 0 ) allocate ( tall2 ( n - 1 ), source = x ( 2 : n )) if ( flag == 0 ) allocate ( rst ( nr , 2 ), source = 0.0d0 ) if ( flag /= 0 ) go to 10 ! Process do m = 1 , nr temp = 0.0d0 do j = 1 , limit - 1 temp = temp + ( tall2 ( j ) - tall1 ( j )) ** 2 tall1 ( j ) = tall1 ( j ) + x ( min ( n , m + j )) tall2 ( j ) = tall2 ( min ( n - 1 , j + 1 )) + x ( min ( n , 2 * m + j + 1 )) end do limit = limit - 2 rst ( m , 1 ) = dt * m rst ( m , 2 ) = temp / ( 2.0d0 * ( n - 2 * m + 1 ) * m ** 2 ) end do ! End return ! Memory Error Handling 10 continue call report_memory_error ( errmgr , \"allan_variance\" , flag ) return end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_allan.f90.html"},{"title":"fstats_distributions.f90 – FSTATS","text":"Source Code module fstats_distributions use iso_fortran_env use ieee_arithmetic use fstats_special_functions use fstats_helper_routines implicit none private public :: distribution public :: distribution_function public :: distribution_property public :: t_distribution public :: normal_distribution public :: f_distribution public :: chi_squared_distribution public :: binomial_distribution real ( real64 ), parameter :: pi = 2.0d0 * acos ( 0.0d0 ) type , abstract :: distribution !! Defines a probability distribution. contains procedure ( distribution_function ), deferred , pass :: pdf !! Computes the probability density function. procedure ( distribution_function ), deferred , pass :: cdf !! Computes the cumulative distribution function. procedure ( distribution_property ), deferred , pass :: mean !! Computes the mean of the distribution. procedure ( distribution_property ), deferred , pass :: median !! Computes the median of the distribution. procedure ( distribution_property ), deferred , pass :: mode !! Computes the mode of the distribution. procedure ( distribution_property ), deferred , pass :: variance !! Computes the variance of the distribution. procedure , public :: standardized_variable => dist_std_var !! Computes the standardized variable for the distribution. end type interface pure elemental function distribution_function ( this , x ) result ( rst ) !! Defines the interface for a probability distribution function. use iso_fortran_env , only : real64 import distribution class ( distribution ), intent ( in ) :: this !! The distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. end function pure function distribution_property ( this ) result ( rst ) !! Computes the value of a distribution property. use iso_fortran_env , only : real64 import distribution class ( distribution ), intent ( in ) :: this !! The distribution object. real ( real64 ) :: rst !! The property value. end function end interface ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: t_distribution !! Defines Student's T-Distribution. real ( real64 ) :: dof !! The number of degrees of freedom. contains procedure , public :: pdf => td_pdf procedure , public :: cdf => td_cdf procedure , public :: mean => td_mean procedure , public :: median => td_median procedure , public :: mode => td_mode procedure , public :: variance => td_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: normal_distribution !! Defines a normal distribution. real ( real64 ) :: standard_deviation !! The standard deviation of the distribution. real ( real64 ) :: mean_value !! The mean value of the distribution. contains procedure , public :: pdf => nd_pdf procedure , public :: cdf => nd_cdf procedure , public :: mean => nd_mean procedure , public :: median => nd_median procedure , public :: mode => nd_mode procedure , public :: variance => nd_variance procedure , public :: standardize => nd_standardize end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: f_distribution !! Defines an F-distribution. real ( real64 ) :: d1 !! The measure of degrees of freedom for the first data set. real ( real64 ) :: d2 !! The measure of degrees of freedom for the second data set. contains procedure , public :: pdf => fd_pdf procedure , public :: cdf => fd_cdf procedure , public :: mean => fd_mean procedure , public :: median => fd_median procedure , public :: mode => fd_mode procedure , public :: variance => fd_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: chi_squared_distribution !! Defines a Chi-squared distribution. integer ( int32 ) :: dof !! The number of degrees of freedom. contains procedure , public :: pdf => cs_pdf procedure , public :: cdf => cs_cdf procedure , public :: mean => cs_mean procedure , public :: median => cs_median procedure , public :: mode => cs_mode procedure , public :: variance => cs_variance end type ! ------------------------------------------------------------------------------ type , extends ( distribution ) :: binomial_distribution !! Defines a binomial distribution. The binomial distribution describes !! the probability p of getting k successes in n independent trials. integer ( int32 ) :: n !! The number of independent trials. real ( real64 ) :: p !! The success probability for each trial. This parameter must !! exist on the set [0, 1]. contains procedure , public :: pdf => bd_pdf procedure , public :: cdf => bd_cdf procedure , public :: mean => bd_mean procedure , public :: median => bd_median procedure , public :: mode => bd_mode procedure , public :: variance => bd_variance end type contains ! ------------------------------------------------------------------------------ pure elemental function dist_std_var ( this , x ) result ( rst ) !! Computes the standardized variable for the distribution. class ( distribution ), intent ( in ) :: this !! The distribution object. real ( real64 ), intent ( in ) :: x !! The value of interest. real ( real64 ) :: rst !! The result. ! Local Variables integer ( int32 ), parameter :: maxiter = 100 real ( real64 ), parameter :: tol = 1.0d-6 integer ( int32 ) :: i real ( real64 ) :: f , df , h , twoh , dy ! Process ! ! We use a simplified Newton's method to solve for the independent variable ! of the CDF function h = 1.0d-6 twoh = 2.0d0 * h rst = 0.5d0 ! just an initial guess do i = 1 , maxiter ! Compute the CDF and its derivative at y f = this % cdf ( rst ) - x df = ( this % cdf ( rst + h ) - this % cdf ( rst - h )) / twoh dy = f / df rst = rst - dy if ( abs ( dy ) < tol ) exit end do end function ! ****************************************************************************** ! STUDENT'S T-DISTRIBUTION ! ------------------------------------------------------------------------------ ! REF: https://en.wikipedia.org/wiki/Student%27s_t-distribution pure elemental function td_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for Student's T-Distribution is given as !! f(t) = \\frac{ \\Gamma \\left( \\frac{\\nu + 1}{2} \\right) } !! { \\sqrt{\\nu \\pi} \\Gamma \\left( \\frac{\\nu}{2} \\right) } !! \\left( 1 + \\frac{t^2}{\\nu} \\right)^{-(\\nu + 1) / 2} . class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process rst = gamma (( this % dof + 1.0d0 ) / 2.0d0 ) / & ( sqrt ( this % dof * pi ) * gamma ( this % dof / 2.0d0 )) * & ( 1.0d0 + x ** 2 / this % dof ) ** ( - 0.5d0 * ( 1.0d0 + this % dof )) end function ! ------------------------------------------------------------------------------ pure elemental function td_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for Student's T-Distribution is given as !! F(t) = \\int_{-\\infty}^{t} f(u) \\,du = 1 - \\frac{1}{2} I_{x(t)} !! \\left( \\frac{\\nu}{2}, \\frac{1}{2} \\right) !! where x(t) = \\frac{\\nu}{\\nu + t^2} . class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: t t = this % dof / ( this % dof + x ** 2 ) rst = 1.0d0 - 0.5d0 * regularized_beta ( 0.5d0 * this % dof , 0.5d0 , t ) if ( x < 0 ) rst = 1.0d0 - rst end function ! ------------------------------------------------------------------------------ pure function td_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The mean. ! Process if ( this % dof < 1.0d0 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) else rst = 0.0d0 end if end function ! ------------------------------------------------------------------------------ pure function td_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst ! Process rst = 0.0d0 end function ! ------------------------------------------------------------------------------ pure function td_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The mode. ! Process rst = 0.0d0 end function ! ------------------------------------------------------------------------------ pure function td_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( t_distribution ), intent ( in ) :: this !! The t_distribution object. real ( real64 ) :: rst !! The variance. ! Process if ( this % dof <= 1.0d0 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) else if ( this % dof > 1.0d0 . and . this % dof <= 2.0d0 ) then rst = ieee_value ( rst , IEEE_POSITIVE_INF ) else rst = this % dof / ( this % dof - 2.0d0 ) end if end function ! ****************************************************************************** ! NORMAL DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function nd_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a normal distribution is given as !! f(x) = \\frac{1}{\\sigma \\sqrt{2 \\pi}} \\exp \\left(-\\frac{1}{2} !! \\left( \\frac{x - \\mu}{\\sigma} \\right)^2 \\right) . class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. rst = exp ( - 0.5d0 * (( x - this % mean_value ) / this % standard_deviation ) ** 2 ) / & ( this % standard_deviation * sqrt ( 2.0d0 * pi )) end function ! ------------------------------------------------------------------------------ pure elemental function nd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a normal distribution is given as !! F(x) = \\frac{1}{2} \\left( 1 + erf \\left( \\frac{x - \\mu} !! {\\sigma \\sqrt{2}} \\right) \\right) . class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. rst = 0.5d0 * ( 1.0d0 + erf (( x - this % mean_value ) / & ( this % standard_deviation * sqrt ( 2.0d0 )))) end function ! ------------------------------------------------------------------------------ pure function nd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The mean rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The median. rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The mode. rst = this % mean_value end function ! ------------------------------------------------------------------------------ pure function nd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( normal_distribution ), intent ( in ) :: this !! The normal_distribution object. real ( real64 ) :: rst !! The variance. rst = this % standard_deviation ** 2 end function ! ------------------------------------------------------------------------------ subroutine nd_standardize ( this ) !! Standardizes the normal distribution to a mean of 0 and a !! standard deviation of 1. class ( normal_distribution ), intent ( inout ) :: this !! The normal_distribution object. this % mean_value = 0.0d0 this % standard_deviation = 1.0d0 end subroutine ! ****************************************************************************** ! F DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function fd_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a F distribution is given as !! f(x) = !! \\sqrt{ \\frac{ (d_1 x)^{d_1} d_{2}^{d_2} }{ (d_1 x + d_2)^{d_1 + d_2} } } !! \\frac{1}{x \\beta \\left( \\frac{d_1}{2}, \\frac{d_2}{2} \\right) } . class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 rst = ( 1.0d0 / beta ( 0.5d0 * d1 , 0.5d0 * d2 )) * ( d1 / d2 ) ** ( 0.5d0 * d1 ) * & x ** ( 0.5d0 * d1 - 1.0d0 ) * ( 1.0d0 + d1 * x / d2 ) ** ( - 0.5d0 * ( d1 + d2 )) end function ! ------------------------------------------------------------------------------ pure elemental function fd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a F distribution is given as !! F(x) = I_{d_1 x/(d_1 x + d_2)} \\left( \\frac{d_1}{2}, !! \\frac{d_2}{2} \\right) . class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 rst = regularized_beta ( 0.5d0 * d1 , 0.5d0 * d2 , d1 * x / ( d1 * x + d2 )) end function ! ------------------------------------------------------------------------------ pure function fd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The mean. ! Process if ( this % d2 > 2.0d0 ) then rst = this % d2 / ( this % d2 - 2.0d0 ) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ------------------------------------------------------------------------------ pure function fd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The median. rst = ieee_value ( rst , IEEE_QUIET_NAN ) end function ! ------------------------------------------------------------------------------ pure function fd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The mode. ! Process if ( this % d1 > 2.0d0 ) then rst = (( this % d1 - 2.0d0 ) / this % d1 ) * ( this % d2 / ( this % d2 + 2.0d0 )) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ------------------------------------------------------------------------------ pure function fd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( f_distribution ), intent ( in ) :: this !! The f_distribution object. real ( real64 ) :: rst !! The variance. ! Process real ( real64 ) :: d1 , d2 d1 = this % d1 d2 = this % d2 if ( d2 > 4.0d0 ) then rst = ( 2.0d0 * d2 ** 2 * ( d1 + d2 - 2.0d0 )) / & ( d1 * ( d2 - 2.0d0 ) ** 2 * ( d2 - 4.0d0 )) else rst = ieee_value ( rst , IEEE_QUIET_NAN ) end if end function ! ****************************************************************************** ! CHI-SQUARED DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function cs_pdf ( this , x ) result ( rst ) !! Computes the probability density function. !! !! The PDF for a Chi-squared distribution is given as !! f(x) = \\frac{x^{k/2 - 1} \\exp{-x / 2}} {2^{k / 2} !! \\Gamma \\left( \\frac{k}{2} \\right)} . class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: arg ! Process arg = 0.5d0 * this % dof rst = 1.0d0 / ( 2.0d0 ** arg * gamma ( arg )) * x ** ( arg - 1.0d0 ) * exp ( - 0.5d0 * x ) end function ! ------------------------------------------------------------------------------ pure elemental function cs_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution function. !! !! The CDF for a Chi-squared distribution is given as !! F(x) = \\frac{ \\gamma \\left( \\frac{k}{2}, \\frac{x}{2} \\right) } !! { \\Gamma \\left( \\frac{k}{2} \\right)} . class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: arg ! Process arg = 0.5d0 * this % dof rst = incomplete_gamma_lower ( arg , 0.5d0 * x ) / gamma ( arg ) end function ! ------------------------------------------------------------------------------ pure function cs_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The mean. ! Process rst = real ( this % dof , real64 ) end function ! ------------------------------------------------------------------------------ pure function cs_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The median. ! Process rst = this % dof * ( 1.0d0 - 2.0d0 / ( 9.0d0 * this % dof )) ** 3 end function ! ------------------------------------------------------------------------------ pure function cs_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The mode. ! Process rst = max ( this % dof - 2.0d0 , 0.0d0 ) end function ! ------------------------------------------------------------------------------ pure function cs_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( chi_squared_distribution ), intent ( in ) :: this !! The chi_squared_distribution object. real ( real64 ) :: rst !! The variance. ! Process rst = 2.0d0 * this % dof end function ! ****************************************************************************** ! BINOMIAL DISTRIBUTION ! ------------------------------------------------------------------------------ pure elemental function bd_pdf ( this , x ) result ( rst ) !! Computes the probability mass function. !! !! The PMF for a binomial distribution is given as !! f(k,n,p) = \\frac{n!}{k! \\left( n - k! \\right)} p^k !! \\left( 1 - p \\right)^{n-k} . class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. This parameter !! is the number k successes in the n independent trials. As !! such, this parameter must exist on the set [0, n]. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: dn ! Process dn = real ( this % n , real64 ) rst = ( factorial ( dn ) / ( factorial ( x ) * factorial ( dn - x ))) * ( this % p ** x ) * ( 1.0d0 - this % p ) ** ( dn - x ) end function ! ------------------------------------------------------------------------------ pure elemental function bd_cdf ( this , x ) result ( rst ) !! Computes the cumulative distribution funtion. !! !! The CDF for a binomial distribution is given as !! F(k,n,p) = I_{1-p} \\left( n - k, 1 + k \\right) , which is simply !! the regularized incomplete beta function. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. This parameter !! is the number k successes in the n independent trials. As !! such, this parameter must exist on the set [0, n]. real ( real64 ) :: rst !! The value of the function. ! Local Variables real ( real64 ) :: dn ! Process dn = real ( this % n , real64 ) rst = regularized_beta ( dn - x , x + 1.0d0 , 1.0d0 - this % p ) end function ! ------------------------------------------------------------------------------ pure function bd_mean ( this ) result ( rst ) !! Computes the mean of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The mean. rst = real ( this % n * this % p , real64 ) end function ! ------------------------------------------------------------------------------ pure function bd_median ( this ) result ( rst ) !! Computes the median of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The median. rst = real ( this % n * this % p , real64 ) end function ! ------------------------------------------------------------------------------ pure function bd_mode ( this ) result ( rst ) !! Computes the mode of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The mode. rst = ( this % n + 1.0d0 ) * this % p end function ! ------------------------------------------------------------------------------ pure function bd_variance ( this ) result ( rst ) !! Computes the variance of the distribution. class ( binomial_distribution ), intent ( in ) :: this !! The binomial_distribution object. real ( real64 ) :: rst !! The variance. rst = this % n * this % p * ( 1.0d0 - this % p ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_distributions.f90.html"},{"title":"fstats_types.f90 – FSTATS","text":"Source Code module fstats_types use iso_fortran_env implicit none type array_container !! Provides a container for a real-valued array. A practical use of !! this construct is in the construction of jagged arrays. real ( real64 ), allocatable , dimension (:) :: x !! The array. end type end module","tags":"","loc":"sourcefile\\fstats_types.f90.html"},{"title":"fstats_regression.f90 – FSTATS","text":"Source Code module fstats_regression use iso_fortran_env use linalg use fstats_errors use blas use ferror use fstats_descriptive_statistics use fstats_distributions use fstats_special_functions use fstats_hypothesis implicit none private public :: iteration_controls public :: convergence_info public :: lm_solver_options public :: regression_function public :: iteration_update public :: regression_statistics public :: r_squared public :: adjusted_r_squared public :: correlation public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: calculate_regression_statistics public :: jacobian public :: nonlinear_least_squares public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE ! ****************************************************************************** ! CONSTANTS ! ------------------------------------------------------------------------------ integer ( int32 ), parameter :: FS_LEVENBERG_MARQUARDT_UPDATE = 1 integer ( int32 ), parameter :: FS_QUADRATIC_UPDATE = 2 integer ( int32 ), parameter :: FS_NIELSEN_UPDATE = 3 ! ****************************************************************************** ! TYPES ! ------------------------------------------------------------------------------ type regression_statistics !! A container for regression-related statistical information. real ( real64 ) :: standard_error !! The standard error for the model coefficient. !! !! E_{s}(\\beta_{i}) = \\sqrt{\\sigma^{2} C_{ii}} real ( real64 ) :: t_statistic !! The T-statistic for the model coefficient. !! !! t_o = \\frac{ \\beta_{i} }{E_{s}(\\beta_{i})} real ( real64 ) :: probability !! The probability that the coefficient is not statistically !! important. A statistically important coefficient will have a !! low probability (p-value), typically 0.05 or lower; however, a !! p-value of up to ~0.2 may be acceptable dependent upon the !! problem. Typically any p-value larger than ~0.2 indicates the !! parameter is not statistically important for the model. !! !! p = t_{|t_o|, df_{residual}} real ( real64 ) :: confidence_interval !! The confidence interval for the parameter at the level !! determined by the regression process. !! !! c = t_{\\alpha, df} E_{s}(\\beta_{i}) end type type iteration_controls !! Provides a collection of iteration control parameters. integer ( int32 ) :: max_iteration_count !! Defines the maximum number of iterations allowed. integer ( int32 ) :: max_function_evaluations !! Defines the maximum number of function evaluations allowed. real ( real64 ) :: gradient_tolerance !! Defines a tolerance on the gradient of the fitted function. real ( real64 ) :: change_in_solution_tolerance !! Defines a tolerance on the change in parameter values. real ( real64 ) :: residual_tolerance !! Defines a tolerance on the metric associated with the residual !! error. real ( real64 ) :: iteration_improvement_tolerance !! Defines a tolerance to ensure adequate improvement on each !! iteration. integer ( int32 ) :: max_iteration_between_updates !! Defines how many iterations can pass before a re-evaluation of !! the Jacobian matrix is forced. contains procedure , public :: set_to_default => lm_set_default_tolerances end type type convergence_info !! Provides information regarding convergence status. logical :: converge_on_gradient !! True if convergence on the gradient was achieved; else, false. real ( real64 ) :: gradient_value !! The value of the gradient test parameter. logical :: converge_on_solution_change !! True if convergence on the change in solution was achieved; else, !! false. real ( real64 ) :: solution_change_value !! The value of the change in solution parameter. logical :: converge_on_residual_parameter !! True if convergence on the residual error parameter was achieved; !! else, false. real ( real64 ) :: residual_value !! The value of the residual error parameter. logical :: reach_iteration_limit !! True if the solution did not converge in the allowed number of !! iterations. integer ( int32 ) :: iteration_count !! The iteration count. logical :: reach_function_evaluation_limit !! True if the solution did not converge in the allowed number of !! function evaluations. integer ( int32 ) :: function_evaluation_count !! The function evaluation count. logical :: user_requested_stop !! True if the user requested the stop; else, false. end type type lm_solver_options !! Options to control the Levenberg-Marquardt solver. integer ( int32 ) :: method !! The solver method to utilize. !! - FS_LEVENBERG_MARQUARDT_UPDATE: !! - FS_QUADRATIC_UPDATE: !! - FS_NIELSEN_UDPATE: real ( real64 ) :: finite_difference_step_size !! The step size used for the finite difference calculations of the !! Jacobian matrix. real ( real64 ) :: damping_increase_factor !! The factor to use when increasing the damping parameter. real ( real64 ) :: damping_decrease_factor !! The factor to use when decreasing the damping parameter. contains procedure , public :: set_to_default => lm_set_default_settings end type interface subroutine regression_function ( xdata , params , resid , stop ) use iso_fortran_env , only : real64 real ( real64 ), intent ( in ), dimension (:) :: xdata , params real ( real64 ), intent ( out ), dimension (:) :: resid logical , intent ( out ) :: stop end subroutine subroutine iteration_update ( iter , funvals , resid , params , step ) use iso_fortran_env , only : int32 , real64 integer ( int32 ), intent ( in ) :: iter real ( real64 ), intent ( in ) :: funvals (:), resid (:), params (:), step (:) end subroutine end interface contains ! ------------------------------------------------------------------------------ function r_squared ( x , xm , err ) result ( rst ) !! Computes the R-squared value for a data set. !! !! The R-squared value is computed by determining the sum of the squares !! of the residuals: !! SS_{res} = \\Sigma \\left( y_i - f_i \\right)^2 !! The total sum of the squares: !! SS_{tot} = \\Sigma \\left( y_i - \\bar{y} \\right)^2 . !! The R-squared value is then: !! R^2 = 1 - \\frac{SS_{res}}{SS_{tot}} . !! !! See Also: !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Coefficient_of_determination) real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the dependent variables from !! the data set. real ( real64 ), intent ( in ) :: xm (:) !! An N-element array containing the corresponding modeled !! values. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings !! to the caller. Possible warning and error codes are as !! follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the !! same size. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: esum , vt class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Input Check n = size ( x ) if ( size ( xm ) /= n ) then call report_array_size_error ( errmgr , \"r_squared_real64\" , \"XM\" , n , & size ( xm )) return end if ! Process esum = zero do i = 1 , n esum = esum + ( x ( i ) - xm ( i )) ** 2 end do vt = variance ( x ) * ( n - one ) rst = one - esum / vt end function ! ------------------------------------------------------------------------------ function adjusted_r_squared ( p , x , xm , err ) result ( rst ) !! Computes the adjusted R-squared value for a data set. !! !! The adjusted R-squared provides a mechanism for tempering the effects !! of extra explanatory variables on the traditional R-squared !! calculation. It is computed by noting the sample size n and !! the number of variables p . !! \\bar{R}^2 = 1 - \\left( 1 - R^2 \\right) \\frac{n - 1}{n - p} . !! !! See Also: !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Coefficient_of_determination#Adjusted_R2) integer ( int32 ), intent ( in ) :: p !! The number of variables. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the dependent variables from !! the data set. real ( real64 ), intent ( in ) :: xm (:) !! An N-element array containing the corresponding modeled !! values. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings !! to the caller. Possible warning and error codes are as !! follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x and xm are not the !! same size. real ( real64 ) :: rst !! The result. ! Local Variables integer ( int32 ) :: n real ( real64 ) :: r2 class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n = size ( x ) ! Process r2 = r_squared ( x , xm , errmgr ) if ( errmgr % has_error_occurred ()) return rst = one - ( one - r2 ) * ( n - one ) / ( n - p - one ) end function ! ------------------------------------------------------------------------------ pure function correlation ( x , y ) result ( rst ) !! Computes the sample correlation coefficient (an estimate to the !! population Pearson correlation) as follows. !! !! r_{xy} = \\frac{cov(x, y)}{s_{x} s_{y}} . !! !! Where, s_{x} & s_{y} are the sample standard deviations of !! x and y respectively. real ( real64 ), intent ( in ), dimension (:) :: x !! The first N-element data set. real ( real64 ), intent ( in ), dimension ( size ( x )) :: y !! The second N-element data set. real ( real64 ) :: rst !! The correlation coefficient. ! Process rst = covariance ( x , y ) / ( standard_deviation ( x ) * standard_deviation ( y )) end function ! ------------------------------------------------------------------------------ subroutine design_matrix ( order , intercept , x , c , err ) !! Computes the design matrix X for the linear !! least-squares regression problem of X \\beta = y , where !! X is the matrix computed here, \\beta is !! the vector of coefficients to be determined, and y is the !! vector of measured dependent variables. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) !! - [Wikipedia](https://en.wikipedia.org/wiki/Vandermonde_matrix) !! - [Wikipedia](https://en.wikipedia.org/wiki/Design_matrix) integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be !! at least one (linear equation), but can be higher as desired. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed !! as part of the regression; else, false. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( out ) :: c (:,:) !! An N-by-K matrix where the results will be written. K !! must equal order + 1 in the event intercept is true; !! however, if intercept is false, K must equal order. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not properly sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , start , npts , ncols class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x ) ncols = order if ( intercept ) ncols = ncols + 1 ! Input Check if ( order < 1 ) then call errmgr % report_error ( \"design_matrix\" , & \"The model order must be at least one.\" , FS_INVALID_INPUT_ERROR ) return end if if ( size ( c , 1 ) /= npts . or . size ( c , 2 ) /= ncols ) then call report_matrix_size_error ( errmgr , \"design_matrix\" , & \"c\" , npts , ncols , size ( c , 1 ), size ( c , 2 )) return end if ! Process if ( intercept ) then c (:, 1 ) = one c (:, 2 ) = x start = 3 else c (:, 1 ) = x start = 2 end if if ( start >= ncols ) return do i = start , ncols c (:, i ) = c (:, i - 1 ) * x end do end subroutine ! ------------------------------------------------------------------------------ subroutine covariance_matrix ( x , c , err ) !! Computes the covariance matrix C where !! C = \\left( X^{T} X \\right)^{-1} and X is computed !! by design_matrix. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Covariance_matrix) !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) real ( real64 ), intent ( in ) :: x (:,:) !! An M-by-N matrix containing the formatted independent data !! matrix X as computed by design_matrix. real ( real64 ), intent ( out ) :: c (:,:) !! The N-by-N covariance matrix. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the matrices are not !! sized correctly. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr integer ( int32 ) :: npts , ncoeffs , flag real ( real64 ), allocatable :: xtx (:,:) ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x , 1 ) ncoeffs = size ( x , 2 ) ! Input Checking if ( size ( c , 1 ) /= ncoeffs . or . size ( c , 2 ) /= ncoeffs ) then call report_matrix_size_error ( errmgr , \"covariance_matrix\" , & \"c\" , ncoeffs , ncoeffs , size ( c , 1 ), size ( c , 2 )) return end if ! Local Memory Allocation allocate ( xtx ( ncoeffs , ncoeffs ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"covariance_matrix\" , flag ) return end if ! Compute X**T * X call DGEMM ( \"T\" , \"N\" , ncoeffs , ncoeffs , npts , one , x , npts , x , npts , & zero , xtx , ncoeffs ) ! Compute the inverse of X**T * X to obtain the covariance matrix call mtx_pinverse ( xtx , c , err = errmgr ) if ( errmgr % has_error_occurred ()) return end subroutine ! ------------------------------------------------------------------------------ subroutine linear_least_squares ( order , intercept , x , y , coeffs , & ymod , resid , stats , alpha , err ) !! Computes a linear least-squares regression to fit a set of data. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) integer ( int32 ), intent ( in ) :: order !! The order of the equation to fit. This value must be at !! least one (linear equation), but can be higher as desired, !! as long as there is sufficient data. logical , intent ( in ) :: intercept !! Set to true if the intercept is being computed as part of !! the regression; else, false. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the independent variable !! measurement points. real ( real64 ), intent ( in ) :: y (:) !! An N-element array containing the dependent variable !! measurement points. real ( real64 ), intent ( out ) :: coeffs (:) !! An ORDER+1 element array where the coefficients will be written. real ( real64 ), intent ( out ) :: ymod (:) !! An N-element array where the modeled data will be written. real ( real64 ), intent ( out ) :: resid (:) !! An N-element array where the residual error data will be !! written (modeled - actual). type ( regression_statistics ), intent ( out ), optional :: stats (:) !! An M-element array of regression_statistics items where !! M = ORDER + 1 when intercept is set to true; however, if !! intercept is set to false, M = ORDER. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , npts , ncols , ncoeffs , flag real ( real64 ) :: alph , var , df , ssr , talpha real ( real64 ), allocatable :: a (:,:), c (:,:), cxt (:,:) type ( t_distribution ) :: dist class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if npts = size ( x ) ncoeffs = order + 1 ncols = order if ( intercept ) ncols = ncols + 1 alph = 0.05d0 if ( present ( alpha )) alph = alpha ! Input Check if ( order < 1 ) then call errmgr % report_error ( \"linear_least_squares\" , & \"The model order must be at least one.\" , FS_INVALID_INPUT_ERROR ) return end if if ( size ( y ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"y\" , npts , size ( y )) return end if if ( size ( coeffs ) /= ncoeffs ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"coeffs\" , ncoeffs , size ( coeffs )) return end if if ( size ( ymod ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"ymod\" , npts , size ( ymod )) return end if if ( size ( resid ) /= npts ) then call report_array_size_error ( errmgr , \"linear_least_squares\" , & \"resid\" , npts , size ( resid )) return end if if ( present ( stats )) then if ( size ( stats ) /= ncols ) then call report_array_size_error ( errmgr , & \"linear_least_squares\" , \"stats\" , ncols , size ( stats )) return end if end if ! Memory Allocation allocate ( a ( npts , ncols ), stat = flag ) if ( flag == 0 ) allocate ( c ( ncols , ncols ), stat = flag ) if ( flag == 0 ) allocate ( cxt ( ncols , npts ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"linear_least_squares\" , flag ) return end if ! Compute the coefficient matrix call design_matrix ( order , intercept , x , a , errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the covariance matrix call covariance_matrix ( a , c , errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the coefficients (NCOLS-by-1) call DGEMM ( \"N\" , \"T\" , ncols , npts , ncols , one , c , ncols , a , npts , zero , & cxt , ncols ) ! C * X**T i = 2 coeffs ( 1 ) = zero if ( intercept ) i = 1 call DGEMM ( \"N\" , \"N\" , ncols , 1 , npts , one , cxt , ncols , y , npts , zero , & coeffs ( i :), ncols ) ! (C * X**T) * Y ! Evaluate the model and compute the residuals call DGEMM ( \"N\" , \"N\" , npts , 1 , ncols , one , a , npts , coeffs ( i :), & ncols , zero , ymod , npts ) resid = ymod - y ! If the user doesn't want the statistics calculations we can stop now if (. not . present ( stats )) return ! Start the process of computing statistics stats = calculate_regression_statistics ( resid , coeffs ( i :), c , alph , & errmgr ) end subroutine ! ------------------------------------------------------------------------------ function calculate_regression_statistics ( resid , params , c , alpha , err ) & result ( rst ) !! Computes statistics for the quality of fit for a regression !! model. real ( real64 ), intent ( in ) :: resid (:) !! An M-element array containing the model residual errors. real ( real64 ), intent ( in ) :: params (:) !! An N-element array containing the model parameters. real ( real64 ), intent ( in ) :: c (:,:) !! The N-by-N covariance matrix. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if c is not sized correctly. !! - FS_INVALID_INPUT_ERROR: Occurs if order is less than 1. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. type ( regression_statistics ), allocatable :: rst (:) !! A regression_statistics object containing the analysis results. ! Parameters real ( real64 ), parameter :: p05 = 0.05d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , m , n , dof , flag real ( real64 ) :: a , ssr , var , talpha type ( t_distribution ) :: dist class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if ! Initialization m = size ( resid ) n = size ( params ) dof = m - n if ( present ( alpha )) then a = alpha else a = p05 end if allocate ( rst ( n ), stat = flag ) if ( flag /= 0 ) then end if ! Input Checking if ( size ( c , 1 ) /= n . or . size ( c , 2 ) /= n ) then end if ! Process ssr = norm2 ( resid ) ** 2 ! sum of the squares of the residual var = ssr / dof dist % dof = real ( dof , real64 ) talpha = confidence_interval ( dist , a , one , 1 ) do i = 1 , n rst ( i )% standard_error = sqrt ( var * c ( i , i )) rst ( i )% t_statistic = params ( i ) / rst ( i )% standard_error rst ( i )% probability = regularized_beta ( & half * dof , & half , & real ( dof , real64 ) / ( dof + ( rst ( i )% t_statistic ) ** 2 ) & ) rst ( i )% confidence_interval = talpha * rst ( i )% standard_error end do end function ! ------------------------------------------------------------------------------ subroutine jacobian ( fun , xdata , params , & jac , stop , f0 , f1 , step , err ) !! Computes the Jacobian matrix for a nonlinear regression problem. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: xdata (:) !! The M-element array containing x-coordinate data. real ( real64 ), intent ( in ) :: params (:) !! The N-element array containing the model parameters. real ( real64 ), intent ( out ) :: jac (:,:) !! The M-by-N matrix where the Jacobian will be written. logical , intent ( out ) :: stop !! A value that the user can set in fun forcing the !! evaluation process to stop prior to completion. real ( real64 ), intent ( in ), optional , target :: f0 (:) !! An optional M-element array containing the model values !! using the current parameters as defined in m. This input !! can be used to prevent the routine from performing a !! function evaluation at the model parameter state defined in !! params. real ( real64 ), intent ( out ), optional , target :: f1 (:) !! An optional M-element workspace array used for function !! evaluations. real ( real64 ), intent ( in ), optional :: step !! The differentiation step size. The default is the square !! root of machine precision. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. ! Local Variables real ( real64 ) :: h integer ( int32 ) :: m , n , flag , expected , actual real ( real64 ), pointer :: f1p (:), f0p (:) real ( real64 ), allocatable , target :: f1a (:), f0a (:), work (:) class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( step )) then h = step else h = sqrt ( epsilon ( h )) end if m = size ( xdata ) n = size ( params ) ! Input Size Checking if ( size ( jac , 1 ) /= m . or . size ( jac , 2 ) /= n ) then call report_matrix_size_error ( errmgr , \"jacobian\" , & \"JAC\" , m , n , size ( jac , 1 ), size ( jac , 2 )) return end if if ( present ( f0 )) then ! Check Size if ( size ( f0 ) /= m ) then call report_array_size_error ( errmgr , \"jacobian\" , & \"F0\" , m , size ( f0 )) return end if f0p ( 1 : m ) => f0 else ! Allocate space, and fill the array with the current function ! results allocate ( f0a ( m ), stat = flag ) if ( flag /= 0 ) go to 20 f0p ( 1 : m ) => f0a call fun ( xdata , params , f0p , stop ) if ( stop ) return end if if ( present ( f1 )) then ! Check Size if ( size ( f1 ) /= m ) then call report_array_size_error ( errmgr , \"jacobian\" , & \"F1\" , m , size ( f1 )) return end if f1p ( 1 : m ) => f1 else ! Allocate space allocate ( f1a ( m ), stat = flag ) if ( flag /= 0 ) go to 20 f1p ( 1 : m ) => f1a end if ! Allocate a workspace array the same size as params allocate ( work ( n ), stat = flag ) if ( flag /= 0 ) go to 20 ! Compute the Jacobian call jacobian_finite_diff ( fun , xdata , params , f0p , jac , f1p , & stop , h , work ) ! End return ! Memroy Allocation Error Handling 20 continue call report_memory_error ( errmgr , \"jacobian\" , flag ) return end subroutine ! ------------------------------------------------------------------------------ subroutine nonlinear_least_squares ( fun , x , y , params , ymod , & resid , weights , maxp , minp , stats , alpha , controls , settings , info , & status , err ) !! Performs a nonlinear regression to fit a model using a version !! of the Levenberg-Marquardt algorithm. procedure ( regression_function ), intent ( in ), pointer :: fun !! A pointer to the regression_function to evaluate. real ( real64 ), intent ( in ) :: x (:) !! The M-element array containing independent data. real ( real64 ), intent ( in ) :: y (:) !! The M-element array containing dependent data. real ( real64 ), intent ( inout ) :: params (:) !! On input, the N-element array containing the initial estimate !! of the model parameters. On output, the computed model !! parameters. real ( real64 ), intent ( out ) :: ymod (:) !! An M-element array where the modeled dependent data will !! be written. real ( real64 ), intent ( out ) :: resid (:) !! An M-element array where the model residuals will be !! written. real ( real64 ), intent ( in ), optional , target :: weights (:) !! An optional M-element array allowing the weighting of !! individual points. real ( real64 ), intent ( in ), optional , target :: maxp (:) !! An optional N-element array that can be used as upper limits !! on the parameter values. If no upper limit is requested for !! a particular parameter, utilize a very large value. The !! internal default is to utilize huge() as a value. real ( real64 ), intent ( in ), optional , target :: minp (:) !! An optional N-element array that can be used as lower limits !! on the parameter values. If no lower limit is requested for !! a particalar parameter, utilize a very large magnitude, but !! negative, value. The internal default is to utilize -huge() !! as a value. type ( regression_statistics ), intent ( out ), optional :: stats (:) !! An optional N-element array that, if supplied, will be used !! to return statistics about the fit for each parameter. real ( real64 ), intent ( in ), optional :: alpha !! The significance level at which to evaluate the confidence !! intervals. The default value is 0.05 such that a 95% !! confidence interval is calculated. type ( iteration_controls ), intent ( in ), optional :: controls !! An optional input providing custom iteration controls. type ( lm_solver_options ), intent ( in ), optional :: settings !! An optional input providing custom settings for the solver. type ( convergence_info ), intent ( out ), optional , target :: info !! An optional output that can be used to gain information about !! the iterative solution and the nature of the convergence. procedure ( iteration_update ), intent ( in ), pointer , optional :: status !! An optional pointer to a routine that can be used to extract !! iteration information. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! properly sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation !! error. !! - FS_UNDERDEFINED_PROBLEM_ERROR: Occurs if the problem posed !! is underdetetermined (M < N). !! - FS_TOLERANCE_TOO_SMALL_ERROR: Occurs if any supplied !! tolerances are too small to be practical. !! - FS_TOO_FEW_ITERATION_ERROR: Occurs if too few iterations !! are allowed. ! Parameters real ( real64 ), parameter :: too_small = 1.0d-14 integer ( int32 ), parameter :: min_iter_count = 2 integer ( int32 ), parameter :: min_fun_count = 10 integer ( int32 ), parameter :: min_update_count = 1 ! Local Variables logical :: stop integer ( int32 ) :: m , n , actual , expected , flag real ( real64 ), pointer :: w (:), pmax (:), pmin (:) real ( real64 ), allocatable , target :: defaultWeights (:), maxparam (:), & minparam (:), JtWJ (:,:) type ( iteration_controls ) :: tol type ( lm_solver_options ) :: opt type ( convergence_info ) :: cInfo class ( errors ), pointer :: errmgr type ( errors ), target :: deferr type ( convergence_info ), target :: defaultinfo type ( convergence_info ), pointer :: inf ! Initialization stop = . false . m = size ( x ) n = size ( params ) if ( present ( info )) then inf => info else inf => defaultinfo end if if ( present ( err )) then errmgr => err else errmgr => deferr end if if ( present ( controls )) then tol = controls else call tol % set_to_default () end if if ( present ( settings )) then opt = settings else call opt % set_to_default () end if ! Input Checking if ( size ( y ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"y\" , m , size ( y )) return end if if ( size ( ymod ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"ymod\" , m , size ( ymod )) return end if if ( size ( resid ) /= m ) then call report_array_size_error ( errmgr , \"nonlinear_least_squares\" , & \"resid\" , m , size ( resid )) return end if if ( m < n ) then call report_underdefined_error ( errmgr , & \"nonlinear_least_squares\" , n , m ) return end if ! Tolerance Checking if ( tol % gradient_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The gradient tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % change_in_solution_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The change in solution tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % residual_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The residual error tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if if ( tol % iteration_improvement_tolerance < too_small ) then call errmgr % report_error ( \"nonlinear_least_squares\" , & \"The iteration improvement tolerance was found to be too small.\" , & FS_TOLERANCE_TOO_SMALL_ERROR ) return end if ! Iteration Count Checking if ( tol % max_iteration_count < min_iter_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few iterations were specified.\" , & min_iter_count ) return end if if ( tol % max_function_evaluations < min_fun_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few function evaluations were specified.\" , & min_fun_count ) return end if if ( tol % max_iteration_between_updates < min_update_count ) then call report_iteration_count_error ( errmgr , & \"nonlinear_least_squares\" , & \"Too few iterations between updates were specified.\" , & min_update_count ) return end if ! Optional Array Arguments (weights, parameter limits, etc.) if ( present ( weights )) then if ( size ( weights ) < m ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"weights\" , m , size ( weights )) return end if w ( 1 : m ) => weights ( 1 : m ) else allocate ( defaultWeights ( m ), source = 1.0d0 , stat = flag ) if ( flag /= 0 ) go to 50 w ( 1 : m ) => defaultWeights ( 1 : m ) end if if ( present ( maxp )) then if ( size ( maxp ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"maxp\" , n , size ( maxp )) return end if pmax ( 1 : n ) => maxp ( 1 : n ) else allocate ( maxparam ( n ), source = huge ( 1.0d0 ), stat = flag ) if ( flag /= 0 ) go to 50 pmax ( 1 : n ) => maxparam ( 1 : n ) end if if ( present ( minp )) then if ( size ( minp ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"minp\" , n , size ( minp )) return end if pmin ( 1 : n ) => minp ( 1 : n ) else allocate ( minparam ( n ), source = - huge ( 1.0d0 ), stat = flag ) if ( flag /= 0 ) go to 50 pmin ( 1 : n ) => minparam ( 1 : n ) end if ! Local Memory Allocations allocate ( JtWJ ( n , n ), stat = flag ) if ( flag /= 0 ) go to 50 ! Process call lm_solve ( fun , x , y , params , w , pmax , pmin , tol , opt , ymod , & resid , JtWJ , inf , stop , errmgr , status ) ! Statistical Parameters if ( present ( stats )) then if ( size ( stats ) /= n ) then call report_array_size_error ( errmgr , & \"nonlinear_least_squares\" , \"stats\" , n , size ( stats )) return end if ! Compute the covariance matrix call mtx_inverse ( JtWJ , err = errmgr ) if ( errmgr % has_error_occurred ()) return ! Compute the statistics stats = calculate_regression_statistics ( resid , params , JtWJ , & alpha , errmgr ) end if ! End return ! Memory Error Handler 50 continue call report_memory_error ( errmgr , \"nonlinear_least_squares\" , flag ) return end subroutine ! ****************************************************************************** ! SETTINGS DEFAULTS ! ------------------------------------------------------------------------------ ! Sets up default tolerances. subroutine lm_set_default_tolerances ( x ) ! Arguments class ( iteration_controls ), intent ( inout ) :: x ! Set defaults x % max_iteration_count = 500 x % max_function_evaluations = 5000 x % max_iteration_between_updates = 10 x % gradient_tolerance = 1.0d-8 x % residual_tolerance = 0.5d-2 x % change_in_solution_tolerance = 1.0d-6 x % iteration_improvement_tolerance = 1.0d-1 end subroutine ! ------------------------------------------------------------------------------ ! Sets up default solver settings. subroutine lm_set_default_settings ( x ) ! Arguments class ( lm_solver_options ), intent ( inout ) :: x ! Set defaults x % method = FS_LEVENBERG_MARQUARDT_UPDATE x % finite_difference_step_size = sqrt ( epsilon ( 1.0d0 )) x % damping_increase_factor = 1 1.0d0 x % damping_decrease_factor = 9.0d0 end subroutine ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ ! Computes the Jacobian matrix via a forward difference. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - params: The model parameters (N-by-1) ! - f0: The current model estimate (M-by-1) ! - step: The differentiation step size ! ! Outputs: ! - jac: The Jacobian matrix (M-by-N) ! - f1: A workspace array for the model output (M-by-1) ! - stop: A flag allowing the user to terminate model execution ! - work: A workspace array for the model parameters (N-by-1) subroutine jacobian_finite_diff ( fun , xdata , params , f0 , jac , f1 , & stop , step , work ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), params (:) real ( real64 ), intent ( in ) :: f0 (:) real ( real64 ), intent ( out ) :: jac (:,:) real ( real64 ), intent ( out ) :: f1 (:), work (:) logical , intent ( out ) :: stop real ( real64 ), intent ( in ) :: step ! Local Variables integer ( int32 ) :: i , n ! Initialization n = size ( params ) ! Cycle over each column of the Jacobian and calculate the derivative ! via a forward difference scheme ! ! J(i,j) = df(i) / dx(j) work = params do i = 1 , n work ( i ) = work ( i ) + step call fun ( xdata , work , f1 , stop ) if ( stop ) return jac (:, i ) = ( f1 - f0 ) / step work ( i ) = params ( i ) end do end subroutine ! ------------------------------------------------------------------------------ ! Computes a rank-1 update to the Jacobian matrix ! ! Inputs: ! - pOld: previous set of parameters (N-by-1) ! - yOld: model evaluation at previous set of parameters (M-by-1) ! - jac: current Jacobian estimate (M-by-N) ! - p: current set of parameters (N-by-1) ! - y: model evaluation at current set of parameters (M-by-1) ! ! Outputs: ! - jac: updated Jacobian matrix (M-by-N) (dy * dp**T + J) ! - dp: p - pOld (N-by-1) ! - dy: (y - yOld - J * dp) / (dp' * dp) (M-by-1) subroutine broyden_update ( pOld , yOld , jac , p , y , dp , dy ) ! Arguments real ( real64 ), intent ( in ) :: pOld (:), yOld (:), p (:), y (:) real ( real64 ), intent ( inout ) :: jac (:,:) real ( real64 ), intent ( out ) :: dp (:), dy (:) ! Local Variables real ( real64 ) :: h2 ! Process dp = p - pOld h2 = dot_product ( dp , dp ) dy = y - yOld - matmul ( jac , dp ) dy = dy / h2 call rank1_update ( 1.0d0 , dy , dp , jac ) end subroutine ! ------------------------------------------------------------------------------ ! Updates the Levenberg-Marquardt matrix by either computing a new Jacobian ! matrix or performing a rank-1 update to the existing Jacobian matrix. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - pOld: previous set of parameters (N-by-1) ! - yOld: model evaluation at previous set of parameters (M-by-1) ! - dX2: The previous change in the Chi-squared criteria ! - jac: current Jacobian estimate (M-by-N) ! - p: current set of parameters (N-by-1) ! - weights: A weighting vector (M-by-1) ! - neval: Current number of function evaluations ! - update: Set to true to force an update of the Jacobian; else, set to ! false to let the program choose based upon the change in the ! Chi-squared parameter. ! - step: The differentiation step size ! ! Outputs: ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - JtWdy: linearized fitting vector (N-by-1) ! - X2: Updated Chi-squared criteria ! - yNew: model evaluated with parameters of p (M-by-1) ! - jac: updated Jacobian matrix (M-by-N) ! - neval: updated count of function evaluations ! - stop: A flag allowing the user to terminate model execution ! - work: A workspace array (N+M-by-1) ! - mwork: A workspace matrix (N-by-M) ! - update: Reset to false if a Jacobian evaluation was performed. subroutine lm_matrix ( fun , xdata , ydata , pOld , yOld , dX2 , jac , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , yNew , stop , work , mwork ) ! Arguments procedure ( regression_function ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), pOld (:), yOld (:), & p (:), weights (:) real ( real64 ), intent ( in ) :: dX2 , step real ( real64 ), intent ( inout ) :: jac (:,:) integer ( int32 ), intent ( inout ) :: neval logical , intent ( inout ) :: update real ( real64 ), intent ( out ) :: JtWJ (:,:), JtWdy (:) real ( real64 ), intent ( out ) :: X2 , mwork (:,:), yNew (:) logical , intent ( out ) :: stop real ( real64 ), intent ( out ), target :: work (:) ! Local Variables integer ( int32 ) :: m , n real ( real64 ), pointer :: w1 (:), w2 (:) ! Initialization m = size ( xdata ) n = size ( p ) w1 ( 1 : m ) => work ( 1 : m ) w2 ( 1 : n ) => work ( m + 1 : n + m ) ! Perform the next function evaluation call fun ( xdata , p , yNew , stop ) neval = neval + 1 if ( stop ) return ! Update or recompute the Jacobian matrix if ( dX2 > 0 . or . update ) then ! Recompute the Jacobian call jacobian_finite_diff ( fun , xdata , p , yNew , jac , w1 , & stop , step , w2 ) neval = neval + n if ( stop ) return update = . false . else ! Simply perform a rank-1 update to the Jacobian call broyden_update ( pOld , yOld , jac , p , yNew , w2 , w1 ) end if ! Update the Chi-squared estimate w1 = ydata - yNew X2 = dot_product ( w1 , w1 * weights ) ! Compute J**T * (W .* dY) w1 = w1 * weights call mtx_mult (. true ., 1.0d0 , jac , w1 , 0.0d0 , JtWdy ) ! Update the Hessian ! First: J**T * W = MWORK ! Second: (J**T * W) * J call diag_mtx_mult (. false ., . true ., 1.0d0 , weights , jac , 0.0d0 , mwork ) call mtx_mult (. false ., . false ., 1.0d0 , mwork , jac , 0.0d0 , JtWJ ) end subroutine ! ------------------------------------------------------------------------------ ! Performs a single iteration of the Levenberg-Marquardt algorithm. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - p: current set of parameters (N-by-1) ! - neval: current number of function evaluations ! - niter: current iteration number ! - update: set to 1 to use Marquardt's modification; else, ! - step: the differentiation step size ! - lambda: LM damping parameter ! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) ! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) ! - weights: a weighting vector (M-by-1) ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - JtWdy: linearized fitting vector (N-by-1) ! ! Outputs: ! - JtWJ: overwritten LU factorization of the original matrix (N-by-N) ! - h: The new estimate of the change in parameter (N-by-1) ! - pNew: The new parameter estimates (N-by-1) ! - deltaY: The new difference between data and model (M-by-1) ! - yNew: model evaluated with parameters of pNew (M-by-1) ! - neval: updated count of function evaluations ! - niter: updated current iteration number ! - X2: updated Chi-squared criteria ! - stop: A flag allowing the user to terminate model execution ! - iwork: A workspace array (N-by-1) ! - err: An error handling mechanism subroutine lm_iter ( fun , xdata , ydata , p , neval , niter , update , lambda , & maxP , minP , weights , JtWJ , JtWdy , h , pNew , deltaY , yNew , X2 , X2Old , & alpha , stop , iwork , err , status ) ! Arguments procedure ( regression_function ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), p (:), maxP (:), & minP (:), weights (:), JtWdy (:) real ( real64 ), intent ( in ) :: lambda , X2Old integer ( int32 ), intent ( inout ) :: neval , niter integer ( int32 ), intent ( in ) :: update real ( real64 ), intent ( inout ) :: JtWJ (:,:) real ( real64 ), intent ( out ) :: h (:), pNew (:), deltaY (:), yNew (:) real ( real64 ), intent ( out ) :: X2 , alpha logical , intent ( out ) :: stop integer ( int32 ), intent ( out ) :: iwork (:) class ( errors ), intent ( inout ) :: err procedure ( iteration_update ), intent ( in ), pointer , optional :: status ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: dpJh ! Initialization n = size ( p ) ! Increment the iteration counter niter = niter + 1 ! Solve the linear system to determine the change in parameters ! A is N-by-N and is stored in JtWJ ! b is N-by-1 if ( update == FS_LEVENBERG_MARQUARDT_UPDATE ) then ! Compute: h = A \\ b ! A = J**T * W * J + lambda * diag(J**T * W * J) ! b = J**T * W * dy do i = 1 , n JtWJ ( i , i ) = JtWJ ( i , i ) * ( 1.0d0 + lambda ) h ( i ) = JtWdy ( i ) end do else ! Compute: h = A \\ b ! A = J**T * W * J + lambda * I ! b = J**T * W * dy do i = 1 , n JtWJ ( i , i ) = JtWJ ( i , i ) + lambda h ( i ) = JtWdy ( i ) end do end if call lu_factor ( JtWJ , iwork , err ) ! overwrites JtWJ with [L\\U] if ( err % has_error_occurred ()) return ! if JtWJ is singular call solve_lu ( JtWJ , iwork , h ) ! solution stored in h ! Compute the new attempted solution, and apply any constraints do i = 1 , n pNew ( i ) = min ( max ( minP ( i ), h ( i ) + p ( i )), maxP ( i )) end do ! Update the residual error call fun ( xdata , pNew , yNew , stop ) neval = neval + 1 deltaY = ydata - yNew if ( stop ) return ! Update the Chi-squared estimate X2 = dot_product ( deltaY , deltaY * weights ) ! Perform a quadratic line update in the H direction, if necessary if ( update == FS_QUADRATIC_UPDATE ) then dpJh = dot_product ( JtWdy , h ) alpha = abs ( dpJh / ( 0.5d0 * ( X2 - X2Old ) + 2.0d0 * dpJh )) h = alpha * h do i = 1 , n pNew ( i ) = min ( max ( minP ( i ), p ( i ) + h ( i )), maxP ( i )) end do call fun ( xdata , pNew , yNew , stop ) if ( stop ) return neval = neval + 1 deltaY = ydata - yNew X2 = dot_product ( deltaY , deltaY * weights ) end if ! Update the status of the iteration, if needed if ( present ( status )) then call status ( niter , yNew , deltaY , pNew , h ) end if end subroutine ! ------------------------------------------------------------------------------ ! A Levenberg-Marquardt solver. ! ! Inputs: ! - fun: The function to evaluate ! - xdata: The independent coordinate data to fit (M-by-1) ! - ydata: The dependent coordinate data to fit (M-by-1) ! - p: current set of parameters (N-by-1) ! - weights: a weighting vector (M-by-1) ! - maxP: maximum limits on the parameters. Use huge() or larger for no constraints (N-by-1) ! - minP: minimum limits on the parameters. Use -huge() or smaller for no constraints (N-by-1) ! - controls: an iteration_controls instance containing solution tolerances ! ! Outputs: ! - p: solution (N-by-1) ! - y: model results at p (M-by-1) ! - resid: residual (ydata - y) (M-by-1) ! - JtWJ: linearized Hessian matrix (inverse of the covariance matrix) (N-by-N) ! - opt: a convergence_info object containing information regarding ! convergence of the iteration ! - stop: A flag allowing the user to terminate model execution ! - err: An error handling object subroutine lm_solve ( fun , xdata , ydata , p , weights , maxP , minP , controls , & opt , y , resid , JtWJ , info , stop , err , status ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), weights (:), maxP (:), & minP (:) real ( real64 ), intent ( inout ) :: p (:) class ( iteration_controls ), intent ( in ) :: controls class ( lm_solver_options ), intent ( in ) :: opt real ( real64 ), intent ( out ) :: y (:), resid (:), JtWJ (:,:) class ( convergence_info ), intent ( out ) :: info logical , intent ( out ) :: stop class ( errors ), intent ( inout ) :: err procedure ( iteration_update ), intent ( in ), pointer , optional :: status ! Local Variables logical :: update integer ( int32 ) :: i , m , n , dof , flag , neval , niter , nupdate real ( real64 ) :: dX2 , X2 , X2Old , X2Try , lambda , alpha , nu , step real ( real64 ), allocatable :: pOld (:), yOld (:), J (:,:), JtWdy (:), & work (:), mwork (:,:), pTry (:), yTemp (:), JtWJc (:,:), h (:) integer ( int32 ), allocatable :: iwork (:) character ( len = :), allocatable :: errmsg ! Initialization update = . true . m = size ( xdata ) n = size ( p ) dof = m - n niter = 0 step = opt % finite_difference_step_size stop = . false . info % user_requested_stop = . false . nupdate = 0 ! Local Memory Allocation allocate ( pOld ( n ), source = 0.0d0 , stat = flag ) if ( flag == 0 ) allocate ( yOld ( m ), source = 0.0d0 , stat = flag ) if ( flag == 0 ) allocate ( J ( m , n ), stat = flag ) if ( flag == 0 ) allocate ( JtWdy ( n ), stat = flag ) if ( flag == 0 ) allocate ( work ( m + n ), stat = flag ) if ( flag == 0 ) allocate ( mwork ( n , m ), stat = flag ) if ( flag == 0 ) allocate ( pTry ( n ), stat = flag ) if ( flag == 0 ) allocate ( h ( n ), stat = flag ) if ( flag == 0 ) allocate ( yTemp ( m ), stat = flag ) if ( flag == 0 ) allocate ( JtWJc ( n , n ), stat = flag ) if ( flag == 0 ) allocate ( iwork ( n ), stat = flag ) if ( flag /= 0 ) go to 10 ! Perform an initial function evaluation call fun ( xdata , p , y , stop ) neval = 1 ! Evaluate the problem matrices call lm_matrix ( fun , xdata , ydata , pOld , yOld , 1.0d0 , J , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , y , stop , work , mwork ) if ( stop ) go to 5 X2Old = X2 JtWJc = JtWJ ! Determine an initial value for lambda if ( opt % method == FS_LEVENBERG_MARQUARDT_UPDATE ) then lambda = 1.0d-2 else call extract_diagonal ( JtWJ , work ( 1 : n )) lambda = 1.0d-2 * maxval ( work ( 1 : n )) nu = 2.0d0 end if ! Main Loop main : do while ( niter < controls % max_iteration_count ) ! Compute the linear solution at the current solution estimate and ! update the new parameter estimates call lm_iter ( fun , xdata , ydata , p , neval , niter , opt % method , & lambda , maxP , minP , weights , JtWJc , JtWdy , h , pTry , resid , & yTemp , X2Try , X2Old , alpha , stop , iwork , err , status ) if ( stop ) go to 5 if ( err % has_error_occurred ()) return ! Update the Chi-squared estimate, update the damping parameter ! lambda, and, if necessary, update the matrices call lm_update ( fun , xdata , ydata , pOld , p , pTry , yOld , y , h , dX2 , & X2Old , X2 , X2Try , lambda , alpha , nu , JtWdy , JtWJ , J , weights , & niter , neval , update , step , work , mwork , controls , opt , stop ) if ( stop ) go to 5 JtWJc = JtWJ ! Determine the matrix update scheme nupdate = nupdate + 1 if ( opt % method == FS_QUADRATIC_UPDATE ) then update = mod ( niter , 2 * n ) > 0 else if ( nupdate >= controls % max_iteration_between_updates ) then update = . true . nupdate = 0 end if ! Test for convergence if ( lm_check_convergence ( controls , dof , resid , niter , neval , & JtWdy , h , p , X2 , info )) & then exit main end if end do main ! End return ! User Requested End 5 continue info % user_requested_stop = . true . return ! Memory Error Handling 10 continue allocate ( character ( len = 512 ) :: errmsg ) write ( errmsg , 100 ) \"Memory allocation error code \" , flag , \".\" call err % report_error ( \"lm_solve\" , & trim ( errmsg ), FS_MEMORY_ERROR ) return ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ ! subroutine lm_update ( fun , xdata , ydata , pOld , p , pTry , yOld , y , h , dX2 , & X2old , X2 , X2try , lambda , alpha , nu , JtWdy , JtWJ , J , weights , niter , & neval , update , step , work , mwork , controls , opt , stop ) ! Arguments procedure ( regression_function ), intent ( in ), pointer :: fun real ( real64 ), intent ( in ) :: xdata (:), ydata (:), X2try , h (:), step , & pTry (:), weights (:), alpha real ( real64 ), intent ( inout ) :: pOld (:), p (:), yOld (:), y (:), lambda , & JtWdy (:), dX2 , X2 , X2old , JtWJ (:,:), J (:,:), nu real ( real64 ), intent ( out ) :: work (:), mwork (:,:) integer ( int32 ), intent ( in ) :: niter integer ( int32 ), intent ( inout ) :: neval logical , intent ( inout ) :: update class ( iteration_controls ), intent ( in ) :: controls class ( lm_solver_options ), intent ( in ) :: opt logical , intent ( out ) :: stop ! Local Variables integer ( int32 ) :: n real ( real64 ) :: rho ! Initialization n = size ( p ) ! Process if ( opt % method == FS_LEVENBERG_MARQUARDT_UPDATE ) then call extract_diagonal ( JtWJ , work ( 1 : n )) work ( 1 : n ) = lambda * work ( 1 : n ) * h + JtWdy else work ( 1 : n ) = lambda * h + JtWdy end if rho = ( X2 - X2try ) / abs ( dot_product ( h , work ( 1 : n ))) if ( rho > controls % iteration_improvement_tolerance ) then ! Things are getting better at an acceptable rate dX2 = X2 - X2old X2old = X2 pOld = p yOld = y p = pTry ! Recompute the matrices call lm_matrix ( fun , xdata , ydata , pOld , yOld , dX2 , J , p , weights , & neval , update , step , JtWJ , JtWdy , X2 , y , stop , work , mwork ) if ( stop ) return ! Decrease lambda select case ( opt % method ) case ( FS_LEVENBERG_MARQUARDT_UPDATE ) lambda = max ( lambda / opt % damping_decrease_factor , 1.0d-7 ) case ( FS_QUADRATIC_UPDATE ) lambda = max ( lambda / ( 1.0d0 + alpha ), 1.0d-7 ) case ( FS_NIELSEN_UPDATE ) lambda = lambda * max ( 1.0d0 / 3.0d0 , & 1.0d0 - ( 2.0d0 * rho - 1.0d0 ** 3 )) nu = 2.0d0 end select else ! The iteration is not improving in a satisfactory manner X2 = X2old if ( mod ( niter , 2 * n ) /= 0 ) then call lm_matrix ( fun , xdata , ydata , pOld , yOld , - 1.0d0 , J , p , & weights , neval , update , step , JtWJ , JtWdy , dX2 , y , stop , & work , mwork ) if ( stop ) return end if ! Increase lambda select case ( opt % method ) case ( FS_LEVENBERG_MARQUARDT_UPDATE ) lambda = min ( lambda * opt % damping_increase_factor , 1.0d7 ) case ( FS_QUADRATIC_UPDATE ) lambda = lambda + abs (( X2try - X2 ) / 2.0d0 / alpha ) case ( FS_NIELSEN_UPDATE ) lambda = lambda * nu nu = 2.0d0 * nu end select end if end subroutine ! ------------------------------------------------------------------------------ ! Checks the Levenberg-Marquardt solution against the convergence criteria. ! ! Inputs: ! - controls: the solution controls and convergence criteria ! - dof: the statistical degrees of freedom of the system (M - N) ! - resid: the residual error (M-by-1) ! - niter: the number of iterations ! - neval: the number of function evaluations ! - JtWdy: linearized fitting vector (N-by-1) ! - h: the change in parameter (solution) values (N-by-1) ! - p: the parameter (solution) values (N-by-1) ! - X2: the Chi-squared estimate ! ! Outputs: ! - info: The convergence information. ! - rst: True if convergence was achieved; else, false. function lm_check_convergence ( controls , dof , resid , niter , neval , & JtWdy , h , p , X2 , info ) result ( rst ) ! Arguments class ( iteration_controls ), intent ( in ) :: controls real ( real64 ), intent ( in ) :: resid (:), JtWdy (:), h (:), p (:), X2 integer ( int32 ), intent ( in ) :: dof , niter , neval class ( convergence_info ), intent ( out ) :: info logical :: rst ! Initialization rst = . false . ! Iteration Checks info % iteration_count = niter if ( niter >= controls % max_iteration_count ) then info % reach_iteration_limit = . true . rst = . true . else info % reach_iteration_limit = . false . end if info % function_evaluation_count = neval if ( neval >= controls % max_function_evaluations ) then info % reach_function_evaluation_limit = . true . rst = . true . else info % reach_function_evaluation_limit = . false . end if info % gradient_value = maxval ( abs ( JtWdy )) if ( info % gradient_value < controls % gradient_tolerance . and . niter > 2 ) & then info % converge_on_gradient = . true . rst = . true . else info % converge_on_gradient = . false . end if info % solution_change_value = maxval ( abs ( h ) / ( abs ( p ) + 1.0d-12 )) if ( info % solution_change_value < & controls % change_in_solution_tolerance . and . niter > 2 ) & then info % converge_on_solution_change = . true . rst = . true . else info % converge_on_solution_change = . false . end if info % residual_value = X2 / dof if ( info % residual_value < controls % residual_tolerance . and . niter > 2 ) & then info % converge_on_residual_parameter = . true . rst = . true . else info % converge_on_residual_parameter = . false . end if end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_regression.f90.html"},{"title":"fstats_anova.f90 – FSTATS","text":"Source Code module fstats_anova use iso_fortran_env use ieee_arithmetic use fstats_special_functions use fstats_descriptive_statistics use ferror use fstats_errors use fstats_distributions implicit none private public :: anova_factor public :: single_factor_anova_table public :: two_factor_anova_table public :: anova type anova_factor !! Defines an ANOVA factor result. real ( real64 ) :: dof !! The number of degrees of freedome. real ( real64 ) :: variance !! The estimate of variance. real ( real64 ) :: sum_of_squares !! The sum of the squares. real ( real64 ) :: f_statistic !! The F-statistic. real ( real64 ) :: probability !! The variance probability term. end type type single_factor_anova_table !! Defines a single-factor ANOVA results table. type ( anova_factor ) :: main_factor !! The main, or main factor, results. type ( anova_factor ) :: within_factor !! The within-treatement (error) results. real ( real64 ) :: total_dof !! The total number of degrees of freedom. real ( real64 ) :: total_sum_of_squares !! The total sum of squares. real ( real64 ) :: total_variance !! The total variance estimate. real ( real64 ) :: overall_mean !! The overall mean value. end type type two_factor_anova_table !! Defines a two-factor ANOVA results table. type ( anova_factor ) :: main_factor_1 !! The first main-factor results. type ( anova_factor ) :: main_factor_2 !! The second main-factor results. type ( anova_factor ) :: interaction !! The interaction effects. type ( anova_factor ) :: within_factor !! The within (error) factor results. real ( real64 ) :: total_dof !! The total number of degrees of freedom. real ( real64 ) :: total_sum_of_squares !! The total sum of squares. real ( real64 ) :: total_variance !! The total variance estimate. real ( real64 ) :: overall_mean !! The overall mean value. end type interface anova !! Performs an analysis of variance (ANOVA) on the supplied data !! set. !! !! The following example illustrates a single-factor ANOVA on a !! data set. !! ```fortran !! program example !! use iso_fortran_env !! use fstats !! implicit none !! !! ! Local Variables !! character, parameter :: tab = achar(9) !! real(real64) :: x(10, 2) !! type(single_factor_anova_table) :: tbl !! !! ! Define the data !! x = reshape( & !! [ & !! 3.086d3, 3.082d3, 3.069d3, 3.072d3, 3.045d3, 3.070d3, 3.079d3, & !! 3.050d3, 3.062d3, 3.062d3, 3.075d3, 3.061d3, 3.063d3, 3.038d3, & !! 3.070d3, 3.062d3, 3.070d3, 3.049d3, 3.042d3, 3.063d3 & !! ], & !! [10, 2] & !! ) !! !! ! Perform the ANOVA !! tbl = anova(x) !! !! ! Print out the table !! print '(A)', \"Description\" // tab // \"DOF\" // tab // \"Sum of Sq.\" // & !! tab // \"Variance\" // tab // \"F-Stat\" // tab // \"P-Value\" !! print '(AF2.0AF5.1AF5.1AF5.3AF5.3)', \"Main Factor: \" // tab, & !! tbl%main_factor%dof, tab, & !! tbl%main_factor%sum_of_squares, tab // tab, & !! tbl%main_factor%variance, tab // tab, & !! tbl%main_factor%f_statistic, tab, & !! tbl%main_factor%probability !! !! print '(AF3.0AF6.1AF5.1)', \"Within: \" // tab, & !! tbl%within_factor%dof, tab, & !! tbl%within_factor%sum_of_squares, tab // tab, & !! tbl%within_factor%variance !! !! print '(AF3.0AF6.1AF5.1)', \"Total: \" // tab // tab, & !! tbl%total_dof, tab, & !! tbl%total_sum_of_squares, tab // tab, & !! tbl%total_variance !! !! print '(AF6.1)', \"Overall Mean: \", tbl%overall_mean !! end program !! ``` !! The above program produces the following output. !! ```text !! Description DOF Sum of Sq. Variance F-Stat P-Value !! Main Factor: 1. 352.8 352.8 2.147 0.160 !! Within: 18. 2958.2 164.3 !! Total: 19. 3311.0 174.3 !! Overall Mean: 3063.5 !! ``` !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Analysis_of_variance) !! - [SPC Excel Single Factor ANOVA](https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova) !! - [SPC Excel Gage R&R](https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1) !! - [SPC Excel Understanding Regression Statistics](https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1) !! - [NIST - Two Way ANOVA](https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm) module procedure :: anova_1_factor module procedure :: anova_2_factor module procedure :: anova_model_fit end interface contains ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/single-factor-anova function anova_1_factor ( x ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. real ( real64 ), intent ( in ) :: x (:,:) !! An M-by-N matrix containing the M replications of the N test !! points of interest. type ( single_factor_anova_table ) :: rst !! A single_factor_anova_table instance containing the ANOVA results. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 ! Local Variables integer ( int32 ) :: j , a , n , nt real ( real64 ) :: sum_all , tssq , essq , bssq ! Initialization a = size ( x , 2 ) nt = size ( x , 1 ) n = nt * a rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Determine the degrees of freedom rst % main_factor % dof = a - 1 rst % within_factor % dof = n - a rst % total_dof = n - 1 ! Quick Return if ( a == 1 . or . nt == 1 ) then rst % main_factor % sum_of_squares = zero rst % main_factor % variance = zero rst % main_factor % f_statistic = zero rst % main_factor % probability = zero rst % within_factor % sum_of_squares = zero rst % within_factor % variance = zero rst % total_variance = variance ( pack ( x , . true .)) rst % total_sum_of_squares = rst % total_variance * rst % total_dof rst % overall_mean = mean ( pack ( x , . true .)) return end if ! Compute the sum of squares for all factors sum_all = sum ( x ) tssq = sum ( x ** 2 ) - ( sum_all ** 2 / n ) bssq = zero do j = 1 , a bssq = bssq + sum ( x (:, j )) ** 2 end do bssq = ( bssq / nt ) - ( sum_all ** 2 / n ) essq = tssq - bssq rst % main_factor % sum_of_squares = bssq rst % within_factor % sum_of_squares = essq rst % total_sum_of_squares = tssq ! Compute the variance terms rst % main_factor % variance = bssq / rst % main_factor % dof rst % within_factor % variance = essq / rst % within_factor % dof rst % total_variance = tssq / rst % total_dof ! Compute the overall mean rst % overall_mean = mean ( pack ( x , . true .)) ! Compute the F-statistic and probability term call anova_probability ( & rst % main_factor % variance , & rst % within_factor % variance , & rst % main_factor % dof , & rst % within_factor % dof , & rst % main_factor % f_statistic , & rst % main_factor % probability & ) end function ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/measurement-systems-analysis/anova-gage-rr-part-1 ! REF: https://www.itl.nist.gov/div898/handbook/prc/section4/prc427.htm ! Data set is expected as a 3D array with each of the K pages containing the R ! treatments of N tests such that the array size is N-by-R-by-K function anova_2_factor ( x ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. real ( real64 ), intent ( in ) :: x (:,:,:) !! An M-by-N-by-K array containing the M replications of the !! N first factor results, and the K second factor results. type ( two_factor_anova_table ) :: rst !! A two_factor_anova_table instance containing the ANOVA results. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , j , jj , k , r , n real ( real64 ) :: factorMean , sum_all real ( real64 ), allocatable :: xpack (:) ! Initialization n = size ( x , 3 ) k = size ( x , 2 ) r = size ( x , 1 ) rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Quick Return if ( k == 1 ) then ! This is a one-factor anova end if ! Determine the number of DOF rst % main_factor_1 % dof = k - one rst % main_factor_2 % dof = n - 1 rst % interaction % dof = ( k - 1 ) * ( n - 1 ) rst % within_factor % dof = n * k * ( r - 1 ) rst % total_dof = n * k * r - 1 ! Compute the overall mean, sum of squares, and variance xpack = pack ( x , . true .) rst % overall_mean = mean ( xpack ) rst % total_sum_of_squares = sum (( xpack - rst % overall_mean ) ** 2 ) rst % total_variance = rst % total_sum_of_squares / rst % total_dof ! Compute factor 1 results rst % main_factor_1 % sum_of_squares = zero do i = 1 , k factorMean = mean ( pack ( x (:, i ,:), . true .)) rst % main_factor_1 % sum_of_squares = rst % main_factor_1 % sum_of_squares + & ( factorMean - rst % overall_mean ) ** 2 end do rst % main_factor_1 % sum_of_squares = n * r * rst % main_factor_1 % sum_of_squares rst % main_factor_1 % variance = rst % main_factor_1 % sum_of_squares / & rst % main_factor_1 % dof ! Compute factor 2 results rst % main_factor_2 % sum_of_squares = zero do i = 1 , n factorMean = mean ( pack ( x (:,:, i ), . true .)) rst % main_factor_2 % sum_of_squares = rst % main_factor_2 % sum_of_squares + & ( factorMean - rst % overall_mean ) ** 2 end do rst % main_factor_2 % sum_of_squares = k * r * rst % main_factor_2 % sum_of_squares rst % main_factor_2 % variance = rst % main_factor_2 % sum_of_squares / & rst % main_factor_2 % dof ! Compute the within (error) term rst % within_factor % sum_of_squares = zero do j = 1 , k do i = 1 , n factorMean = mean ( x (:, j , i )) do jj = 1 , r rst % within_factor % sum_of_squares = & rst % within_factor % sum_of_squares + & ( x ( jj , j , i ) - factorMean ) ** 2 end do end do end do rst % within_factor % variance = rst % within_factor % sum_of_squares / & rst % within_factor % dof ! Compute the interaction term rst % interaction % sum_of_squares = rst % total_sum_of_squares - ( & rst % main_factor_1 % sum_of_squares + & rst % main_factor_2 % sum_of_squares + & rst % within_factor % sum_of_squares & ) rst % interaction % variance = rst % interaction % sum_of_squares / & rst % interaction % dof ! Compute the F-statistics call anova_probability ( & rst % main_factor_1 % variance , & rst % within_factor % variance , & rst % main_factor_1 % dof , & rst % within_factor % dof , & rst % main_factor_1 % f_statistic , & rst % main_factor_1 % probability & ) call anova_probability ( & rst % main_factor_2 % variance , & rst % within_factor % variance , & rst % main_factor_2 % dof , & rst % within_factor % dof , & rst % main_factor_2 % f_statistic , & rst % main_factor_2 % probability & ) call anova_probability ( & rst % interaction % variance , & rst % within_factor % variance , & rst % interaction % dof , & rst % within_factor % dof , & rst % interaction % f_statistic , & rst % interaction % probability & ) end function ! ------------------------------------------------------------------------------ ! REF: https://www.spcforexcel.com/knowledge/root-cause-analysis/understanding-regression-statistics-part-1 function anova_model_fit ( nmodelparams , ymeas , ymod , err ) result ( rst ) !! Performs an analysis of variance (ANOVA) on the supplied data set. integer ( int32 ), intent ( in ) :: nmodelparams !! The number of model parameters. real ( real64 ), intent ( in ) :: ymeas (:) !! An N-element array containing the measured dependent variable data. real ( real64 ), intent ( in ) :: ymod (:) !! An N-element array containing the modeled dependent variable data. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if ymeas and ymod are not the !! same length. !! - FS_MEMORY_ERROR: Occurs if a memory error is encountered. type ( single_factor_anova_table ) :: rst !! A single_factor_anova_table instance containing the ANOVA results. ! Local Variables integer ( int32 ) :: n , flag real ( real64 ), allocatable :: ypack (:) real ( real64 ) :: sum_all class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization n = size ( ymeas ) if ( present ( err )) then errmgr => err else errmgr => deferr end if rst % within_factor % f_statistic = ieee_value ( sum_all , IEEE_QUIET_NAN ) rst % within_factor % probability = ieee_value ( sum_all , IEEE_QUIET_NAN ) ! Input Checking if ( size ( ymod ) /= n ) then call report_arrays_not_same_size_error ( errmgr , \"anova_model_fit\" , & \"YMEAS\" , \"YMOD\" , n , size ( ymod )) return end if ! Memory Allocation allocate ( ypack ( 2 * n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"anova_model_fit\" , flag ) return end if ! Determine the number of DOF rst % main_factor % dof = nmodelparams - 1 rst % within_factor % dof = n - rst % main_factor % dof - 1 rst % total_dof = n - 1 ! Process ypack ( 1 : n ) = ymeas ypack ( n + 1 : 2 * n ) = ymod rst % overall_mean = mean ( ypack ) rst % total_sum_of_squares = sum (( ymeas - rst % overall_mean ) ** 2 ) rst % main_factor % sum_of_squares = sum (( ymod - rst % overall_mean ) ** 2 ) rst % within_factor % sum_of_squares = sum (( ymeas - ymod ) ** 2 ) rst % total_variance = rst % total_sum_of_squares / rst % total_dof rst % main_factor % variance = rst % main_factor % sum_of_squares / & rst % main_factor % dof rst % within_factor % variance = rst % within_factor % sum_of_squares / & rst % within_factor % dof ! Compute the F-statistic and probability term call anova_probability ( & rst % main_factor % variance , & rst % within_factor % variance , & rst % main_factor % dof , & rst % within_factor % dof , & rst % main_factor % f_statistic , & rst % main_factor % probability & ) ! Formatting 100 format ( A , I0 , A , I0 , A ) 101 format ( A , I0 , A ) end function ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ subroutine anova_probability ( v1 , v2 , dof1 , dof2 , f , p ) ! Arguments real ( real64 ), intent ( in ) :: v1 , v2 , dof1 , dof2 real ( real64 ), intent ( out ) :: f , p ! Local Variables type ( f_distribution ) :: dist ! Process f = v1 / v2 dist % d1 = dof1 dist % d2 = dof2 p = 1.0d0 - dist % cdf ( f ) if ( p > 1.0d0 ) then p = 2.0d0 - p end if end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_anova.f90.html"},{"title":"fstats_descriptive_statistics.f90 – FSTATS","text":"Source Code module fstats_descriptive_statistics use iso_fortran_env use linalg , only : sort use ferror use fstats_errors use fstats_types implicit none private public :: mean public :: variance public :: standard_deviation public :: median public :: quantile public :: trimmed_mean public :: covariance public :: pooled_variance interface pooled_variance !! Computes the pooled estimate of variance. module procedure :: pooled_variance_1 module procedure :: pooled_variance_2 end interface contains ! ------------------------------------------------------------------------------ pure function mean ( x ) result ( rst ) !! Computes the mean of the values in an array. real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 ! Local Variables integer ( int32 ) :: i , n ! Process n = size ( x ) if ( n == 0 ) then rst = zero else rst = x ( 1 ) do i = 2 , n rst = rst + ( x ( i ) - rst ) / i end do end if end function ! ------------------------------------------------------------------------------ pure function variance ( x ) result ( rst ) !! Computes the sample variance of the values in an array. !! !! The variance computed is the sample variance such that !! s^2 = \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right)^2}{n - 1} . real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: oldMean , newMean ! Process n = size ( x ) if ( n <= 1 ) then rst = zero else oldMean = x ( 1 ) rst = zero do i = 2 , n newMean = oldMean + ( x ( i ) - oldMean ) / i rst = rst + ( x ( i ) - oldMean ) * ( x ( i ) - newMean ) oldMean = newMean end do rst = rst / ( n - one ) end if end function ! ------------------------------------------------------------------------------ pure function standard_deviation ( x ) result ( rst ) !! Computes the sample standard deviation of the values in an array. !! !! The value computed is the sample standard deviation. !! s = \\sqrt{ \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right)^2}{n - 1} } real ( real64 ), intent ( in ) :: x (:) !! The array of values to analyze. real ( real64 ) :: rst !! The result. ! Process rst = sqrt ( variance ( x )) end function ! ------------------------------------------------------------------------------ function median ( x ) result ( rst ) !! Computes the median of the values in an array. real ( real64 ), intent ( inout ) :: x (:) !! The array of values to analyze. On output, this array is sorted into !! ascending order. real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: half = 0.5d0 ! Local Variables integer ( int32 ) :: n , nmid , nmidp1 , flag , iflag ! Initialization n = size ( x ) nmid = n / 2 nmidp1 = nmid + 1 iflag = n - 2 * nmid ! Sort the array in ascending order call sort ( x , . true .) ! Find the median if ( iflag == 0 ) then rst = half * ( x ( nmid ) + x ( nmidp1 )) else rst = x ( nmidp1 ) end if end function ! ------------------------------------------------------------------------------ ! REF: https://fortranwiki.org/fortran/show/Quartiles ! ! This is the method used by Minitab pure function quantile ( x , q ) result ( rst ) !! Computes the specified quantile of a data set using the SAS !! Method 4. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Quantile) real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the data. real ( real64 ), intent ( in ) :: q !! The quantile to compute (e.g. 0.25 computes the 25% quantile). real ( real64 ) :: rst !! The result. ! Parameters real ( real64 ), parameter :: one = 1.0d0 ! Local Variables real ( real64 ) :: a , b , c , tol integer ( int32 ) :: n , ib ! Initialization tol = sqrt ( epsilon ( tol )) n = size ( x ) ! Process a = ( n + one ) * q b = mod ( a , one ) c = a - b ib = int ( c , int32 ) if (( ib + 1 ) > n ) then rst = ( one - b ) * x ( ib ) + b * x ( n ) else rst = ( one - b ) * x ( ib ) + b * x ( ib + 1 ) end if end function ! ------------------------------------------------------------------------------ function trimmed_mean ( x , p ) result ( rst ) !! Computes the trimmed mean of a data set. real ( real64 ), intent ( inout ), dimension (:) :: x !! An N-element array containing the data. On output, the !! array is sorted into ascending order. real ( real64 ), intent ( in ), optional :: p !! An optional parameter specifying the percentage of values !! from either end of the distribution to remove. The default !! is 0.05 such that the bottom 5% and top 5% are removed. real ( real64 ) :: rst !! The trimmed mean. ! Local Variables integer ( int32 ) :: i1 , i2 , n real ( real64 ) :: pv ! Initialization if ( present ( p )) then pv = abs ( p ) else pv = 0.05d0 end if ! Sort the array into ascending order call sort ( x , . true .) ! Find the limiting indices n = size ( x ) i1 = max ( floor ( n * pv , int32 ), 1 ) i2 = min ( n , n - i1 + 1 ) rst = mean ( x ( i1 : i2 )) end function ! ------------------------------------------------------------------------------ pure function covariance ( x , y ) result ( rst ) !! Computes the sample covariance of two data sets. !! !! The covariance computed is the sample covariance such that !! q_{jk} = \\frac{\\Sigma \\left( x_{i} - \\bar{x} \\right) !! \\left( y_{i} - \\bar{y} \\right)}{n - 1} . real ( real64 ), intent ( in ), dimension (:) :: x !! The first N-element data set. real ( real64 ), intent ( in ), dimension ( size ( x )) :: y !! The second N-element data set. real ( real64 ) :: rst !! The covariance. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables integer ( int32 ) :: i , n real ( real64 ) :: meanX , meanY ! Process n = size ( x ) if ( n <= 1 ) then rst = zero else ! Compute the means meanX = x ( 1 ) meanY = y ( 1 ) do i = 2 , n meanX = meanX + ( x ( i ) - meanX ) / i meanY = meanY + ( y ( i ) - meanY ) / i end do ! Compute the covariance rst = sum (( x - meanX ) * ( y - meanY )) / ( n - one ) end if end function ! ------------------------------------------------------------------------------ pure function pooled_variance_1 ( si , ni ) result ( rst ) !! Computes the pooled estimate of variance. real ( real64 ), intent ( in ), dimension (:) :: si !! An N-element array containing the estimates for each of the N !! variances. integer ( int32 ), intent ( in ), dimension ( size ( si )) :: ni !! An N-element array containing the number of data points in each !! of the data sets used to compute the variances in si. real ( real64 ) :: rst !! The pooled variance. ! Local Variables integer ( int32 ) :: i , k , n ! Process k = size ( si ) rst = 0.0d0 n = 0 do i = 1 , k n = n + ni ( i ) rst = rst + ( ni ( i ) - 1.0d0 ) * si ( i ) end do rst = rst / real ( n - k , real64 ) end function pure function pooled_variance_2 ( x ) result ( rst ) !! Computes the pooled estimate of variance. type ( array_container ), intent ( in ), dimension (:) :: x !! An array of arrays of data. real ( real64 ) :: rst !! The pooled variance. ! Local Variables integer ( int32 ) :: i , k , n , ni ! Process k = size ( x ) n = 0 rst = 0.0d0 do i = 1 , k ni = size ( x ( i )% x ) n = n + ni rst = rst + variance ( x ( i )% x ) * ( ni - 1.0 ) end do rst = rst / real ( n - k , real64 ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_descriptive_statistics.f90.html"},{"title":"fstats_errors.f90 – FSTATS","text":"Source Code ! A module providing a set of routines to handle errors for the FSTATS library. module fstats_errors use ferror use iso_fortran_env , only : int32 implicit none ! ****************************************************************************** ! ERROR CODES ! ------------------------------------------------------------------------------ integer ( int32 ), parameter :: FS_NO_ERROR = 0 integer ( int32 ), parameter :: FS_ARRAY_SIZE_ERROR = 10000 integer ( int32 ), parameter :: FS_MATRIX_SIZE_ERROR = 10001 integer ( int32 ), parameter :: FS_INVALID_INPUT_ERROR = 10002 integer ( int32 ), parameter :: FS_MEMORY_ERROR = 10003 integer ( int32 ), parameter :: FS_UNDERDEFINED_PROBLEM_ERROR = 10004 integer ( int32 ), parameter :: FS_TOLERANCE_TOO_SMALL_ERROR = 10005 integer ( int32 ), parameter :: FS_TOO_FEW_ITERATION_ERROR = 10006 ! ------------------------------------------------------------------------------ integer ( int32 ), private , parameter :: MESSAGE_SIZE = 1024 contains ! ------------------------------------------------------------------------------ subroutine report_memory_error ( err , fname , code ) !! Reports a memory allocation related error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. integer ( int32 ), intent ( in ) :: code !! The error code returned by the allocation routine. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) & \"A memory allocation error occurred with code \" , code , \".\" call err % report_error ( fname , trim ( msg ), FS_MEMORY_ERROR ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_array_size_error ( err , fname , name , expect , actual ) !! Reports an array size error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name !! The name of the array. integer ( int32 ), intent ( in ) :: expect !! The expected size of the array. integer ( int32 ), intent ( in ) :: actual !! The actual size of the array. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Expected array \" // name // \" to be of length \" , & expect , \", but found it to be of length \" , actual , \".\" call err % report_error ( fname , trim ( msg ), FS_ARRAY_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_matrix_size_error ( err , fname , name , expect_rows , & expect_cols , actual_rows , actual_cols ) !! Reports a matrix size error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name !! The name of the matrix. integer ( int32 ), intent ( in ) :: expect_rows !! The expected number of rows. integer ( int32 ), intent ( in ) :: expect_cols !! The expected number of columns. integer ( int32 ), intent ( in ) :: actual_rows !! The actual number of rows. integer ( int32 ), intent ( in ) :: actual_cols !! The actual number of columns. ! Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Expected matrix \" // name // \" to be of size (\" , & expect_rows , \", \" , expect_cols , \"), but found it to be of size (\" , & actual_rows , \", \" , actual_cols , \").\" call err % report_error ( fname , trim ( msg ), FS_MATRIX_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_arrays_not_same_size_error ( err , fname , name1 , name2 , & size1 , size2 ) !! Reports an error relating to two arrays not being the same size !! when they should be the same size. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. character ( len = * ), intent ( in ) :: name1 !! The name of the first array. character ( len = * ), intent ( in ) :: name2 !! The name of the second array. integer ( int32 ), intent ( in ) :: size1 !! The size of the first array. integer ( int32 ), intent ( in ) :: size2 !! The size of the second array. ! Local Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"Array \" // name1 // \" and array \" // name2 // & \"were expected to be the same size, but instead were found \" // & \"to be sized \" , size1 , \" and \" , size2 , \" respectively.\" call err % report_error ( fname , trim ( msg ), FS_ARRAY_SIZE_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_underdefined_error ( err , fname , expect , actual ) !! Reports an underdefined problem error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ), intent ( in ) :: fname !! The name of the routine in which the error occurred. integer ( int32 ), intent ( in ) :: expect !! The expected minimum number of equations. integer ( int32 ), intent ( in ) :: actual !! The actual number of equations. ! Local Variables character ( len = MESSAGE_SIZE ) :: msg ! Process write ( msg , 100 ) \"The problem is underdefined. The number of \" // & \"equations was found to be \" , actual , & \", but must be at least equal to the number of unknowns \" , & expect , \".\" call err % report_error ( fname , trim ( msg ), FS_UNDERDEFINED_PROBLEM_ERROR ) ! Formatting 100 format ( A , I0 , A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ subroutine report_iteration_count_error ( err , fname , msg , mincount ) !! Reports an iteration count error. class ( errors ), intent ( inout ) :: err !! The error handling object. character ( len = * ) :: fname !! The name of the routine in which the error occurred. character ( len = * ) :: msg !! The error message. integer ( int32 ), intent ( in ) :: mincount !! The minimum iteration count expected. ! Local Variables character ( len = MESSAGE_SIZE ) :: emsg ! Process write ( emsg , 100 ) msg // \" A minimum of \" , mincount , \" is expected.\" call err % report_error ( fname , trim ( emsg ), FS_TOO_FEW_ITERATION_ERROR ) ! Formatting 100 format ( A , I0 , A ) end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_errors.f90.html"},{"title":"fstats_smoothing.f90 – FSTATS","text":"Source Code module fstats_smoothing use iso_fortran_env use ferror use fstats_errors use linalg , only : sort implicit none private public :: lowess contains ! ------------------------------------------------------------------------------ subroutine lowess ( x , y , ys , fsmooth , nstps , del , rweights , resid , err ) !! Computes the smoothing of a data set using a robust locally weighted !! scatterplot smoothing (LOWESS) algorithm. Fitted values are computed at !! each of the supplied x values. !! !! Remarks !! !! The code is a reimplementation of the LOWESS library. For a detailed !! understanding, see [this] !! (http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf) !! paper by William Cleveland. real ( real64 ), intent ( in ), dimension (:) :: x !! An N-element array containing the independent variable data. This !! array must be monotonically increasing. real ( real64 ), intent ( in ), dimension (:) :: y !! An N-element array containing the dependent variable data. real ( real64 ), intent ( out ), dimension (:) :: ys !! An N-element array where the smoothed results will be written. real ( real64 ), intent ( in ), optional :: fsmooth !! An optional input that specifies the amount of smoothing. !! Specifically, this value is the fraction of points used to compute !! each value. As this value increases, the output becomes smoother. !! Choosing a value in the range of 0.2 to 0.8 typically results in a !! good fit. The default value is 0.2. integer ( int32 ), intent ( in ), optional :: nstps !! An optional input that specifies the numb of iterations. If set to !! zero, a non-robust fit is returned. The default value is set to 2. real ( real64 ), intent ( in ), optional :: del !! real ( real64 ), intent ( out ), optional , dimension (:), target :: rweights !! An optional N-element array, that if supplied, will be used to !! return the weights given to each data point. real ( real64 ), intent ( out ), optional , dimension (:), target :: resid !! An optional N-element array, that if supplied, will be used to !! return the residual. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if any of the arrays are not !! approriately sized. !! - FS_MEMORY_ERROR: Occurs if there is a memory allocation error. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: p2 = 2.0d-1 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: three = 3.0d0 real ( real64 ), parameter :: p001 = 1.0d-3 real ( real64 ), parameter :: p999 = 0.999d0 ! Local Variables logical :: ok integer ( int32 ) :: iter , i , j , nleft , nright , ns , last , m1 , m2 , n , nsteps , flag real ( real64 ) :: f , delta , d1 , d2 , denom , alpha , cut , eps , cmad , c1 , c9 , r real ( real64 ), allocatable , target , dimension (:) :: rwdef , rsdef real ( real64 ), pointer , dimension (:) :: rw , res class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n = size ( x ) if ( present ( fsmooth )) then f = fsmooth else f = p2 end if if ( present ( nstps )) then nsteps = nstps else nsteps = 2 end if if ( present ( del )) then delta = del else delta = 0.0d0 end if if ( present ( rweights )) then if ( size ( rweights ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"rweights\" , n , & size ( rweights )) return end if rw => rweights else allocate ( rwdef ( n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"lowess\" , flag ) return end if rw => rwdef end if if ( present ( resid )) then if ( size ( resid ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"resid\" , n , & size ( resid )) return end if res => resid else allocate ( rsdef ( n ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"lowess\" , flag ) return end if res => rsdef end if ns = max ( min ( int ( f * real ( n ), int32 ), n ), 2 ) eps = epsilon ( eps ) ! Input Checking if ( size ( y ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"y\" , n , size ( y )) return end if if ( size ( ys ) /= n ) then call report_array_size_error ( errmgr , \"lowess\" , \"ys\" , n , size ( ys )) return end if ! Quick Return if ( n < 2 ) then ys = y return end if ! Process do iter = 1 , nsteps + 1 nleft = 1 nright = ns last = 0 i = 1 do do while ( nright < n ) d1 = x ( i ) - x ( nleft ) d2 = x ( nright + 1 ) - x ( i ) if ( d1 <= d2 ) exit nleft = nleft + 1 nright = nright + 1 end do call lowest ( x , y , x ( i ), ys ( i ), nleft , nright , res , iter > 1 , & rw , ok ) if (. not . ok ) ys ( i ) = y ( i ) if ( last < i - 1 ) then denom = x ( i ) - x ( last ) do j = last + 1 , i - 1 alpha = ( x ( j ) - x ( last )) / denom ys ( j ) = alpha * ys ( i ) + ( one - alpha ) * ys ( last ) end do end if last = i cut = x ( last ) + delta do i = last + 1 , n if ( x ( i ) > cut ) exit if ( abs ( x ( i ) - x ( last )) < eps ) then ys ( i ) = ys ( last ) last = i end if end do i = max ( last + 1 , i - 1 ) if ( last >= n ) exit end do res = y - ys if ( iter > nsteps ) exit rw = abs ( res ) call sort ( rw , . true .) m1 = 1 + n / 2 m2 = n - m1 + 1 cmad = three * ( rw ( m1 ) + rw ( m2 )) c9 = p999 * cmad c1 = p001 * cmad do i = 1 , n r = abs ( res ( i )) if ( r <= c1 ) then rw ( i ) = one else if ( r > c9 ) then rw ( i ) = zero else rw ( i ) = ( one - ( r / cmad ) ** 2 ) ** 2 end if end do end do end subroutine ! ****************************************************************************** ! PRIVATE ROUTINES ! ------------------------------------------------------------------------------ ! REF: ! - https://en.wikipedia.org/wiki/Local_regression ! - http://www.aliquote.org/cours/2012_biomed/biblio/Cleveland1979.pdf subroutine lowest ( x , y , xs , ys , nleft , nright , w , userw , rw , ok ) ! Arguments real ( real64 ), intent ( in ), dimension (:) :: x , y , rw ! N ELEMENT real ( real64 ), intent ( in ) :: xs real ( real64 ), intent ( out ) :: ys integer ( int32 ), intent ( in ) :: nleft , nright real ( real64 ), intent ( out ), dimension (:) :: w ! N ELEMENT logical , intent ( in ) :: userw logical , intent ( out ) :: ok ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: p001 = 1.0d-3 real ( real64 ), parameter :: p999 = 0.999d0 ! Local Variables integer ( int32 ) :: j , n , nrt real ( real64 ) :: range , h , h9 , h1 , a , b , c , r ! Initialization n = size ( x ) range = x ( n ) - x ( 1 ) h = max ( xs - x ( nleft ), x ( nright ) - xs ) h9 = p999 * h h1 = p001 * h a = zero ! Process do j = nleft , n w ( j ) = zero r = abs ( x ( j ) - xs ) if ( r <= h9 ) then if ( r > h1 ) then w ( j ) = ( one - ( r / h ) ** 3 ) ** 3 else w ( j ) = one end if if ( userw ) w ( j ) = rw ( j ) * w ( j ) a = a + w ( j ) else if ( x ( j ) > xs ) then exit end if end do nrt = j - 1 if ( a <= zero ) then ok = . false . else ok = . true . w ( nleft : nrt ) = w ( nleft : nrt ) / a if ( h > zero ) then a = zero do j = nleft , nrt a = a + w ( j ) * x ( j ) end do b = xs - a c = zero do j = nleft , nrt c = c + w ( j ) * ( x ( j ) - a ) ** 2 end do if ( sqrt ( c ) > p001 * range ) then b = b / c do j = nleft , nrt w ( j ) = w ( j ) * ( one + b * ( x ( j ) - a )) end do end if end if ys = zero do j = nleft , nrt ys = ys + w ( j ) * y ( j ) end do end if end subroutine ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_smoothing.f90.html"},{"title":"fstats_special_functions.f90 – FSTATS","text":"Source Code module fstats_special_functions use iso_fortran_env use ieee_arithmetic implicit none private public :: beta public :: regularized_beta public :: incomplete_beta public :: incomplete_gamma_lower public :: incomplete_gamma_upper public :: digamma contains ! ------------------------------------------------------------------------------ pure elemental function beta ( a , b ) result ( rst ) !! Computes the beta function. !! !! The beta function is related to the gamma function !! by the following relationship. !! \\beta(a,b) = \\frac{\\Gamma(a) \\Gamma(b)}{\\Gamma(a + b)} . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ) :: rst !! The value of the beta function at a and b . ! Process ! REF: https://en.wikipedia.org/wiki/Beta_function rst = exp ( log_gamma ( a ) + log_gamma ( b ) - log_gamma ( a + b )) end function ! ------------------------------------------------------------------------------ ! source: https://people.math.sc.edu/Burkardt/f_src/special_functions/special_functions.f90 pure elemental function regularized_beta ( a , b , x ) result ( rst ) !! Computes the regularized beta function. !! !! The regularized beta function is defined as the ratio between !! the incomplete beta function and the beta function. !! I_{x}(a,b) = \\frac{\\beta(x;a,b)}{\\beta(a,b)} . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ), intent ( in ) :: x !! The upper limit of the integration. real ( real64 ) :: rst !! The value of the regularized beta function. ! Local Variables real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 real ( real64 ) :: bt , dk ( 51 ), fk ( 51 ), s0 , t1 , t2 , ta , tb integer ( int32 ) :: k ! Process s0 = ( a + one ) / ( a + b + two ) bt = beta ( a , b ) if ( x <= s0 ) then do k = 1 , 20 dk ( 2 * k ) = k * ( b - k ) * x / ( a + two * k - one ) / ( a + two * k ) end do do k = 0 , 20 dk ( 2 * k + 1 ) = - ( a + k ) * ( a + b + k ) * x / ( a + two * k ) / & ( a + two * k + one ) end do t1 = zero do k = 20 , 1 , - 1 t1 = dk ( k ) / ( one + t1 ) end do ta = one / ( one + t1 ) rst = x ** a * ( one - x ) ** b / ( a * bt ) * ta else do k = 1 , 20 fk ( 2 * k ) = k * ( a - k ) * ( one - x ) / ( b + two * k - one ) / & ( b + two * k ) end do do k = 0 , 20 fk ( 2 * k + 1 ) = - ( b + k ) * ( a + b + k ) * ( one - x ) / ( b + two * k ) / & ( b + two * k + one ) end do t2 = zero do k = 20 , 1 , - 1 t2 = fk ( k ) / ( one + t2 ) end do tb = one / ( one + t2 ) rst = one - x ** a * ( one - x ) ** b / ( b * bt ) * tb end if end function ! ------------------------------------------------------------------------------ pure elemental function incomplete_beta ( a , b , x ) result ( rst ) !! Computes the incomplete beta function. !! !! The incomplete beta function is defind as: !! \\beta(x;a,b) = \\int_{0}^{x} t^{a-1} (1 - t)^{b-1} dt . !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Beta_function#Incomplete_beta_function) real ( real64 ), intent ( in ) :: a !! The first argument of the function. real ( real64 ), intent ( in ) :: b !! The second argument of the function. real ( real64 ), intent ( in ) :: x !! The upper limit of the integration. real ( real64 ) :: rst !! The value of the incomplete beta function. ! Process rst = beta ( a , b ) * regularized_beta ( a , b , x ) end function ! ------------------------------------------------------------------------------ ! REF: https://people.math.sc.edu/Burkardt/f_src/special_functions/special_functions.f90 pure elemental function incomplete_gamma_upper ( a , x ) result ( rst ) !! Computes the upper incomplete gamma function. !! !! The upper incomplete gamma function is defined as: !! \\Gamma(a, x) = \\int_{x}^{\\infty} t^{a-1} e^{-t} \\,dt !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Incomplete_gamma_function) real ( real64 ), intent ( in ) :: a !! The coefficient value. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: ten = 1.0d1 ! Local Variables real ( real64 ) :: ga , gin , gip , r , s , t0 , xam , small integer ( int32 ) :: k ! Process small = ten * epsilon ( small ) xam = - x + a * log ( x ) if ( xam > 7.0d2 . or . a > 1.7d2 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) return end if if ( x == zero ) then rst = gamma ( a ) else if ( x <= one + a ) then s = one / a r = s do k = 1 , 60 r = r * x / ( a + k ) s = s + r if ( abs ( r / s ) < small ) then exit end if end do gin = exp ( xam ) * s ga = gamma ( a ) gip = gin / ga rst = ga - gin else if ( one + a < x ) then t0 = zero do k = 60 , 1 , - 1 t0 = ( k - a ) / ( one + k / ( x + t0 )) end do rst = exp ( xam ) / ( x + t0 ) end if end function ! ------------------------------------------------------------------------------ pure elemental function incomplete_gamma_lower ( a , x ) result ( rst ) !! Computes the lower incomplete gamma function. !! !! The lower incomplete gamma function is defined as: !! \\gamma(a, x) = \\int_{0}^{x} t^{a-1} e^{-t} \\,dt !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Incomplete_gamma_function) real ( real64 ), intent ( in ) :: a !! The coefficient value. real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: ten = 1.0d1 ! Local Variables real ( real64 ) :: ga , gim , r , s , t0 , xam , small integer ( int32 ) :: k ! Process small = ten * epsilon ( small ) xam = - x + a * log ( x ) if ( xam > 7.0d2 . or . a > 1.7d2 ) then rst = ieee_value ( rst , IEEE_QUIET_NAN ) return end if if ( x == zero ) then rst = 0.0d0 else if ( x <= one + a ) then s = one / a r = s do k = 1 , 60 r = r * x / ( a + k ) s = s + r if ( abs ( r / s ) < small ) then exit end if end do rst = exp ( xam ) * s else if ( one + a < x ) then t0 = zero do k = 60 , 1 , - 1 t0 = ( k - a ) / ( one + k / ( x + t0 )) end do gim = exp ( xam ) / ( x + t0 ) ga = gamma ( a ) rst = ga - gim end if end function ! ------------------------------------------------------------------------------ pure elemental function digamma ( x ) result ( rst ) !! Computes the digamma function. !! !! The digamma function is defined as: !! \\psi(x) = !! \\frac{d}{dx}\\left( \\ln \\left( \\Gamma \\left( x \\right) \\right) !! \\right) !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Digamma_function) real ( real64 ), intent ( in ) :: x !! The value at which to evaluate the function. real ( real64 ) :: rst !! The function value. ! Parameters real ( real64 ), parameter :: c = 8.5d0 real ( real64 ), parameter :: euler_mascheroni = 0.57721566490153286060d0 ! Local Variables real ( real64 ) :: r , x2 , nan ! REF: ! - https://people.sc.fsu.edu/~jburkardt/f_src/asa103/asa103.f90 ! If x <= 0.0 if ( x <= 0.0 ) then nan = ieee_value ( nan , IEEE_QUIET_NAN ) rst = nan return end if ! Approximation for a small argument if ( x <= 1.0d-6 ) then rst = - euler_mascheroni - 1.0d0 / x + 1.6449340668482264365d0 * x return end if ! Process rst = 0.0d0 x2 = x do while ( x2 < c ) rst = rst - 1.0d0 / x2 x2 = x2 + 1.0d0 end do r = 1.0d0 / x2 rst = rst + log ( x2 ) - 0.5d0 * r r = r * r rst = rst & - r * ( 1.0d0 / 1 2.0d0 & - r * ( 1.0d0 / 12 0.0d0 & - r * ( 1.0d0 / 25 2.0d0 & - r * ( 1.0d0 / 24 0.0d0 & - r * ( 1.0d0 / 13 2.0d0 ) & )))) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_special_functions.f90.html"},{"title":"fstats.f90 – FSTATS","text":"Source Code module fstats !! FSTATS is a modern Fortran statistical library containing routines for !! computing basic statistical properties, hypothesis testing, regression, !! special functions, and experimental design. use iso_fortran_env use fstats_special_functions use fstats_descriptive_statistics use fstats_hypothesis use fstats_distributions use fstats_anova use fstats_helper_routines use fstats_regression use fstats_experimental_design use fstats_allan use fstats_bootstrap use fstats_sampling use fstats_smoothing implicit none private public :: distribution public :: distribution_function public :: distribution_property public :: t_distribution public :: normal_distribution public :: f_distribution public :: chi_squared_distribution public :: binomial_distribution public :: mean public :: variance public :: standard_deviation public :: median public :: covariance public :: r_squared public :: adjusted_r_squared public :: correlation public :: quantile public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test public :: anova public :: anova_factor public :: single_factor_anova_table public :: two_factor_anova_table public :: confidence_interval public :: beta public :: regularized_beta public :: incomplete_beta public :: digamma public :: incomplete_gamma_upper public :: incomplete_gamma_lower public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: regression_statistics public :: get_full_factorial_matrix_size public :: full_factorial public :: iteration_controls public :: lm_solver_options public :: convergence_info public :: regression_function public :: iteration_update public :: jacobian public :: nonlinear_least_squares public :: allan_variance public :: trimmed_mean public :: difference public :: factorial public :: bootstrap_resampling_routine public :: bootstrap_statistic_routine public :: random_resample public :: scaled_random_resample public :: bootstrap_statistics public :: bootstrap public :: bootstrap_regression_statistics public :: bootstrap_linear_least_squares public :: bootstrap_nonlinear_least_squares public :: box_muller_sample public :: rejection_sample public :: lowess public :: pooled_variance public :: bartletts_test public :: levenes_test public :: sample_size public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE end module","tags":"","loc":"sourcefile\\fstats.f90.html"},{"title":"fstats_sampling.f90 – FSTATS","text":"Source Code module fstats_sampling use iso_fortran_env use linalg , only : sort use fstats_distributions implicit none private public :: box_muller_sample public :: rejection_sample real ( real64 ), parameter :: pi = 2.0d0 * acos ( 0.0d0 ) real ( real64 ), parameter :: twopi = 2.0d0 * pi real ( real64 ), parameter :: pi_f = 2.0 * acos ( 0.0 ) real ( real64 ), parameter :: twopi_f = 2.0 * pi_f interface box_muller_sample !! Generates random, normally distributed values via the Box-Muller !! transform. module procedure :: box_muller_sample_scalar module procedure :: box_muller_array end interface contains ! ------------------------------------------------------------------------------ function box_muller_sample_scalar ( mu , sigma ) result ( rst ) !! Generates a pair of independent, standard, normally distributed !! random values using the Box-Muller transform. real ( real64 ), intent ( in ) :: mu !! The mean of the distribution. real ( real64 ), intent ( in ) :: sigma !! The standard deviation of the distribution. real ( real64 ) :: rst ( 2 ) !! The pair of random values. ! Parameters complex ( real64 ), parameter :: j = ( 0.0d0 , 1.0d0 ) ! Local Variables real ( real64 ) :: u1 , u2 complex ( real64 ) :: z ! Process call random_number ( u1 ) call random_number ( u2 ) z = sqrt ( - log ( u1 )) * exp ( j * twopi * u2 ) rst = [ real ( z , real64 ), aimag ( z )] end function ! ------------------------------------------------------------------------------ function box_muller_array ( mu , sigma , n ) result ( rst ) !! Generates an array of normally distributed random values sampled !! by the Box-Muller transform. real ( real64 ), intent ( in ) :: mu !! The mean of the distribution. real ( real64 ), intent ( in ) :: sigma !! The standard deviation of the distribution. integer ( int32 ), intent ( in ) :: n !! The number of Box-Muller pairs to generate. real ( real64 ), allocatable , dimension (:) :: rst !! A 2N-element array containing the N Box-Muller pairs. ! Local Variables integer ( int32 ) :: i ! Process if ( n < 1 ) then allocate ( rst ( 0 )) return end if allocate ( rst ( 2 * n )) do i = 1 , n rst ( 2 * i - 1 : 2 * i ) = box_muller_sample ( mu , sigma ) end do end function ! ****************************************************************************** ! REJECTION SAMPLING ! ------------------------------------------------------------------------------ function rejection_sample ( tdist , n , xmin , xmax ) result ( rst ) !! Uses rejection sampling to randomly sample a target distribution. class ( distribution ), intent ( in ) :: tdist !! The distribution to sample integer ( int32 ), intent ( in ) :: n !! The number of samples to make. real ( real64 ), intent ( in ) :: xmin !! The minimum range to explore. real ( real64 ), intent ( in ) :: xmax !! The maximum range to explore. real ( real64 ), allocatable , dimension (:) :: rst !! An N-element array containing the N samples from the !! distribution. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: c_start = 1.01d0 ! Local Variables integer ( int32 ) :: i , j , jmax real ( real64 ) :: u , c , g , f , rng ! Quick Return if ( n < 1 ) then allocate ( rst ( 0 ), source = zero ) end if ! Process i = 0 j = 0 jmax = min ( 1000 * n , huge ( j )) ! Guard against insanity rng = xmax - xmin c = c_start allocate ( rst ( n ), source = zero ) do while ( i <= n ) ! Update the acceptance threshold call random_number ( u ) ! Sample from the proposal distribution call random_number ( g ) g = g * rng + xmin ! Sample the target distribution f = tdist % pdf ( g ) ! Test if ( u <= f / ( c * g )) then i = i + 1 rst ( i ) = g end if ! Update C c = max ( c , f / g ) ! Update the infinite loop guard variable j = j + 1 if ( j == jmax ) exit end do end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_sampling.f90.html"},{"title":"fstats_hypothesis.f90 – FSTATS","text":"Source Code module fstats_hypothesis use iso_fortran_env use ieee_arithmetic use fstats_errors use fstats_special_functions use fstats_distributions use fstats_descriptive_statistics use fstats_types private public :: confidence_interval public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test public :: bartletts_test public :: levenes_test public :: sample_size interface confidence_interval !! Computes the confidence interval for the specified distribution. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Confidence_interval) module procedure :: confidence_interval_scalar module procedure :: confidence_interval_array end interface contains ! ------------------------------------------------------------------------------ pure function confidence_interval_scalar ( dist , alpha , s , n ) result ( rst ) !! Computes the confidence interval for the specified distribution. class ( distribution ), intent ( in ) :: dist !! The distribution object defining the probability distribution !! to establish the confidence level. real ( real64 ), intent ( in ) :: alpha !! The probability value of interest. For instance, use a value of 0.05 !! for a confidence level of 95%. real ( real64 ), intent ( in ) :: s !! The sample standard deviation. integer ( int32 ), intent ( in ) :: n !! The number of samples in the data set. real ( real64 ) :: rst !! The result. ! Local Variables real ( real64 ) :: x ! Process x = 1.0d0 - alpha / 2.0d0 rst = dist % standardized_variable ( x ) rst = rst * s / sqrt ( real ( n , real64 )) end function ! ------------------------------------------------------------------------------ pure function confidence_interval_array ( dist , alpha , x ) result ( rst ) !! Computes the confidence interval for the specified distribution. class ( distribution ), intent ( in ) :: dist !! The distribution object defining the probability distribution !! to establish the confidence level. real ( real64 ), intent ( in ) :: alpha !! The probability value of interest. For instance, use a value of 0.05 !! for a confidence level of 95%. real ( real64 ), intent ( in ) :: x (:) !! An N-element array containing the data to analyze. real ( real64 ) :: rst !! The result. ! Process rst = confidence_interval ( dist , alpha , standard_deviation ( x ), size ( x )) end function ! ------------------------------------------------------------------------------ subroutine t_test_equal_variance ( x1 , x2 , stat , p , dof ) !! Computes the 2-tailed Student's T-Test for two data sets of !! assumed equivalent variances. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables real ( real64 ) :: v1 , v2 , m1 , m2 , sv , a , b , x integer ( int32 ) :: n1 , n2 ! Compute the T-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = n1 + n2 - two sv = (( n1 - one ) * v1 + ( n2 - one ) * v2 ) / dof stat = abs ( m1 - m2 ) / sqrt ( sv * ( one / real ( n1 ) + one / real ( n2 ))) ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine t_test_unequal_variance ( x1 , x2 , stat , p , dof ) !! Computes the 2-tailed Student's T-Test for two data sets of !! assumed non-equivalent variances. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. ! Parameters real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 ! Local Variables real ( real64 ) :: v1 , v2 , m1 , m2 , sv , a , b , x integer ( int32 ) :: n1 , n2 ! Compute the T-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = ( v1 / real ( n1 ) + v2 / real ( n2 )) ** 2 / (( v1 / n1 ) ** 2 / ( n1 - one ) + & ( v2 / n2 ) ** 2 / ( n2 - one )) sv = sqrt ( v1 / n1 + v2 / n2 ) stat = ( m1 - m2 ) / sv ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine t_test_paired ( x1 , x2 , stat , p , dof , err ) !! Computes the 2-tailed Student's T-Test for two paired data sets. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Student%27s_t-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An N-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The Student-'s T-Test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from two underlying populations that !! have the same mean. real ( real64 ), intent ( out ) :: dof !! The degrees of freedom. class ( errors ), intent ( inout ), optional , target :: err !! A mechanism for communicating errors and warnings to the !! caller. Possible warning and error codes are as follows. !! - FS_NO_ERROR: No errors encountered. !! - FS_ARRAY_SIZE_ERROR: Occurs if x1 and x2 are not the same !! length. ! Parameters real ( real64 ), parameter :: zero = 0.0d0 real ( real64 ), parameter :: half = 0.5d0 real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables class ( errors ), pointer :: errmgr type ( errors ), target :: deferr real ( real64 ) :: v1 , v2 , m1 , m2 , sd , cov , a , b , x integer ( int32 ) :: i , n1 , n2 , n ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if n1 = size ( x1 ) n2 = size ( x2 ) n = min ( n1 , n2 ) ! Input Checking if ( n1 /= n2 ) then call report_arrays_not_same_size_error ( errmgr , \"t_test_paired_real64\" , & \"X1\" , \"X2\" , n1 , n2 ) return end if ! Compute the T-statistic m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) dof = real ( n1 ) - one cov = zero do i = 1 , n cov = cov + ( x1 ( i ) - m1 ) * ( x2 ( i ) - m2 ) end do cov = cov / dof sd = sqrt (( v1 + v2 - two * cov ) / n ) stat = ( m1 - m2 ) / sd ! Compute the probability a = half * dof b = half x = dof / ( dof + stat ** 2 ) p = regularized_beta ( a , b , x ) end subroutine ! ------------------------------------------------------------------------------ subroutine f_test ( x1 , x2 , stat , p , dof1 , dof2 ) !! Computes the F-test and returns the probability (two-tailed) that !! the variances of two data sets are not significantly different. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/F-test) real ( real64 ), intent ( in ) :: x1 (:) !! An N-element array containing the first data set. real ( real64 ), intent ( in ) :: x2 (:) !! An M-element array containing the second data set. real ( real64 ), intent ( out ) :: stat !! The F-statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the two samples are likely to !! have come from the two underlying populations that !! have the same variance. real ( real64 ), intent ( out ) :: dof1 !! A measure of the degrees of freedom. real ( real64 ), intent ( out ) :: dof2 !! A measure of the degrees of freedom. ! Parameters real ( real64 ), parameter :: one = 1.0d0 real ( real64 ), parameter :: two = 2.0d0 ! Local Variables integer ( int32 ) :: n1 , n2 real ( real64 ) :: v1 , v2 , m1 , m2 type ( f_distribution ) :: dist ! Compute the F-statistic n1 = size ( x1 ) n2 = size ( x2 ) m1 = mean ( x1 ) m2 = mean ( x2 ) v1 = variance ( x1 ) v2 = variance ( x2 ) if ( v1 > v2 ) then stat = v1 / v2 dof1 = n1 - one dof2 = n2 - one else stat = v2 / v1 dof1 = n2 - one dof2 = n1 - one end if dist % d1 = dof1 dist % d2 = dof2 p = two * ( one - dist % cdf ( stat )) ! 2x because this is a two-tailed estimate if ( p > one ) p = two - p end subroutine ! ------------------------------------------------------------------------------ subroutine bartletts_test ( x , stat , p ) !! Computes Bartlett's test statistic and associated probability. !! !! The statistic is calculated as follows. !! !! \\chi^{2} = \\frac{(N - k) \\ln(S_{p}^{2}) \\sum_{i = 1}^{k} !! \\left(n_{i} - 1 \\right) \\ln(S_{i}^{2})}{1 + !! \\frac{1}{3 \\left( k - 1 \\right)} \\left( \\sum_{i = 1}^{k} !! \\left( \\frac{1}{n_{i} - 1} \\right) - \\frac{1}{N - k} \\right)} !! !! Where N = \\sum_{i = 1}^{k} n_{i} and S_{p}^{2} is the pooled !! variance. !! !! The probability is calculated as the right-tail probability of the !! chi-squared distribution. !! !! Bartlett's test is most relevant for distributions showing strong !! normality. For distributions lacking strong normality, consider !! Levene's test instead. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Bartlett%27s_test) type ( array_container ), intent ( in ), dimension (:) :: x !! The arrays of data to analyze. real ( real64 ), intent ( out ) :: stat !! The Bartlett's test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the variances of each data set are !! equivalent. A low p-value, less than some significance level, !! indicates a non-equivalance of variances. ! Local Variables integer ( int32 ) :: i , n , k , ni real ( real64 ) :: si , sp , numer , denom type ( chi_squared_distribution ) :: dist ! Initialization k = size ( x ) n = 0 do i = 1 , k n = n + size ( x ( i )% x ) end do ! Compute the statistic n = 0 sp = 0.0d0 numer = 0.0d0 denom = 0.0d0 do i = 1 , k ni = size ( x ( i )% x ) n = n + ni si = variance ( x ( i )% x ) sp = sp + ( ni - 1.0d0 ) * si numer = numer + ( ni - 1.0d0 ) * log ( variance ( x ( i )% x )) denom = denom + 1.0d0 / ( ni - 1.0d0 ) end do sp = sp / real ( n - k , real64 ) stat = (( n - k ) * log ( sp ) - numer ) / & ( 1.0d0 + ( 1.0d0 / ( 3.0d0 * k - 3.0d0 )) * & ( denom - 1.0d0 / real ( n - k , real64 ))) ! Compute the p-value dist % dof = k - 1 p = 1.0d0 - dist % cdf ( stat ) end subroutine ! ------------------------------------------------------------------------------ subroutine levenes_test ( x , stat , p , err ) !! Computes Levene's test statistic and associated probability. !! !! The statistic is calculated as follows. !! W = \\frac{N - k}{k - 1} \\frac{ \\sum_{i = 1}^{k} N_{i} \\left( Z_{i.} - !! Z{..} \\right)^{2}}{ \\sum_{i = 1}^{k} \\sum_{j = 1}^{n_{i}} \\left( Z_{ij} - !! Z_{i.} \\right)^{2} } !! !! Where: !! Z_{ij} = |X_{ij} - \\overline{X_{i.}}| !! Z_{i.} = \\frac{1}{n_{i}} \\sum_{j = 1}^{n_{i}} Z_{ij} !! Z_{..} = \\frac{1}{N} \\sum_{i = 1}^{k} \\sum_{j = 1}^{n_{i}} Z_{ij} !! !! As the test statistic is approximately F-distributed, the F-distribution !! is used to calculate the probability term. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Levene%27s_test) type ( array_container ), intent ( in ), dimension (:) :: x !! The arrays of data to analyze. real ( real64 ), intent ( out ) :: stat !! The Bartlett's test statistic. real ( real64 ), intent ( out ) :: p !! The probability value that the variances of each data set are !! equivalent. A low p-value, less than some significance level, !! indicates a non-equivalance of variances. class ( errors ), intent ( inout ), optional , target :: err ! Local Variables integer ( int32 ) :: i , j , k , n , ni , flag real ( real64 ) :: numer , denom , inner , yi , z , zij real ( real64 ), allocatable , dimension (:) :: y , zt , zi type ( f_distribution ) :: dist class ( errors ), pointer :: errmgr type ( errors ), target :: deferr ! Initialization if ( present ( err )) then errmgr => err else errmgr => deferr end if k = size ( x ) ! Local Memory Allocations allocate ( y ( k ), zi ( k ), stat = flag ) if ( flag /= 0 ) then call report_memory_error ( errmgr , \"levenes_test\" , flag ) return end if ! Compute the total mean z = 0.0d0 n = 0 do i = 1 , k ni = size ( x ( i )% x ) n = n + ni y ( i ) = mean ( x ( i )% x ) zt = abs ( x ( i )% x - y ( i )) zi ( i ) = mean ( zt ) z = z + zi ( i ) * ni end do z = z / n ! Process numer = 0.0d0 denom = 0.0d0 do i = 1 , k ni = size ( x ( i )% x ) yi = y ( i ) numer = numer + ni * ( zi ( i ) - z ) ** 2 inner = 0.0d0 do j = 1 , ni zij = abs ( x ( i )% x ( j ) - yi ) inner = inner + ( zij - zi ( i )) ** 2 end do denom = denom + inner end do stat = real (( N - k ) / ( k - 1 ), real64 ) * ( numer / denom ) dist % d1 = k - 1.0d0 dist % d2 = real ( n - k , real64 ) p = 1.0d0 - dist % cdf ( stat ) end subroutine ! ------------------------------------------------------------------------------ pure function sample_size ( dist , var , delta , bet , alpha ) result ( rst ) !! Estimates the sample size required to achieve an experiment with the !! desired power and significance levels to ascertain the desired !! difference in parameter. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Power_of_a_test) class ( distribution ), intent ( in ) :: dist !! The distribution to utilize as a measure. real ( real64 ), intent ( in ) :: var !! An estimate of the population variance. real ( real64 ), intent ( in ) :: delta !! The parameter difference that is desired. real ( real64 ), intent ( in ), optional :: bet !! The desired power level. The default for this value is 0.2, for a !! power of 80%. real ( real64 ), intent ( in ), optional :: alpha !! The desired significance level. The default for this value is 0.05 !! for a confidence level of 95%. real ( real64 ) :: rst !! The minimum sample size requried to achieve the desired experimental !! outcome. ! Local Variables real ( real64 ) :: a , b , za , zb ! Initialization if ( present ( bet )) then b = bet else b = 0.8d0 end if if ( present ( alpha )) then a = alpha else a = 0.05d0 end if za = dist % standardized_variable ( 1.0d0 - a / 2.0d0 ) zb = dist % standardized_variable ( b ) rst = 2.0d0 * ( za + zb ) ** 2 * var / ( delta ** 2 ) end function ! ------------------------------------------------------------------------------ end module","tags":"","loc":"sourcefile\\fstats_hypothesis.f90.html"}]} \ No newline at end of file diff --git a/doc/type/anova_factor.html b/doc/type/anova_factor.html index 57efa3f..14033bb 100644 --- a/doc/type/anova_factor.html +++ b/doc/type/anova_factor.html @@ -74,7 +74,7 @@

            anova_factor
          • 7 statements + title="

            4.8% of total for derived types.

            Including implementation: 7 statements, 1.4% of total for derived types.">7 statements
          • @@ -114,7 +114,7 @@

            Variables

            - dof + dof f_statistic probability sum_of_squares @@ -167,7 +167,7 @@

            Components

            - + real(kind=real64), public @@ -275,7 +275,7 @@

            Components

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/array_container.html b/doc/type/array_container.html new file mode 100644 index 0000000..c7bac65 --- /dev/null +++ b/doc/type/array_container.html @@ -0,0 +1,236 @@ + + + + + + + + + + + + + array_container – FSTATS + + + + + + + + + + + + + + +
            + +
            + +
            +
            +

            array_container + Derived Type + +

            +
            +
            +
            + +
            +
            + +
            +
            +
            + + +
            + +
            + + +
            +

            + type, public :: array_container

            +

            Provides a container for a real-valued array. A practical use of +this construct is in the construction of jagged arrays.

            +
            + +
            +

            Components

            + + + + + + + + + + + + + + + + + + + + + +
            TypeVisibility AttributesNameInitial
            + + real(kind=real64), + public, + allocatable, dimension(:) + ::x +

            The array.

            +
            + +
            +
            + + + + + +
            +
            + +
            +
            +
            +
            +
            +

            FSTATS was developed by Jason Christopherson
            © 2024 +

            +
            +
            +

            + Documentation generated by + FORD + on 2024-04-19 07:47

            +
            +
            +
            +
            +
            + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/type/binomial_distribution.html b/doc/type/binomial_distribution.html index 6eff008..710d93d 100644 --- a/doc/type/binomial_distribution.html +++ b/doc/type/binomial_distribution.html @@ -74,7 +74,7 @@

            binomial_distribution
          • 11 statements + title="

            7.6% of total for derived types.

            Including implementation: 66 statements, 13.7% of total for derived types.">11 statements
          • @@ -114,8 +114,8 @@

            Variables

            - n - p + n + p
            @@ -147,6 +147,7 @@

            Type-Bound Procedures

            median mode pdf + standardized_variable variance @@ -181,7 +182,7 @@

            Components

            - + integer(kind=int32), public @@ -198,7 +199,7 @@

            Components

            - + real(kind=real64), public @@ -557,6 +558,83 @@

            + +

            + procedure, public :: + standardized_variable => dist_std_var + +

            +
            +
            + +

            Computes the standardized variable for the distribution.

            +
            +
              +
            • +

              + private pure elemental function dist_std_var(this, x) result(rst) +

              + +

              Computes the standardized variable for the distribution.

              + +

              Arguments

              + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              TypeIntentOptional AttributesName
              + + class(distribution), + intent(in) + + ::this +

              The distribution object.

              +
              + + real(kind=real64), + intent(in) + + ::x +

              The value of interest.

              +
              + +

              + Return Value + real(kind=real64) +

              +

              The result.

              + +
            • +
            +
            + +
            +
            +
            +

            procedure, public :: @@ -630,7 +708,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/bootstrap_regression_statistics.html b/doc/type/bootstrap_regression_statistics.html index e514984..8cb9050 100644 --- a/doc/type/bootstrap_regression_statistics.html +++ b/doc/type/bootstrap_regression_statistics.html @@ -74,7 +74,7 @@

            bootstrap_regression_statistics
          • 7 statements + title="

            4.8% of total for derived types.

            Including implementation: 7 statements, 1.4% of total for derived types.">7 statements
          • @@ -287,7 +287,7 @@

            Components

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


          • diff --git a/doc/type/bootstrap_statistics.html b/doc/type/bootstrap_statistics.html index 96e7c99..976ed96 100644 --- a/doc/type/bootstrap_statistics.html +++ b/doc/type/bootstrap_statistics.html @@ -74,7 +74,7 @@

            bootstrap_statistics
          • 8 statements + title="

            5.5% of total for derived types.

            Including implementation: 8 statements, 1.7% of total for derived types.">8 statements
          • @@ -294,7 +294,7 @@

            Components

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/chi_squared_distribution.html b/doc/type/chi_squared_distribution.html index 69f4f34..b86f46c 100644 --- a/doc/type/chi_squared_distribution.html +++ b/doc/type/chi_squared_distribution.html @@ -74,7 +74,7 @@

            chi_squared_distribution
          • 10 statements + title="

            6.9% of total for derived types.

            Including implementation: 65 statements, 13.5% of total for derived types.">10 statements
          • @@ -146,6 +146,7 @@

            Type-Bound Procedures

            median mode pdf + standardized_variable variance @@ -533,6 +534,83 @@

            + +

            + procedure, public :: + standardized_variable => dist_std_var + +

            +
            +
            + +

            Computes the standardized variable for the distribution.

            +
            +
              +
            • +

              + private pure elemental function dist_std_var(this, x) result(rst) +

              + +

              Computes the standardized variable for the distribution.

              + +

              Arguments

              + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              TypeIntentOptional AttributesName
              + + class(distribution), + intent(in) + + ::this +

              The distribution object.

              +
              + + real(kind=real64), + intent(in) + + ::x +

              The value of interest.

              +
              + +

              + Return Value + real(kind=real64) +

              +

              The result.

              + +
            • +
            +
            + +
            +
            +
            +

            procedure, public :: @@ -606,7 +684,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/convergence_info.html b/doc/type/convergence_info.html index 675034b..5c45017 100644 --- a/doc/type/convergence_info.html +++ b/doc/type/convergence_info.html @@ -74,7 +74,7 @@

            convergence_info
          • 13 statements + title="

            9.0% of total for derived types.

            Including implementation: 13 statements, 2.7% of total for derived types.">13 statements
          • @@ -387,7 +387,7 @@

            Components

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


          • diff --git a/doc/type/distribution.html b/doc/type/distribution.html index 7d65bc2..a0a63d2 100644 --- a/doc/type/distribution.html +++ b/doc/type/distribution.html @@ -74,7 +74,7 @@

            distribution
          • 9 statements + title="

            6.9% of total for derived types.

            Including implementation: 29 statements, 6.0% of total for derived types.">10 statements
          • @@ -135,6 +135,7 @@

            Type-Bound Procedures

            median mode pdf + standardized_variable variance @@ -502,6 +503,83 @@

            + +

            + procedure, public :: + standardized_variable => dist_std_var + +

            +
            +
            + +

            Computes the standardized variable for the distribution.

            +
            +
              +
            • +

              + private pure elemental function dist_std_var(this, x) result(rst) +

              + +

              Computes the standardized variable for the distribution.

              + +

              Arguments

              + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              TypeIntentOptional AttributesName
              + + class(distribution), + intent(in) + + ::this +

              The distribution object.

              +
              + + real(kind=real64), + intent(in) + + ::x +

              The value of interest.

              +
              + +

              + Return Value + real(kind=real64) +

              +

              The result.

              + +
            • +
            +
            + +
            +
            +
            +

            procedure(distribution_property), public, deferred, pass :: @@ -579,7 +657,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/f_distribution.html b/doc/type/f_distribution.html index 0b11120..779350a 100644 --- a/doc/type/f_distribution.html +++ b/doc/type/f_distribution.html @@ -74,7 +74,7 @@

            f_distribution
          • 11 statements + title="

            7.6% of total for derived types.

            Including implementation: 83 statements, 17.2% of total for derived types.">11 statements
          • @@ -147,6 +147,7 @@

            Type-Bound Procedures

            median mode pdf + standardized_variable variance
          • @@ -552,6 +553,83 @@

            + +

            + procedure, public :: + standardized_variable => dist_std_var + +

            +
            +
            + +

            Computes the standardized variable for the distribution.

            +
            +
              +
            • +

              + private pure elemental function dist_std_var(this, x) result(rst) +

              + +

              Computes the standardized variable for the distribution.

              + +

              Arguments

              + + + + + + + + + + + + + + + + + + + + + + + + + + + +
              TypeIntentOptional AttributesName
              + + class(distribution), + intent(in) + + ::this +

              The distribution object.

              +
              + + real(kind=real64), + intent(in) + + ::x +

              The value of interest.

              +
              + +

              + Return Value + real(kind=real64) +

              +

              The result.

              + +
            • +
            +
            + +
            +
            +
            +

            procedure, public :: @@ -625,7 +703,7 @@

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/iteration_controls.html b/doc/type/iteration_controls.html index 4713090..ac2cc13 100644 --- a/doc/type/iteration_controls.html +++ b/doc/type/iteration_controls.html @@ -74,7 +74,7 @@

            iteration_controls
          • 11 statements + title="

            7.6% of total for derived types.

            Including implementation: 21 statements, 4.3% of total for derived types.">11 statements
          • @@ -381,7 +381,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


          • diff --git a/doc/type/lm_solver_options.html b/doc/type/lm_solver_options.html index 84b0d09..e9f13ab 100644 --- a/doc/type/lm_solver_options.html +++ b/doc/type/lm_solver_options.html @@ -74,7 +74,7 @@

            lm_solver_options
          • 8 statements + title="

            5.5% of total for derived types.

            Including implementation: 15 statements, 3.1% of total for derived types.">8 statements
          • @@ -328,7 +328,7 @@

            Arguments

            Documentation generated by FORD - on 2024-03-26 07:52

            + on 2024-04-19 07:47


            diff --git a/doc/type/normal_distribution.html b/doc/type/normal_distribution.html index 677cfbe..4c510ac 100644 --- a/doc/type/normal_distribution.html +++ b/doc/type/normal_distribution.html @@ -74,7 +74,7 @@

            normal_distribution
          • 12 statements + title="

            8.3% of total for derived types.

            Including implementation: 68 statements, 14.1% of total for derived types.">12 statements
          • @@ -148,6 +148,7 @@

            Type-Bound Procedures

            mode pdf standardize + standardized_variable variance @@ -598,6 +599,83 @@

            Arguments

            +
          • +

          + + + +
          +
          +
          + +

          + procedure, public :: + standardized_variable => dist_std_var + +

          +
          +
          + +

          Computes the standardized variable for the distribution.

          +
          +
            +
          • +

            + private pure elemental function dist_std_var(this, x) result(rst) +

            + +

            Computes the standardized variable for the distribution.

            + +

            Arguments

            + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            TypeIntentOptional AttributesName
            + + class(distribution), + intent(in) + + ::this +

            The distribution object.

            +
            + + real(kind=real64), + intent(in) + + ::x +

            The value of interest.

            +
            + +

            + Return Value + real(kind=real64) +

            +

            The result.

            +
          @@ -679,7 +757,7 @@

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/type/regression_statistics.html b/doc/type/regression_statistics.html index f3915e6..8ee68b1 100644 --- a/doc/type/regression_statistics.html +++ b/doc/type/regression_statistics.html @@ -74,7 +74,7 @@

          regression_statistics
        • 6 statements + title="

          4.1% of total for derived types.

          Including implementation: 6 statements, 1.2% of total for derived types.">6 statements
        • @@ -275,7 +275,7 @@

          Components

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/type/single_factor_anova_table.html b/doc/type/single_factor_anova_table.html index 0502a6e..fb6c673 100644 --- a/doc/type/single_factor_anova_table.html +++ b/doc/type/single_factor_anova_table.html @@ -74,7 +74,7 @@

          single_factor_anova_table
        • 8 statements + title="

          5.5% of total for derived types.

          Including implementation: 8 statements, 1.7% of total for derived types.">8 statements
        • @@ -293,7 +293,7 @@

          Components

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/type/t_distribution.html b/doc/type/t_distribution.html index a5e7670..7f3170b 100644 --- a/doc/type/t_distribution.html +++ b/doc/type/t_distribution.html @@ -74,7 +74,7 @@

          t_distribution
        • 10 statements + title="

          6.9% of total for derived types.

          Including implementation: 74 statements, 15.3% of total for derived types.">10 statements
        • @@ -146,6 +146,7 @@

          Type-Bound Procedures

          median mode pdf + standardized_variable variance @@ -535,6 +536,83 @@

          + +

          + procedure, public :: + standardized_variable => dist_std_var + +

          +
          +
          + +

          Computes the standardized variable for the distribution.

          +
          +
            +
          • +

            + private pure elemental function dist_std_var(this, x) result(rst) +

            + +

            Computes the standardized variable for the distribution.

            + +

            Arguments

            + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            TypeIntentOptional AttributesName
            + + class(distribution), + intent(in) + + ::this +

            The distribution object.

            +
            + + real(kind=real64), + intent(in) + + ::x +

            The value of interest.

            +
            + +

            + Return Value + real(kind=real64) +

            +

            The result.

            + +
          • +
          +
          + +
          +
          +
          +

          procedure, public :: @@ -608,7 +686,7 @@

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


          diff --git a/doc/type/two_factor_anova_table.html b/doc/type/two_factor_anova_table.html index 378cbfd..694eb40 100644 --- a/doc/type/two_factor_anova_table.html +++ b/doc/type/two_factor_anova_table.html @@ -74,7 +74,7 @@

          two_factor_anova_table
        • 10 statements + title="

          6.9% of total for derived types.

          Including implementation: 10 statements, 2.1% of total for derived types.">10 statements
        • @@ -329,7 +329,7 @@

          Components

          Documentation generated by FORD - on 2024-03-26 07:52

          + on 2024-04-19 07:47


        • diff --git a/fpm.toml b/fpm.toml index c7024c1..6a2ef00 100644 --- a/fpm.toml +++ b/fpm.toml @@ -1,5 +1,5 @@ name = "fstats" -version = "1.2.1" +version = "1.2.2" license = "GPL-3.0" author = "Jason Christopherson" maintainer = "Jason Christopherson" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 81c888c..005b39e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,5 +17,6 @@ set(FSTATS_SOURCES ${dir}/fstats_bootstrap.f90 ${dir}/fstats_sampling.f90 ${dir}/fstats_smoothing.f90 + ${dir}/fstats_types.f90 ) set(FSTATS_SOURCES ${FSTATS_SOURCES} PARENT_SCOPE) diff --git a/src/fstats.f90 b/src/fstats.f90 index 17ddec2..7eb1e80 100644 --- a/src/fstats.f90 +++ b/src/fstats.f90 @@ -49,7 +49,7 @@ module fstats public :: digamma public :: incomplete_gamma_upper public :: incomplete_gamma_lower - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: regression_statistics @@ -78,6 +78,10 @@ module fstats public :: box_muller_sample public :: rejection_sample public :: lowess + public :: pooled_variance + public :: bartletts_test + public :: levenes_test + public :: sample_size public :: FS_LEVENBERG_MARQUARDT_UPDATE public :: FS_QUADRATIC_UPDATE public :: FS_NIELSEN_UPDATE diff --git a/src/fstats_anova.f90 b/src/fstats_anova.f90 index 51ed9a6..fffddb7 100644 --- a/src/fstats_anova.f90 +++ b/src/fstats_anova.f90 @@ -5,6 +5,7 @@ module fstats_anova use fstats_descriptive_statistics use ferror use fstats_errors + use fstats_distributions implicit none private public :: anova_factor @@ -427,18 +428,13 @@ subroutine anova_probability(v1, v2, dof1, dof2, f, p) real(real64), intent(out) :: f, p ! Local Variables - real(real64) :: d1, d2, a, b, x + type(f_distribution) :: dist ! Process f = v1 / v2 - d1 = dof1 - d2 = dof2 - - a = 0.5d0 * d2 - b = 0.5d0 * d1 - x = d2 / (d2 + d1 * f) - - p = regularized_beta(a, b, x) + dist%d1 = dof1 + dist%d2 = dof2 + p = 1.0d0 - dist%cdf(f) if (p > 1.0d0) then p = 2.0d0 - p end if diff --git a/src/fstats_descriptive_statistics.f90 b/src/fstats_descriptive_statistics.f90 index b6a376e..591904a 100644 --- a/src/fstats_descriptive_statistics.f90 +++ b/src/fstats_descriptive_statistics.f90 @@ -3,6 +3,7 @@ module fstats_descriptive_statistics use linalg, only : sort use ferror use fstats_errors + use fstats_types implicit none private public :: mean @@ -12,7 +13,13 @@ module fstats_descriptive_statistics public :: quantile public :: trimmed_mean public :: covariance + public :: pooled_variance + interface pooled_variance + !! Computes the pooled estimate of variance. + module procedure :: pooled_variance_1 + module procedure :: pooled_variance_2 + end interface contains ! ------------------------------------------------------------------------------ pure function mean(x) result(rst) @@ -237,5 +244,53 @@ pure function covariance(x, y) result(rst) end if end function +! ------------------------------------------------------------------------------ +pure function pooled_variance_1(si, ni) result(rst) + !! Computes the pooled estimate of variance. + real(real64), intent(in), dimension(:) :: si + !! An N-element array containing the estimates for each of the N + !! variances. + integer(int32), intent(in), dimension(size(si)) :: ni + !! An N-element array containing the number of data points in each + !! of the data sets used to compute the variances in si. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n + + ! Process + k = size(si) + rst = 0.0d0 + n = 0 + do i = 1, k + n = n + ni(i) + rst = rst + (ni(i) - 1.0d0) * si(i) + end do + rst = rst / real(n - k, real64) +end function + +pure function pooled_variance_2(x) result(rst) + !! Computes the pooled estimate of variance. + type(array_container), intent(in), dimension(:) :: x + !! An array of arrays of data. + real(real64) :: rst + !! The pooled variance. + + ! Local Variables + integer(int32) :: i, k, n, ni + + ! Process + k = size(x) + n = 0 + rst = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + rst = rst + variance(x(i)%x) * (ni - 1.0) + end do + rst = rst / real(n - k, real64) +end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/src/fstats_distributions.f90 b/src/fstats_distributions.f90 index bc30726..559afa0 100644 --- a/src/fstats_distributions.f90 +++ b/src/fstats_distributions.f90 @@ -31,6 +31,8 @@ module fstats_distributions !! Computes the mode of the distribution. procedure(distribution_property), deferred, pass :: variance !! Computes the variance of the distribution. + procedure, public :: standardized_variable => dist_std_var + !! Computes the standardized variable for the distribution. end type interface @@ -135,8 +137,40 @@ pure function distribution_property(this) result(rst) procedure, public :: variance => bd_variance end type -! ------------------------------------------------------------------------------ contains +! ------------------------------------------------------------------------------ +pure elemental function dist_std_var(this, x) result(rst) + !! Computes the standardized variable for the distribution. + class(distribution), intent(in) :: this + !! The distribution object. + real(real64), intent(in) :: x + !! The value of interest. + real(real64) :: rst + !! The result. + + ! Local Variables + integer(int32), parameter :: maxiter = 100 + real(real64), parameter :: tol = 1.0d-6 + integer(int32) :: i + real(real64) :: f, df, h, twoh, dy + + ! Process + ! + ! We use a simplified Newton's method to solve for the independent variable + ! of the CDF function + h = 1.0d-6 + twoh = 2.0d0 * h + rst = 0.5d0 ! just an initial guess + do i = 1, maxiter + ! Compute the CDF and its derivative at y + f = this%cdf(rst) - x + df = (this%cdf(rst + h) - this%cdf(rst - h)) / twoh + dy = f / df + rst = rst - dy + if (abs(dy) < tol) exit + end do +end function + ! ****************************************************************************** ! STUDENT'S T-DISTRIBUTION ! ------------------------------------------------------------------------------ diff --git a/src/fstats_hypothesis.f90 b/src/fstats_hypothesis.f90 index d6eb068..98cabf7 100644 --- a/src/fstats_hypothesis.f90 +++ b/src/fstats_hypothesis.f90 @@ -5,12 +5,16 @@ module fstats_hypothesis use fstats_special_functions use fstats_distributions use fstats_descriptive_statistics + use fstats_types private public :: confidence_interval public :: t_test_equal_variance public :: t_test_unequal_variance public :: t_test_paired public :: f_test + public :: bartletts_test + public :: levenes_test + public :: sample_size interface confidence_interval !! Computes the confidence interval for the specified distribution. @@ -39,29 +43,11 @@ pure function confidence_interval_scalar(dist, alpha, s, n) result(rst) !! The result. ! Local Variables - integer(int32), parameter :: maxiter = 100 - real(real64), parameter :: tol = 1.0d-6 - integer(int32) :: i - real(real64) :: x, f, df, h, twoh, dy + real(real64) :: x ! Process - ! - ! We use a simplified Newton's method to solve for the independent variable - ! of the CDF function where it equals 1 - alpha / 2. - h = 1.0d-6 - twoh = 2.0d0 * h x = 1.0d0 - alpha / 2.0d0 - rst = 0.5d0 - do i = 1, maxiter - ! Compute the CDF and its derivative at y - f = dist%cdf(rst) - x - df = (dist%cdf(rst + h) - dist%cdf(rst - h)) / twoh - dy = f / df - rst = rst - dy - if (abs(dy) < tol) exit - end do - - ! Determine the actual interval + rst = dist%standardized_variable(x) rst = rst * s / sqrt(real(n, real64)) end function @@ -279,13 +265,13 @@ subroutine f_test(x1, x2, stat, p, dof1, dof2) !! A measure of the degrees of freedom. ! Parameters - real(real64), parameter :: half = 0.5d0 real(real64), parameter :: one = 1.0d0 real(real64), parameter :: two = 2.0d0 ! Local Variables integer(int32) :: n1, n2 - real(real64) :: v1, v2, m1, m2, a, b, x + real(real64) :: v1, v2, m1, m2 + type(f_distribution) :: dist ! Compute the F-statistic n1 = size(x1) @@ -304,13 +290,211 @@ subroutine f_test(x1, x2, stat, p, dof1, dof2) dof2 = n1 - one end if - ! Compute the probability - a = half * dof2 - b = half * dof1 - x = dof2 / (dof2 + dof1 * stat) - p = two * regularized_beta(a, b, x) + dist%d1 = dof1 + dist%d2 = dof2 + p = two * (one - dist%cdf(stat))! 2x because this is a two-tailed estimate if (p > one) p = two - p end subroutine +! ------------------------------------------------------------------------------ +subroutine bartletts_test(x, stat, p) + !! Computes Bartlett's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! + !! $$ \chi^{2} = \frac{(N - k) \ln(S_{p}^{2}) \sum_{i = 1}^{k} + !! \left(n_{i} - 1 \right) \ln(S_{i}^{2})}{1 + + !! \frac{1}{3 \left( k - 1 \right)} \left( \sum_{i = 1}^{k} + !! \left( \frac{1}{n_{i} - 1} \right) - \frac{1}{N - k} \right)} $$ + !! + !! Where \( N = \sum_{i = 1}^{k} n_{i} \) and \( S_{p}^{2} \) is the pooled + !! variance. + !! + !! The probability is calculated as the right-tail probability of the + !! chi-squared distribution. + !! + !! Bartlett's test is most relevant for distributions showing strong + !! normality. For distributions lacking strong normality, consider + !! Levene's test instead. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Bartlett%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + + ! Local Variables + integer(int32) :: i, n, k, ni + real(real64) :: si, sp, numer, denom + type(chi_squared_distribution) :: dist + + ! Initialization + k = size(x) + n = 0 + do i = 1, k + n = n + size(x(i)%x) + end do + + ! Compute the statistic + n = 0 + sp = 0.0d0 + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + si = variance(x(i)%x) + sp = sp + (ni - 1.0d0) * si + numer = numer + (ni - 1.0d0) * log(variance(x(i)%x)) + denom = denom + 1.0d0 / (ni - 1.0d0) + end do + sp = sp / real(n - k, real64) + stat = ((n - k) * log(sp) - numer) / & + (1.0d0 + (1.0d0 / (3.0d0 * k - 3.0d0)) * & + (denom - 1.0d0 / real(n - k, real64))) + + ! Compute the p-value + dist%dof = k - 1 + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +subroutine levenes_test(x, stat, p, err) + !! Computes Levene's test statistic and associated probability. + !! + !! The statistic is calculated as follows. + !! $$ W = \frac{N - k}{k - 1} \frac{ \sum_{i = 1}^{k} N_{i} \left( Z_{i.} - + !! Z{..} \right)^{2}}{ \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} \left( Z_{ij} - + !! Z_{i.} \right)^{2} } $$ + !! + !! Where: + !! $$ Z_{ij} = |X_{ij} - \overline{X_{i.}}| $$ + !! $$ Z_{i.} = \frac{1}{n_{i}} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! $$ Z_{..} = \frac{1}{N} \sum_{i = 1}^{k} \sum_{j = 1}^{n_{i}} Z_{ij} $$ + !! + !! As the test statistic is approximately F-distributed, the F-distribution + !! is used to calculate the probability term. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Levene%27s_test) + type(array_container), intent(in), dimension(:) :: x + !! The arrays of data to analyze. + real(real64), intent(out) :: stat + !! The Bartlett's test statistic. + real(real64), intent(out) :: p + !! The probability value that the variances of each data set are + !! equivalent. A low p-value, less than some significance level, + !! indicates a non-equivalance of variances. + class(errors), intent(inout), optional, target :: err + + ! Local Variables + integer(int32) :: i, j, k, n, ni, flag + real(real64) :: numer, denom, inner, yi, z, zij + real(real64), allocatable, dimension(:) :: y, zt, zi + type(f_distribution) :: dist + class(errors), pointer :: errmgr + type(errors), target :: deferr + + ! Initialization + if (present(err)) then + errmgr => err + else + errmgr => deferr + end if + k = size(x) + + ! Local Memory Allocations + allocate(y(k), zi(k), stat = flag) + if (flag /= 0) then + call report_memory_error(errmgr, "levenes_test", flag) + return + end if + + ! Compute the total mean + z = 0.0d0 + n = 0 + do i = 1, k + ni = size(x(i)%x) + n = n + ni + y(i) = mean(x(i)%x) + zt = abs(x(i)%x - y(i)) + zi(i) = mean(zt) + z = z + zi(i) * ni + end do + z = z / n + + ! Process + numer = 0.0d0 + denom = 0.0d0 + do i = 1, k + ni = size(x(i)%x) + yi = y(i) + numer = numer + ni * (zi(i) - z)**2 + + inner = 0.0d0 + do j = 1, ni + zij = abs(x(i)%x(j) - yi) + inner = inner + (zij - zi(i))**2 + end do + denom = denom + inner + end do + stat = real((N - k) / (k - 1), real64) * (numer / denom) + dist%d1 = k - 1.0d0 + dist%d2 = real(n - k, real64) + p = 1.0d0 - dist%cdf(stat) +end subroutine + +! ------------------------------------------------------------------------------ +pure function sample_size(dist, var, delta, bet, alpha) result(rst) + !! Estimates the sample size required to achieve an experiment with the + !! desired power and significance levels to ascertain the desired + !! difference in parameter. + !! + !! See Also + !! + !! - [Wikipedia](https://en.wikipedia.org/wiki/Power_of_a_test) + class(distribution), intent(in) :: dist + !! The distribution to utilize as a measure. + real(real64), intent(in) :: var + !! An estimate of the population variance. + real(real64), intent(in) :: delta + !! The parameter difference that is desired. + real(real64), intent(in), optional :: bet + !! The desired power level. The default for this value is 0.2, for a + !! power of 80%. + real(real64), intent(in), optional :: alpha + !! The desired significance level. The default for this value is 0.05 + !! for a confidence level of 95%. + real(real64) :: rst + !! The minimum sample size requried to achieve the desired experimental + !! outcome. + + ! Local Variables + real(real64) :: a, b, za, zb + + ! Initialization + if (present(bet)) then + b = bet + else + b = 0.8d0 + end if + if (present(alpha)) then + a = alpha + else + a = 0.05d0 + end if + + za = dist%standardized_variable(1.0d0 - a / 2.0d0) + zb = dist%standardized_variable(b) + rst = 2.0d0 * (za + zb)**2 * var / (delta**2) +end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/src/fstats_regression.f90 b/src/fstats_regression.f90 index 9e05a76..5b79337 100644 --- a/src/fstats_regression.f90 +++ b/src/fstats_regression.f90 @@ -19,7 +19,7 @@ module fstats_regression public :: r_squared public :: adjusted_r_squared public :: correlation - public :: coefficient_matrix + public :: design_matrix public :: covariance_matrix public :: linear_least_squares public :: calculate_regression_statistics @@ -293,16 +293,18 @@ pure function correlation(x, y) result(rst) end function ! ------------------------------------------------------------------------------ -subroutine coefficient_matrix(order, intercept, x, c, err) - !! Computes the coefficient matrix \( X \) to the linear +subroutine design_matrix(order, intercept, x, c, err) + !! Computes the design matrix \( X \) for the linear !! least-squares regression problem of \( X \beta = y \), where - !! \( X \) is the coefficient matrix computed here, \( \beta \) is + !! \( X \) is the matrix computed here, \( \beta \) is !! the vector of coefficients to be determined, and \( y \) is the !! vector of measured dependent variables. !! !! See Also !! !! - [Wikipedia](https://en.wikipedia.org/wiki/Linear_regression) + !! - [Wikipedia](https://en.wikipedia.org/wiki/Vandermonde_matrix) + !! - [Wikipedia](https://en.wikipedia.org/wiki/Design_matrix) integer(int32), intent(in) :: order !! The order of the equation to fit. This value must be !! at least one (linear equation), but can be higher as desired. @@ -343,12 +345,12 @@ subroutine coefficient_matrix(order, intercept, x, c, err) ! Input Check if (order < 1) then - call errmgr%report_error("coefficient_matrix", & + call errmgr%report_error("design_matrix", & "The model order must be at least one.", FS_INVALID_INPUT_ERROR) return end if if (size(c, 1) /= npts .or. size(c, 2) /= ncols) then - call report_matrix_size_error(errmgr, "coefficient_matrix", & + call report_matrix_size_error(errmgr, "design_matrix", & "c", npts, ncols, size(c, 1), size(c, 2)) return end if @@ -372,7 +374,7 @@ subroutine coefficient_matrix(order, intercept, x, c, err) subroutine covariance_matrix(x, c, err) !! Computes the covariance matrix \( C \) where !! \( C = \left( X^{T} X \right)^{-1} \) and \( X \) is computed - !! by coefficient_matrix. + !! by design_matrix. !! !! See Also !! @@ -380,7 +382,7 @@ subroutine covariance_matrix(x, c, err) !! - [Wikipedia - Regression](https://en.wikipedia.org/wiki/Linear_regression) real(real64), intent(in) :: x(:,:) !! An M-by-N matrix containing the formatted independent data - !! matrix \( X \) as computed by coefficient_matrix. + !! matrix \( X \) as computed by design_matrix. real(real64), intent(out) :: c(:,:) !! The N-by-N covariance matrix. class(errors), intent(inout), optional, target :: err @@ -551,7 +553,7 @@ subroutine linear_least_squares(order, intercept, x, y, coeffs, & end if ! Compute the coefficient matrix - call coefficient_matrix(order, intercept, x, a, errmgr) + call design_matrix(order, intercept, x, a, errmgr) if (errmgr%has_error_occurred()) return ! Compute the covariance matrix diff --git a/src/fstats_types.f90 b/src/fstats_types.f90 new file mode 100644 index 0000000..62cff8f --- /dev/null +++ b/src/fstats_types.f90 @@ -0,0 +1,11 @@ +module fstats_types + use iso_fortran_env + implicit none + + type array_container + !! Provides a container for a real-valued array. A practical use of + !! this construct is in the construction of jagged arrays. + real(real64), allocatable, dimension(:) :: x + !! The array. + end type +end module \ No newline at end of file diff --git a/tests/fstats_distribution_tests.f90 b/tests/fstats_distribution_tests.f90 index ef9348f..6e9c1bc 100644 --- a/tests/fstats_distribution_tests.f90 +++ b/tests/fstats_distribution_tests.f90 @@ -186,5 +186,38 @@ function binomial_distribution_test_1() result(rst) end if end function +! ------------------------------------------------------------------------------ + function test_standardized_variable() result(rst) + ! Arguments + logical :: rst + + ! Variables + real(real64), parameter :: tol = 1.0d-2 + real(real64), parameter :: alpha1 = 0.975d0 + real(real64), parameter :: alpha2 = 0.2d0 + real(real64), parameter :: ans1 = 1.96d0 + real(real64), parameter :: ans2 = 0.84d0 + real(real64) :: z1, z2 + type(normal_distribution) :: dist + + ! Initialization + rst = .true. + call dist%standardize() + + ! Test 1 + z1 = dist%standardized_variable(alpha1) + if (.not.is_equal(z1, ans1, tol)) then + rst = .false. + print '(A)', "TEST FAILED: Standardized variable test -1." + end if + + ! Test 2 + z2 = dist%standardized_variable(0.8d0) + if (.not.is_equal(z2, ans2, tol)) then + rst = .false. + print '(A)', "TEST FAILED: Standardized variable test -2." + end if + end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/tests/fstats_regression_tests.f90 b/tests/fstats_regression_tests.f90 index 3837239..15ed15b 100644 --- a/tests/fstats_regression_tests.f90 +++ b/tests/fstats_regression_tests.f90 @@ -5,7 +5,7 @@ module fstats_regression_tests implicit none contains ! ------------------------------------------------------------------------------ - function coefficient_matrix_test_1() result(rst) + function design_matrix_test_1() result(rst) ! Arguments logical :: rst @@ -37,24 +37,24 @@ function coefficient_matrix_test_1() result(rst) ans3(:,5) = x**4 ! Test 1 - linear w/ intercept - call coefficient_matrix(order1, .true., x, c1) + call design_matrix(order1, .true., x, c1) if (.not.is_equal(c1, ans1)) then rst = .false. - print '(A)', "TEST FAILED: Coefficient Matrix Test 1 - 1" + print '(A)', "TEST FAILED: Design Matrix Test 1 - 1" end if ! Test 2 - linear w/o intercept - call coefficient_matrix(order1, .false., x, c2) + call design_matrix(order1, .false., x, c2) if (.not.is_equal(c2, ans2)) then rst = .false. - print '(A)', "TEST FAILED: Coefficient Matrix Test 1 - 2" + print '(A)', "TEST FAILED: Design Matrix Test 1 - 2" end if ! Test 3 - 4th order w/ intercept - call coefficient_matrix(order2, .true., x, c3) + call design_matrix(order2, .true., x, c3) if (.not.is_equal(c3, ans3)) then rst = .false. - print '(A)', "TEST FAILED: Coefficient Matrix Test 1 - 3" + print '(A)', "TEST FAILED: Design Matrix Test 1 - 3" end if end function diff --git a/tests/fstats_statistics_tests.f90 b/tests/fstats_statistics_tests.f90 index 8ec752d..8514435 100644 --- a/tests/fstats_statistics_tests.f90 +++ b/tests/fstats_statistics_tests.f90 @@ -2,6 +2,7 @@ module fstats_statistics_tests use iso_fortran_env use fstats use fstats_test_helper + use fstats_types implicit none contains ! ------------------------------------------------------------------------------ @@ -903,5 +904,168 @@ function test_correlation_1() result(rst) end if end function +! ------------------------------------------------------------------------------ + function test_pooled_variance_1() result(rst) + ! Arguments + logical :: rst + + ! Variables + integer(int32), parameter :: k = 20 + integer(int32), parameter :: n = 1000 + integer(int32) :: i, m, ni(k) + type(array_container) :: x(k) + real(real64) :: ans, sp, sp2, si(k) + + ! Initialization + rst = .true. + m = n * k + ans = 0.0d0 + do i = 1, k + allocate(x(i)%x(n)) + call random_number(x(i)%x) + si(i) = variance(x(i)%x) + ni(i) = n + ans = ans + si(i) * (n - 1.0d0) + end do + ans = ans / real(m - k, real64) + + ! Test 1 + sp = pooled_variance(x) + if (.not.is_equal(ans, sp)) then + rst = .false. + print '(A)', "TEST FAILED: Pooled variance test 1" + end if + + ! Test 2 + sp2 = pooled_variance(si, ni) + if (.not.is_equal(ans, sp2)) then + rst = .false. + print '(A)', "TEST FAILED: Pooled variance test 2" + end if + end function + +! ------------------------------------------------------------------------------ + function test_bartlett_1() result(rst) + ! Arguments + logical :: rst + + ! Local Variables + integer(int32), parameter :: npts = 25 + real(real64), parameter :: stat_ans = 1.52960933869d0 + real(real64), parameter :: p_ans = 0.21617108550d0 + type(array_container) :: x(2) + real(real64) :: stat, p + + ! Initialization + rst = .true. + allocate(x(1)%x(npts), x(2)%x(npts)) + x(1)%x = [ & + 0.357692624494507d0, 0.614383931107340d0, 0.802887803239860d0, & + 0.138578373117993d0, 0.754710064162687d0, 0.522900047841238d0, & + 0.076443208652965d0, 0.860167572639019d0, 0.183130360392741d0, & + 0.471659086806133d0, 0.071125320345872d0, 0.559104389166637d0, & + 0.500927806104085d0, 0.458795768141623d0,0.846677090629315d0, & + 0.569806543430701d0, 0.342909916953321d0, 0.660491929487175d0, & + 0.153963845813654d0, 0.274295416513455d0, 0.568200275187962d0, & + 0.234641814188948d0, 0.223741046257743d0, 0.960908965603275d0, & + 0.409105079237050d0] + x(2)%x = [ & + 0.146676174916891d0, 0.074990182260762d0, 0.626736796964143d0, & + 0.715565996611289d0, 0.243765200640375d0, 0.158861292064668d0, & + 0.135906579751008d0, 0.105995980721743d0, 0.040415255757239d0, & + 0.483256288452508d0, 0.658804776850479d0, 0.777622410194220d0, & + 0.965626651747080d0, 0.779568110382855d0, 0.215591619210302d0, & + 0.921351076345661d0, 0.199225207581094d0, 0.147835195118642d0, & + 0.908049631668390d0, 0.970759884908368d0, 0.825828458448519d0, & + 0.183678303516097d0, 0.433932667318501d0, 0.915015089978645d0, & + 0.495746710480416d0] + + ! Test 1 - reference results calculated by Excel + call bartletts_test(x, stat, p) + if (.not.is_equal(stat, stat_ans)) then + rst = .false. + print '(A)', "TEST FAILED: Bartlett's test 1" + end if + if (.not.is_equal(p, p_ans)) then + rst = .false. + print '(A)', "TEST FAILED: Bartlett's test 1" + end if + end function + +! ------------------------------------------------------------------------------ + function test_levene_1() result(rst) + ! Arguments + logical :: rst + + ! Local Variables + integer(int32), parameter :: npts = 25 + real(real64), parameter :: stat_ans = 4.85959468188d0 + real(real64), parameter :: p_ans = 0.03231972203d0 + type(array_container) :: x(2) + real(real64) :: stat, p + + ! Initialization + rst = .true. + allocate(x(1)%x(npts), x(2)%x(npts)) + x(1)%x = [ & + 0.357692624494507d0, 0.614383931107340d0, 0.802887803239860d0, & + 0.138578373117993d0, 0.754710064162687d0, 0.522900047841238d0, & + 0.076443208652965d0, 0.860167572639019d0, 0.183130360392741d0, & + 0.471659086806133d0, 0.071125320345872d0, 0.559104389166637d0, & + 0.500927806104085d0, 0.458795768141623d0,0.846677090629315d0, & + 0.569806543430701d0, 0.342909916953321d0, 0.660491929487175d0, & + 0.153963845813654d0, 0.274295416513455d0, 0.568200275187962d0, & + 0.234641814188948d0, 0.223741046257743d0, 0.960908965603275d0, & + 0.409105079237050d0] + x(2)%x = [ & + 0.146676174916891d0, 0.074990182260762d0, 0.626736796964143d0, & + 0.715565996611289d0, 0.243765200640375d0, 0.158861292064668d0, & + 0.135906579751008d0, 0.105995980721743d0, 0.040415255757239d0, & + 0.483256288452508d0, 0.658804776850479d0, 0.777622410194220d0, & + 0.965626651747080d0, 0.779568110382855d0, 0.215591619210302d0, & + 0.921351076345661d0, 0.199225207581094d0, 0.147835195118642d0, & + 0.908049631668390d0, 0.970759884908368d0, 0.825828458448519d0, & + 0.183678303516097d0, 0.433932667318501d0, 0.915015089978645d0, & + 0.495746710480416d0] + + ! Test 1 - reference results calculated by Excel + call levenes_test(x, stat, p) + if (.not.is_equal(stat, stat_ans)) then + rst = .false. + print '(A)', "TEST FAILED: Levene's test 1" + end if + if (.not.is_equal(p, p_ans)) then + rst = .false. + print '(A)', "TEST FAILED: Levene's test 1" + end if + end function + +! ------------------------------------------------------------------------------ + function test_sample_size() result(rst) + ! Arguments + logical :: rst + + ! Variables + real(real64), parameter :: tol = 1.0d-3 + real(real64), parameter :: ans = 15.698d0 + real(real64), parameter :: var = 1.0d0 + real(real64), parameter :: delta = 1.0d0 + real(real64), parameter :: alpha = 0.05d0 + real(real64), parameter :: bet = 0.8d0 + real(real64) :: dn + type(normal_distribution) :: dist + + ! Initialization + rst = .true. + call dist%standardize() + + ! Test 1 + dn = sample_size(dist, var, delta, bet, alpha) + if (.not.is_equal(ans, dn, tol)) then + rst = .false. + print '(A)', "TEST FAILED: Sample size test 1." + end if + end function + ! ------------------------------------------------------------------------------ end module \ No newline at end of file diff --git a/tests/fstats_tests.f90 b/tests/fstats_tests.f90 index 1d3a19a..eef853d 100644 --- a/tests/fstats_tests.f90 +++ b/tests/fstats_tests.f90 @@ -73,7 +73,7 @@ program tests local = incomplete_gamma_test_1() if (.not.local) overall = .false. - local = coefficient_matrix_test_1() + local = design_matrix_test_1() if (.not.local) overall = .false. local = regression_test_1() @@ -118,6 +118,22 @@ program tests local = test_correlation_1() if (.not.local) overall = .false. + ! Additional Tests + local = test_pooled_variance_1() + if (.not.local) overall = .false. + + local = test_bartlett_1() + if (.not.local) overall = .false. + + local = test_levene_1() + if (.not.local) overall = .false. + + local = test_standardized_variable() + if (.not.local) overall = .false. + + local = test_sample_size() + if (.not.local) overall = .false. + ! End if (.not.overall) then stop 1