XLL+ Class Library

MyCorrel Example

This example demonstrates how to read vector inputs and pass them to a 'real-world' function.

#include <math.h>

// Function:    CalculateCorrel
// Returns:     double
// Description: Calculate the correlation of a series

double CalculateCorrel(int nSamples, const double* pdX, 
                       const double* pdY)
{
    int i, j;
    double d, adSum[2], adSum2[2], dSumProd;
    const double* pdIn[2] = { pdX, pdY };
    double adSd[2], dCorrel;

    adSum[0] = adSum[1] = adSum2[0] = adSum2[1] = 0.0;
    dSumProd = 0.0;

    for ( i = 0; i < nSamples; i++ )
    {
        for ( j = 0; j < 2; j++ )
        {
            d = pdIn[j][i];
            adSum[j] += d;
            adSum2[j] += d * d;
        }
        dSumProd += pdIn[0][i] * pdIn[1][i];
    }
    
    for ( j = 0; j < 2; j++ )
        adSd[j] = sqrt((adSum2[j] - (adSum[j] * adSum[j] / nSamples))
                     / nSamples);

    if ( ( adSd[0] == 0.0 ) && ( adSd[1] == 0.0 ) )
        dCorrel = 1.0;
    else if ( ( adSd[0] == 0.0 ) || ( adSd[1] == 0.0 ) )
        dCorrel = 0.0;
    else
        dCorrel = (dSumProd - ((adSum[0] * adSum[1]) / nSamples))
                / ( nSamples * adSd[0] * adSd[1]);

    return dCorrel;
}

// Function:    MyCorrel
// Returns:     LPXLOPER
// Description: Calculate the correlation of two series

//{{XLP_SRC(MyCorrel)
    // NOTE - the FunctionWizard will add and remove mapping code here.
    //    DO NOT EDIT what you see in these blocks of generated code!
IMPLEMENT_XLLFN2(MyCorrel, "RPP", "MyCorrel", "X,Y", "User Define"
    "d", "Calculate the correlation of two series", "First series"
    "\000Second series\000", "\0\0", 1)

extern "C" __declspec( dllexport )
LPXLOPER MyCorrel(const COper* lpopX, const COper* lpopY)
{
    CXlOper xloResult;
//}}XLP_SRC

    BOOL bOk = TRUE;
    CString strError;

    // Read X into a vector of doubles
    std::vector<double> vecX;
    if ( bOk && !(bOk = lpopX->ColToVector(vecX, &strError)) )
        strError = "Error in X: " + strError;
    if ( bOk && !(bOk = (vecX.size() >= 2)) )
        strError = "Error in X: expected at least 2 cells";

    // Read Y into a vector of doubles
    std::vector<double> vecY;
    if ( bOk && !(bOk = lpopY->ColToVector(vecY, &strError)) )
        strError = "Error in Y: " + strError;

    // Compare X & Y
    if ( bOk && !(bOk = (vecX.size() == vecY.size())) )
        strError = "Error: expected X and Y to be the same size";

    // Deal with input errors now - do not continue
    if ( !bOk )
    {
        xloResult = strError;
        return xloResult.Ret();
    }

    // Call the real-world function & return the result
    xloResult = CalculateCorrel(vecX.size(), &vecX[0], &vecY[0]);
    return xloResult.Ret();
}

Uses

COper::ColToVector