Skip to content

Instantly share code, notes, and snippets.

@Laeeth
Last active December 17, 2019 10:50
Show Gist options
  • Save Laeeth/16beb1033fc9131d170724995b3d603f to your computer and use it in GitHub Desktop.
Save Laeeth/16beb1033fc9131d170724995b3d603f to your computer and use it in GitHub Desktop.
C++ vs D

C++ using Mark Joshi's library

 LPXLFOPER EXCEL_EXPORT xlStats(LPXLFOPER inTargetRange) {
        EXCEL_BEGIN;
        XlfOper xlTargetRange(inTargetRange);

        // Temporary variables.
        double averageTmp = 0.0;
        double varianceTmp = 0.0;

        // Iterate over the cells in the incoming matrix.
        for (RW i = 0; i < xlTargetRange.rows(); ++i)
        {
            for (RW j = 0; j < xlTargetRange.columns(); ++j)
            {
                // sums the values.
                double value(xlTargetRange(i,j).AsDouble());
                averageTmp += value;
                // sums the squared values.
                varianceTmp += value * value;
            }
        }
        size_t popSize = xlTargetRange.rows() * xlTargetRange.columns();

        // avoid divide by zero
        if(popSize == 0)
        {
            THROW_XLW("Can't calculate stats on empty range");
        }

        // Initialization of the results Array oper.
        XlfOper result(1, 2);
        // compute average.
        double average = averageTmp / popSize;
        result(0, 0) = average;
        // compute variance
        result(0, 1) = varianceTmp / popSize - average * average;
        return result;
        EXCEL_END;
    }

The D version

    import xlld;
    import std.algorithm:map,sum;
    import std.range:front;

    @Register(ArgumentText("input range to calculate statistics for"),
        HelpTopic("excel-d"),
        FunctionHelp("calculates mean and variance for input array"),
        ArgumentHelp(["input range to calculate statistics for"]))
    auto xlStats(double[][] inTargetRange)
    {
        auto numCells = (inTargetRange.length > 0) ?
                                     inTargetRange.length * inTargetRange.front.length : 0;
        auto means = inTargetRange.map!(row => row.sum).sum / numCells;
        auto sumSquares = inTargetRange.map!( row => row.map!(cell => cell*cell).sum).sum;
        return [means, sumSquares / numCells - means];
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment