NxF32 Gauss::Get(Rand &r) { if ( !HasGaussFlag(GF_STDEV) ) return mMean; NxF32 v; if ( HasGaussFlag(GF_LINEAR) ) { v = mMean + (ranfloat()*mStandardDeviation - (mStandardDeviation*0.5f)); } else { v = RandGauss(&r)*mStandardDeviation + mMean; } if ( HasGaussFlag(GF_MIN) ) { if ( v < mMin ) v = mMin; } if ( HasGaussFlag(GF_MAX) ) { if ( v > mMax ) v = mMax; } mCurrent = v; return v; };
static double func6(const double x[], const int iResponse) { // 5 preds, 2nd order return x[0] +x[1]+ x[2] +x[3] +x[4] +x[5] + x[0]*x[1] + x[2]*x[3] + x[4]*x[5] + .1 * RandGauss(); }
static double func1(const double x[], const int iResponse) { return x[0] + x[1] + .1 * RandGauss(); }
//----------------------------------------------------------------------------- static double funcNoise(const double x[], const int iResponse) { return RandGauss(); }
//----------------------------------------------------------------------------- static void TestEarth(char sTestName[], double (__cdecl *func)(const double xrow[], const int iResponse), const int nCases, const int nResponses, const int nPreds, const int nMaxDegree, const int nMaxTerms, const double Trace, const bool Format, const double ForwardStepThresh, const int nFastK, const double FastBeta, const double NewVarPenalty, const int seed, const double Collinear = 0) // used for testing NewVarPenalty { #define y_(i,iResponse) y[(i) + (iResponse)*(nCases)] int *LinPreds = (int *)calloc(nPreds, sizeof(int)); double *x = (double *)malloc(nCases * nPreds * sizeof(double)); double *y = (double *)malloc(nCases * nResponses * sizeof(double)); double *bx = (double *)malloc(nCases * nMaxTerms * sizeof(double)); bool *BestSet = (bool *) malloc(nMaxTerms * sizeof(bool)); int *Dirs = (int *) malloc(nMaxTerms * nPreds * sizeof(int)); double *Cuts = (double *)malloc(nMaxTerms * nPreds * sizeof(double)); double *Residuals = (double *)malloc(nCases * nResponses * sizeof(double)); double *Betas = (double *)malloc(nMaxTerms * nResponses * sizeof(double)); static int nTest; nTest++; printf("=============================================================================\n"); printf("TEST %d: %s n=%d p=%d\n", nTest, sTestName, nCases, nPreds); // init x srand(seed); int i; for (i = 0; i < nCases; i++) for (int iPred = 0; iPred < nPreds; iPred++) { double xtemp; xtemp = (double)((rand() % 20000) - 10000) / 10000; // rand number from -1 to +1 x[i + iPred * nCases] = xtemp; } // sort the first column of x, makes debugging easier qsort(x, nCases, sizeof(double), cmp); if (Collinear > 0) { // copy column 0 to 1 with added noise for (i = 0; i < nCases; i++) x[i + 1 * nCases] = x[i] + Collinear * RandGauss(); } // init y double *xrow = (double *)malloc(nPreds * sizeof(double)); for (i = 0; i < nCases; i++) { for (int iPred = 0; iPred < nPreds; iPred++) xrow[iPred] = x[i + iPred * nCases]; for (int iResponse = 0; iResponse < nResponses; iResponse++) y_(i, iResponse) = func(xrow, iResponse); } free(xrow); double BestGcv; int nTerms, iReason; const double Penalty = ((nMaxDegree>1)? 3:2); clock_t Time = clock(); if(Trace >= 4) { if(nResponses != 1) error("cannot use Trace>=4 with nResponses!=1"); printf(" y"); for(int iPred = 0; iPred < nPreds; iPred++) printf(" x%d", iPred); printf("\n"); for(int i = 0; i < nCases; i++) { printf("%4d % 7.5f", i, y[i]); for(int iPred = 0; iPred < nPreds; iPred++) { printf(" % 7.5f", x[i + iPred * nCases]); } printf("\n"); } printf("\n"); } Earth(&BestGcv, &nTerms, &iReason, BestSet, bx, Dirs, Cuts, Residuals, Betas, x, y, NULL, // weights are NULL nCases, nResponses, nPreds, nMaxDegree, nMaxTerms, Penalty, ForwardStepThresh, 0, 0, // MinSpan, EndSpan true, // Prune nFastK, FastBeta, NewVarPenalty, LinPreds, 2 /*AdjustEndSpan*/, true /*AutoLinPred*/, true /*UseBetaCache*/, Trace, NULL); // calc nUsedTerms int nUsedTerms = 0; for (int iTerm = 0; iTerm < nTerms; iTerm++) if (BestSet[iTerm]) nUsedTerms++; // calc RSquared, GRSquared for (int iResponse = 0; iResponse < nResponses; iResponse++) { double Rss = 0, Tss = 0, meanY = 0; for (i = 0; i < nCases; i++) meanY += y_(i, iResponse); meanY /= nCases; xrow = (double *)malloc(nPreds * sizeof(double)); double *yHat = (double *)malloc(nResponses * sizeof(double)); for (i = 0; i < nCases; i++) { for (int iPred = 0; iPred < nPreds; iPred++) xrow[iPred] = x[i + iPred * nCases]; PredictEarth(yHat, xrow, BestSet, Dirs, Cuts, Betas, nPreds, nResponses, nTerms, nMaxTerms); double Residual = y_(i,iResponse) - yHat[iResponse]; Rss += sq(Residual); Tss += sq(y_(i,iResponse) - meanY); } free(yHat); free(xrow); const double RSq = 1 - Rss/Tss; const double GcvNull = getGcv(1, nCases, Tss, Penalty); const double GRSq = 1 - getGcv(nUsedTerms, nCases, Rss, Penalty) / GcvNull; #if PRINT_TIME double TimeDelta = (double)(clock() - Time) / CLOCKS_PER_SEC; #else double TimeDelta = 99.99; #endif // show results if (nResponses > 1) { printf("RESULT %d Response %d: GRSq %.5g RSq %.5g nTerms %d of %d of %d", nTest, iResponse+1, GRSq, RSq, nUsedTerms, nTerms, nMaxTerms); if (iResponse == 0) printf(" FUNCTION %s n=%d p=%d [%.2f secs]", sTestName, nCases, nPreds, TimeDelta); printf("\n"); } else printf("RESULT %d: GRSq %g RSq %g nTerms %d of %d of %d " "FUNCTION %s n=%d p=%d [%.2f secs]\n", nTest, GRSq, RSq, nUsedTerms, nTerms, nMaxTerms, sTestName, nCases, nPreds, TimeDelta); } if (Format && Trace != 0) { printf("\nTEST %d: FUNCTION %s n=%d p=%d\n", nTest, sTestName, nCases, nPreds); FormatEarth(BestSet, Dirs, Cuts, Betas, nPreds, nResponses, nTerms, nMaxTerms, 3, 1e-6); printf("\n"); } free(LinPreds); free(x); free(y); free(BestSet); free(Dirs); free(Cuts); free(Residuals); free(Betas); free(bx); }
static double func2collinear(const double x[], const int iResponse) { return cos(x[0]) + cos(x[1]) + .1 * RandGauss(); }
static double func1collinear(const double x[], const int iResponse) { return x[0] + x[1] + .001 * RandGauss(); }
static double func56(const double x[], const int iResponse) { // Friedman MARS paper eqn 56 return 0.1 * exp(4*x[0]) + 4 / (1 + exp(-20*(x[1]-0.5)) + 3*x[2] + 2*x[3] + x[4] + RandGauss()); }
static double func8(const double x[], const int iResponse) { // 20 preds, 2nd order return x[0] +x[1]+ x[2] +x[3] +x[4] +x[5] +x[6] +x[7] +x[8] +x[9] + x[10]+x[11]+x[12]+x[13]+x[14]+x[15]+x[16]+x[17]+x[18]+x[19] + x[0]*x[1] + x[2]*x[3] + x[4]*x[5] + x[6]*x[7] + x[8]*x[9] + + .1 * RandGauss(); }
static void RandomlyShiftFeatures (RgbImage &Img, // io: the face image we are going to modify const RgbImage &OriginalImg, // in const SHAPE &Shape, // in: landmark results of ASM search bool fShowBox) // in: show rectangle borders, for debugging { const tBlends Blends[] = { { 0, .2 }, { 3, .5 }, { 5, .7 }, { 6, 1 }, }; double InterPupilDist = Shape(36, VX) - Shape(31, VX); ShiftRectangleWithBlend(Img, // lower nose OriginalImg, Shape(67, VX), (Shape(37, VY) + 3 * Shape(41, VY)) / 4, (Shape(43, VX) - Shape(39, VX)) * 1.2, (Shape(37, VY) - Shape(41, VY)) * .8, RandGauss(2), RandGauss(2), 1, 1, Blends, NELEMS(Blends), fShowBox); ShiftRectangleWithBlend(Img, // upper nose OriginalImg, (Shape(34, VX) + Shape(29, VX)) / 2, (Shape(34, VY) + Shape(29, VY)) / 2, InterPupilDist / 2.6, InterPupilDist / 2, RandGauss(2), RandGauss(2), 1, 1, Blends, NELEMS(Blends), fShowBox); ShiftRectangleWithBlend(Img, // left eyebrow OriginalImg, (Shape(24, VX) + Shape(21, VX)) / 2, (Shape(23, VY) + Shape(25, VY)) / 2, 1.3 * ((Shape(24, VX) - Shape(21, VX))), MAX(Shape(23, VY), Shape(24, VY)) - MIN(Shape(25, VY), Shape(21, VY)) + 8, RandGauss(3), RandGauss(3), 1, 1, gDefaultBlends, NELEMS(gDefaultBlends), fShowBox); ShiftRectangleWithBlend(Img, // right eyebrow OriginalImg, (Shape(15, VX) + Shape(18, VX)) / 2, (Shape(20, VY) + Shape(22, VY)) / 2, 1.3 * ((Shape(15, VX) - Shape(18, VX))), MAX(Shape(17, VY), Shape(18, VY)) - MIN(Shape(19, VY), Shape(15, VY)) + 8, RandGauss(3), RandGauss(3), 1, 1, gDefaultBlends, NELEMS(gDefaultBlends), fShowBox); ShiftRectangleWithBlend(Img, // forehead OriginalImg, (Shape(36, VX) + Shape(31, VX)) / 2, Shape(31, VY) + .7 * InterPupilDist, InterPupilDist * 1.4, InterPupilDist * .4, RandGauss(4), RandGauss(4), 1, 1, gDefaultBlends, NELEMS(gDefaultBlends), fShowBox); ShiftRectangleWithBlend(Img, // upper forehead OriginalImg, (Shape(36, VX) + Shape(31, VX)) / 2, Shape(31, VY) + 1.1 * InterPupilDist, InterPupilDist * 1.5, InterPupilDist * .5, RandGauss(3), RandGauss(3), 1, 1, gDefaultBlends, NELEMS(gDefaultBlends), fShowBox); ShiftRectangleWithBlend(Img, // left cheek OriginalImg, Shape(27, VX), Shape(27, VY) - .5 * InterPupilDist, InterPupilDist * .4, InterPupilDist * .4, RandGauss(4), RandGauss(4), 1, 1, Blends, NELEMS(Blends), fShowBox); ShiftRectangleWithBlend(Img, // right cheek OriginalImg, Shape(32, VX), Shape(32, VY) - .5 * InterPupilDist, InterPupilDist * .4, InterPupilDist * .4, RandGauss(4), RandGauss(4), 1, 1, Blends, NELEMS(Blends), fShowBox); }