View Raw SPL
/****************************************************************************
*                                                                           *
*   VAR.SPL     Copyright 2022 (C) DSP Development Corporation              *
*                                                                           *
*   Author:     Randy Race                                                  *
*                                                                           *
*   Synopsis:   Column based variance                                       *
*                                                                           *
*   Revisions:  13 Jul 2022     RRR     Creation                            *
*                                                                           *
****************************************************************************/

#include 

#if @HELP_VAR

    VAR

    Purpose: Calculates the sample or population variance of a series.

    Syntax:  VAR(s, dof, dim, "naflag")

             (v, mn) = VAR(s, dof, dim, "naflag")

                     s - A series.

                   dof - Optional. An integer, the normalization mode.
                         For N = length(s)

                          0: sample variance, normalize by 1/(N-1) (default)

                          1: population variance, normalize by 1/N

                   dim - Optional. An integer or string, the computation
                         dimension.

                              0 : calculate over full array

                              1 : calculate row-wise (default)

                              2 : calculate column-wise

                          "all" : calculate over full array


              "naflag" - Optional. A string, the NA handling method.

                             "omitnan" : ignore NA values (default)

                          "includenan" : include NA values
  

    Returns: A real scalar for a one column series or computation over the
             entire array else a 1xM real table for an M column series.

             (v, mn) = VAR(s, dof, dim, "naflag") returns the variance and
             mean value as separate variables.

    Example:
             W1: 1..10
             var(w1)

             Returns 9.1667, the sample variance.

    Example:
             W1: 1..10
             var(w1+1e7)

             Returns 9.1667, same as above since the true variance
             is independent of the mean value.

    Example:
             W1: 1..10
             var(w1, 1)

             Returns 8.250, the population variance.

    Example:
             W1: ravel(1..9, 3)^2
             W2: var(w1)

             W2 == {{16.3333, 100.3333, 256.3333}}, the variance of each
             column.

   Example:
             W1: ravel(1..9, 3)^2
             W2: var(w1, 0, 2)

             W2 == {603, 927, 1323}, the variance of each row.

    Example:
             W1: ravel(1..9, 3)^2
             W2: {var(w1, 0, "all")}

             W2 == {788.5}, the sample variance of the entire array.

    Example:
             W1: ravel(1..9, 3)^2
             (v, mn) = var(w1, 0, "all");

             v  == 788.5
             mn == 31.6667

             Returns the sample variance and mean of the entire array.

    Example:
             W1: {1, 10, nan, 3, 4, nan, 6}
             W2: {var(w1, 0)}
             W3: {var(w1, 0, "omitnan")}
             W4: {var(w1, 0, "includenan")}

             W2 == W3 == {11.7}, the variance of the series with NA
             values ignored.

             W4 == nan, since NA values are included.

    Remarks:
             If s is the input series and N the length of the series,
             the basic form of the sample variance (dof == 0)
             is:

                var(s) = sum((s - mean(s))^2/(N-1))

             The population variance (dof == 1) is defined as:

                var(s) = sum((s - mean(s))^2/N)


             VAR uses a fast, highly accurate corrected two-pass Neumaier
             sum algorithm that exhibits insensitivity to round-off errors.

             As shown in the second example, the variance is independent
             of an additive mean value.

             VAR returns the variance of each column or row for a
             multi-column series. Use DIM = 0 or DIM = "all" or use
             VARIANCE to compute the variance of the entire array.

    See Also:
             Mean
             Std
             Stdev
             Variance
#endif


/* variance of each column */
var(s, dof, dim, naflag, method)
{
        local N, v, mn;

        if (argc < 1 || not(isarray(s)))
        {
                /* default to current series */
                (dof, dim, naflag, method) = stdvar_parse_args(FALSE, s, dof, dim, naflag);

                s = refseries(w0);
        }
        else
        {
                (dof, dim, naflag, method) = stdvar_parse_args(TRUE, dof, dim, naflag, method);
        }

        if (dim > 1)
        {
                s = s';
        }

        if (dim == 0)
        {
                /* full array */
                (v, mn) = variance(s, -1, -1, dof, naflag, method);
        }
        else
        {
                /* variance of each column or row */
                (v, mn) = colstdev(s, -1, -1, dof, "variance", naflag, method);

                if (numcols(v) == 1)
                {
                        /* return scalars */
                        v  = v[1];
                        mn = mn[1];
                }
                else if (dim > 1)
                {
                        v  = v';
                        mn = mn';
                }
        }
        
        return(v, mn);
}