View Raw SPL
/*****************************************************************************
*                                                                            *
*   VAVGS.SPL   Copyright (C) 2014-2015 DSP Development Corporation          *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:      Randy Race                                                  *
*                                                                            *
*   Synopsis:    Returns the point by point mean of one or more inputs       *
*                                                                            *
*   Revisions:   22 Sep 2014  RRR  Creation                                  *
*                 1 Sep 2015  RRR  unity series fix                          *
*                                                                            *
*****************************************************************************/


#if @HELP_VAVGS

    VAVGS

    Purpose: Returns the point by point mean of one or more input arguments.

    Syntax:  VAVGS(val1, val2, ..., valN)

               valN - One ore more series or scalars.

    Returns: A series, the point by point mean of all the input values.

    Example:
             vavgs(10, 15, 20)

             returns {15}

    Example:
             W1: avgs({1, 2, 3, 4, 5}, {1, 4, 2}, {1, 0, 3, 8})
             W2: vavgs({1, 2, 3, 4, 5}, {1, 4, 2}, {1, 0, 3, 8})

             W1 == {1, 2, 2.6667, 4, 1.6667}
             W2 == {1, 2, 2.6667, 6, 5}

             Unlike the result from AVGS, VAVGS does not zero pad shorter
             series.

    Example:
             W1: ravel(1..9, 3)
             W2: ravel(11..26, 4)
             W3: avgs(W1, W2)
             W4: vavgs(W1, W2)

             W1 == {{1, 4, 7},
                    {2, 5, 8},
                    {3, 6, 9}}

             W2 == {{11, 15, 19, 23},
                    {12, 16, 20, 24},
                    {13, 17, 21, 25},
                    {14, 18, 22, 26}}

             W3 == {{6,   9.5, 13, 11.5},
                    {7,  10.5, 14, 12},
                    {8,  11.5, 15, 12.5},
                    {7,   9,   11, 13}}

             W4 == {{6,   9.5, 13, 23},
                    {7,  10.5, 14, 24},
                    {8,  11.5, 15, 25},
                    {14, 18,   22, 26}}

             Unlike the result from AVGS, VAVGS does not zero pad series
             with fewer columns.

    Remarks:
             VAVGS requires at least one input argument.

             VAVGS always returns a series.

             Non-numeric arguments are ignored.

             Unlike AVGS, unequal sized input series are not padded with
             zeros.

             See VSUMS to compute the point by point sum of the input values.

             See VMEAN to compute the scalar mean of the input values.

    See Also:
             Avgs
             Mean
             Vmax
             Vmean
             Vmin
             Vsum
             Vsums
#endif


/* point by point mean of input args */
vavgs(argv)
{
        local j, cnt, sum, nr, nc, ncc, vnct, s, smin, smax;

        if (argc < 1)
        {
                error("vavgs - input value required");
        }

        /* max rows & cols */
        (nr, nc) = vavgs_size(argv);

        sum = zeros(1, nc);
        cnt = zeros(1, nc);

        /* get sum and lengths of inputs */
        loop (j = 1..argc)
        {
                if (isnumeric(getargv(j)))
                {
                        s = isarray(getargv(j)) ? refseries(getargv(j)) : castseries(getargv(j));

                        if (length(s) > 0)
                        {
                                smax = max(max(collength(s)), max(collength(sum)));
                                smin = min(min(collength(s)), min(collength(sum)));

                                /* counts for each column */
                                if (numcols(s) > 1)
                                {
                                        vcnt = reshape(ones(numel(s), 1), collength(s)');
                                }
                                else
                                {
                                        vcnt = ones(length(s), 1);
                                }

                                if (smin == 1)
                                {
                                        /* unity length series */
                                        s = extract(s, 1, smax);
                                }

                                /* deal unequal length series */
                                vcnt = extract(vcnt, 1, smax);

                                if (numcols(s) < nc)
                                {
                                        /* add columns to conform */
                                        ncc  = nc - numcols(s);

                                        vcnt = ravel(vcnt, zeros(1, ncc));
                                        s    = ravel(s,    zeros(1, ncc));
                                }

                                /* update sum and count */
                                sum = sum + s;
                                cnt = cnt + vcnt;
                        }
                }
        }

        /* mean */
        return(sum / cnt);
}


/* find max numrows & numcols for inputs */
vavgs_size(argv)
{
        local j, nr, nc, s;

        if (argc < 1)
        {
                error("vavgs - input value required");
        }

        nr = nc = 0;

        /* get sum and lengths of inputs */
        loop (j = 1..argc)
        {
                if (isnumeric(getargv(j)))
                {
                        s = isarray(getargv(j)) ? refseries(getargv(j)) : castseries(getargv(j));

                        nr = max(nr, numrows(s));
                        nc = max(nc, numcols(s));
                }
        }

        return(nr, nc);
}