2
\$\begingroup\$

What could I improve in the following code? The goal is to test a function againts a table of input parameters and compare to some expected results with some tolerance (as there are random variables involved in the computations).

This is how I am doing it right now. Note that I cannot use any C++11 features.

void test() throw (const char *) {

    const double TOLERANCE = 0.01;

    const double EXPIRY_TESTS[] = {0.0, more values...};
    const double STRIKE_TESTS[] = { 0.0, more values... };
    const double SPOT_TESTS[] = { 0.0, more values... };
    const double VOL_TESTS[] = { 0.0, more values... };
    const double R_TESTS[] = { 0.0, more values... };
    const unsigned long NPATHS_TESTS[] = { 1, more values... };
    const double EXPECTED_RESULTS[] = { 0.0, more values... };

    int i_result = 0;
    for (int i0 = 0; i0 < sizeof(EXPIRY_TESTS) / sizeof(double); i0++) {
        for (int i1 = 0; i1 < sizeof(STRIKE_TESTS) / sizeof(double); i1++) {
            for (int i2 = 0; i2 < sizeof(SPOT_TESTS) / sizeof(double); i2++) {
                for (int i3 = 0; i3 < sizeof(VOL_TESTS) / sizeof(double); i3++) {
                    for (int i4 = 0; i4 < sizeof(R_TESTS) / sizeof(double); i4++) {
                        for (int i5 = 0; i5 < sizeof(NPATHS_TESTS) / sizeof(long); i5++) {

                            double result = SimpleMonteCarlo1(EXPIRY_TESTS[i0], 
                                                              STRIKE_TESTS[i1], 
                                                              SPOT_TESTS[i2], 
                                                              VOL_TESTS[i3], 
                                                              R_TESTS[i4], 
                                                              NPATHS_TESTS[i5]);
                            if (abs(EXPECTED_RESULTS[i_result] - result) >= TOLERANCE) {
                                throw "Test failed!";
                            }
                            i_result++;

                        }
                    }
                }
            }
        }
    }

}
\$\endgroup\$
  • \$\begingroup\$ Approximately how many values? \$\endgroup\$ – 200_success Feb 16 '15 at 9:31
  • \$\begingroup\$ About 3-8 values per parameter. \$\endgroup\$ – José D. Feb 16 '15 at 9:34
2
\$\begingroup\$
  • A six-fold nesting is not a way to go. Enumerating all possible combinations can be achieved in two loops, no matter how many arrays are contributing:

    bool next_combination(int * combination, int * limits, int size) {
        for (int index = 0; index < size; ++index) {
            combination[index] += 1;
            if (combination[index] < limits[index]) {
                return true;
            }
            combination[index] = 0;
        }
        return false;
    }
    
    ...
    
    int limits[] = { countof(EXPIRY_TEST), countof(STRIKE_TEST), /*etc*/ };
    int combination[countof(limits)] = 0;
    
    do {
        result = function(EXPIRY_TEST[combination[0], STRIKE_TEST[combination[1], /*etc*/);
    while (next_combination(combination, limits, countof(combination)));
    
  • Size of array is better be computed in a type-agnostic way:

    #define countof(name) (sizeof(name) / sizeof(name[0]))
    
  • The expected results are totally disconnected from the argument sets. It would be very hard to make additional cases.

  • You must report which test case failed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.