コード例 #1
0
ファイル: IniParser_ut.cpp プロジェクト: Jshauk/sumatrapdf
static void IniTest()
{
    IniFile pNull((const char *)NULL);
    assert(pNull.sections.Count() == 0);

    IniFile pEmpty("");
    assert(pEmpty.sections.Count() == 1 && !pEmpty.sections.At(0)->name);
    assert(pEmpty.FindSection(NULL)->lines.Count() == 0);

    IniFile pNoNL1("key = value");
    assert(str::Eq(pNoNL1.sections.At(0)->lines.At(0).value, "value"));

    IniFile pNoNL2("[Section ]");
    assert(pNoNL2.FindSection("Section "));

    static const char *iniData = "\
; NULL section \n\
key1=value1\n\
[Section 1]\n\
  key2 = value2 \n\
  # comment \n\
  key3: \"quoted value\" \n\n\
[ Empty Section ]\n\n\
  ]Section 2 \n\
key without separator\n\
";
    IniLine verify[] = {
        IniLine(NULL, NULL), IniLine("key1", "value1"),
        IniLine("Section 1", NULL), IniLine("Key2", "value2"), IniLine("key3", "\"quoted value\""),
        IniLine(" Empty Section ", NULL),
        IniLine("Section 2", NULL), IniLine("key", "without separator"),
    };

    IniFile p(iniData);
    size_t idxSec = (size_t)-1, idxLine = (size_t)-1;
    for (int i = 0; i < dimof(verify); i++) {
        if (!verify[i].value) {
            if (idxSec != (size_t)-1) {
                assert(p.sections.At(idxSec)->lines.Count() == idxLine);
            }
            idxSec++;
            idxLine = 0;
            assert(p.FindSection(verify[i].key) == p.sections.At(idxSec));
            continue;
        }
        assert(idxSec < p.sections.Count() && idxLine < p.sections.At(idxSec)->lines.Count());
        IniLine *line = p.sections.At(idxSec)->FindLine(verify[i].key);
        assert(line && str::EqI(line->key, verify[i].key) && str::Eq(line->value, verify[i].value));
        idxLine++;
    }
    assert(p.sections.Count() == idxSec + 1 && p.sections.Last()->lines.Count() == idxLine);
    assert(p.FindSection("Section 1", 1) && p.FindSection("Section 2", 2));
    assert(!p.FindSection("missing") && !p.FindSection("Section 1", 2));
    assert(!p.FindSection("Section 1")->FindLine("missing"));
}
コード例 #2
0
ファイル: test-object.cpp プロジェクト: drb27/fl
void ObjectTestFixture::testHighlyChunkedAppend()
{
    listref a = listref(empty_list());
    listref b = listref(empty_list());

    void_object* null = new void_object(g_pContext);
    objref pNull(null);

    a->append(pNull);
    a->append(pNull);
    a->append(pNull);

    b->append(pNull);
    b->append(pNull);
    b->append(pNull);

    CPPUNIT_ASSERT(a->chunks()==3);
    CPPUNIT_ASSERT(b->chunks()==3);

    list_object* c = new list_object(g_pContext,*a);
    c->append(b);

    CPPUNIT_ASSERT(c->size()==6);
}
コード例 #3
0
ファイル: glmtest.cpp プロジェクト: eddelbuettel/mvabund
int GlmTest::summary(glm *fit)
{
    double lambda;
    unsigned int k;
    unsigned int nRows=tm->nRows, nVars=tm->nVars, nParam=tm->nParam;
    unsigned int mtype = fit->mmRef->model-1;
    PoissonGlm pNull(fit->mmRef), pAlt(fit->mmRef);
    BinGlm binNull(fit->mmRef), binAlt(fit->mmRef);
    NBinGlm nbNull(fit->mmRef), nbAlt(fit->mmRef);
    glm *PtrNull[3] = { &pNull, &nbNull, &binNull };
    glm *PtrAlt[3] = { &pAlt, &nbAlt, &binAlt };
    gsl_vector_view teststat, unitstat;
    gsl_matrix_view L1;
    // To estimate initial Beta from PtrNull->Beta    
//    gsl_vector *ref=gsl_vector_alloc(nParam);
//    gsl_matrix *BetaO=gsl_matrix_alloc(nParam, nVars);

    smryStat = gsl_matrix_alloc((nParam+1), nVars+1);
    Psmry = gsl_matrix_alloc((nParam+1), nVars+1);
    gsl_matrix_set_zero (Psmry);

    // initialize the design matrix for all hypo tests
    GrpMat *GrpXs = (GrpMat *)malloc((nParam+2)*sizeof(GrpMat));
    GrpXs[0].matrix = gsl_matrix_alloc(nRows, nParam);
    gsl_matrix_memcpy(GrpXs[0].matrix, fit->Xref); // the alt X
    GrpXs[1].matrix = gsl_matrix_alloc(nRows, 1); // overall test
    gsl_matrix_set_all (GrpXs[1].matrix, 1.0);
    for (k=2; k<nParam+2; k++) { // significance tests
       GrpXs[k].matrix = gsl_matrix_alloc(nRows, nParam-1);
       subX2(fit->Xref, k-2, GrpXs[k].matrix);
    }
    // Calc test statistics
    if ( tm->test == WALD ) {
        // the overall test compares to mean 
        teststat = gsl_matrix_row(smryStat, 0);
        L1=gsl_matrix_submatrix(L,1,0,nParam-1,nParam);
        lambda=gsl_vector_get(tm->smry_lambda, 0);
        GetR(fit->Res, tm->corr, lambda, Rlambda);
        GeeWald(fit, &L1.matrix, &teststat.vector);
        // the significance test 
        for (k=2; k<nParam+2; k++) {
            teststat = gsl_matrix_row(smryStat, k-1);
            L1 = gsl_matrix_submatrix(L, k-2, 0, 1, nParam);            
            GeeWald(fit, &L1.matrix, &teststat.vector);
        }
    }
    else if (tm->test==SCORE) {
        for (k=1; k<nParam+2; k++) {
            teststat=gsl_matrix_row(smryStat, k-1);
            PtrNull[mtype]->regression(fit->Yref,GrpXs[k].matrix,fit->Oref,NULL); 
            lambda=gsl_vector_get(tm->smry_lambda, k);
            GetR(PtrNull[mtype]->Res, tm->corr, lambda, Rlambda);
            GeeScore(GrpXs[0].matrix, PtrNull[mtype], &teststat.vector);
        }
    }
    else {
        for (k=1; k<nParam+2; k++) {
            teststat=gsl_matrix_row(smryStat, k-1);
            PtrNull[mtype]->regression(fit->Yref,GrpXs[k].matrix,fit->Oref,NULL); 
            GeeLR(fit, PtrNull[mtype], &teststat.vector); // works better
        }
    }    

    // sort id if the unitvaraite test is free step-down
    gsl_permutation **sortid;
    sortid=(gsl_permutation **)malloc((nParam+1)*sizeof(gsl_permutation *));
    for ( k=0; k<(nParam+1); k++ ) {
        teststat = gsl_matrix_row (smryStat, k);
        unitstat = gsl_vector_subvector(&teststat.vector, 1, nVars);
        sortid[k] = gsl_permutation_alloc(nVars);
        gsl_sort_vector_index (sortid[k], &unitstat.vector);
        gsl_permutation_reverse(sortid[k]);  // rearrange in descending order
    }

    if (tm->resamp==MONTECARLO) {
       lambda=gsl_vector_get(tm->smry_lambda,0);
       GetR(fit->Res, tm->corr, lambda, Sigma);
       setMonteCarlo(fit, XBeta, Sigma);
    }

    nSamp=0;
    double *suj, *buj, *puj;
    gsl_matrix *bStat = gsl_matrix_alloc((nParam+1), nVars+1);
    gsl_matrix_set_zero (bStat);
    gsl_matrix *bY = gsl_matrix_alloc(nRows, nVars);
    gsl_matrix *bO = gsl_matrix_alloc(nRows, nVars);
    gsl_matrix_memcpy (bO, fit->Eta);
    double diff, timelast=0;
    clock_t clk_start=clock();

    for ( unsigned int i=0; i<tm->nboot; i++) {        
        if ( tm->resamp==CASEBOOT ) 
             resampSmryCase(fit,bY,GrpXs,bO,i);
        else resampNonCase(fit, bY, i);

        if ( tm->test == WALD ) {
            PtrAlt[mtype]->regression(bY,GrpXs[0].matrix,bO,NULL);
            // the overall test compares to mean 
            teststat = gsl_matrix_row(bStat, 0);
            L1=gsl_matrix_submatrix(L,1,0,nParam-1,nParam);
            lambda=gsl_vector_get(tm->smry_lambda, 0);
            GetR(PtrAlt[mtype]->Res, tm->corr, lambda, Rlambda);
            GeeWald(PtrAlt[mtype], &L1.matrix, &teststat.vector);
            // the significance test 
            for (k=2; k<nParam+2; k++) {
               teststat = gsl_matrix_row(bStat, k-1);
               L1 = gsl_matrix_submatrix(L, k-2, 0, 1, nParam);
               GeeWald(PtrAlt[mtype], &L1.matrix, &teststat.vector);
            }
        }
        else if (tm->test==SCORE) {
            for (k=1; k<nParam+2; k++) {
               teststat=gsl_matrix_row(bStat, k-1);
               PtrNull[mtype]->regression(bY,GrpXs[k].matrix,bO,NULL); 
               lambda=gsl_vector_get(tm->smry_lambda,k);
               GetR(PtrNull[mtype]->Res, tm->corr, lambda, Rlambda);
               GeeScore(GrpXs[0].matrix, PtrNull[mtype], &teststat.vector);
            }
        }
        else {  // use single bAlt estimate works better
            PtrAlt[mtype]->regression(bY,GrpXs[0].matrix,bO,NULL);
            for (k=1; k<nParam+2; k++) {
               teststat=gsl_matrix_row(bStat, k-1);
               PtrNull[mtype]->regression(bY,GrpXs[k].matrix,bO,NULL); 
               GeeLR(PtrAlt[mtype], PtrNull[mtype], &teststat.vector);
            }
        }
        for (k=0; k<(nParam+1); k++) {
           buj = gsl_matrix_ptr (bStat, k, 0);
           suj = gsl_matrix_ptr (smryStat, k, 0);
           puj = gsl_matrix_ptr (Psmry, k, 0);
           if ( *buj >= *suj ) *puj=*puj+1;
           calcAdjustP(tm->punit, nVars, buj+1, suj+1, puj+1, sortid[k]);
        } // end for j loop
        nSamp++;
        // Prompts
        if ((tm->showtime==TRUE)&(i%100==0)) {
           diff=(float)(clock()-clk_start)/(float)CLOCKS_PER_SEC;
           timelast+=(double)diff/60;
           printf("\tResampling run %d finished. Time elapsed: %.2f min ...\n", i, timelast);
           clk_start=clock();
        }
    } // end for i loop

    // ========= Get P-values ========= //        
    if ( tm->punit == FREESTEP ) {
       for (k=0; k<(nParam+1); k++) {
           puj = gsl_matrix_ptr (Psmry, k, 1);
           reinforceP( puj, nVars, sortid[k] );
    }  }
    // p = (#exceeding observed stat + 1)/(#nboot+1)
    gsl_matrix_add_constant (Psmry, 1.0);
    gsl_matrix_scale (Psmry, (double)1.0/(nSamp+1));

    for (k=0; k<nVars; k++) aic[k]=-fit->ll[k]+2*(nParam+1);

    // === release memory ==== //
    PtrAlt[mtype]->releaseGlm();
    if ( tm->test!=WALD ) 
        PtrNull[mtype]->releaseGlm();
    gsl_matrix_free(bStat);
    gsl_matrix_free(bY);
    gsl_matrix_free(bO);

    for (k=0; k<nParam+1; k++) 
       if (sortid[k]!=NULL) gsl_permutation_free(sortid[k]);
    free(sortid);

    if ( GrpXs != NULL ) {
       for ( unsigned int k=0; k<nParam+2; k++ ) 
           if ( GrpXs[k].matrix != NULL )
              gsl_matrix_free (GrpXs[k].matrix);
       free(GrpXs);
    }

    return SUCCESS;
}
コード例 #4
0
ファイル: glmtest.cpp プロジェクト: eddelbuettel/mvabund
int GlmTest::anova(glm *fit, gsl_matrix *isXvarIn) 
{
    // Assume the models have been already sorted (in R)
    Xin = isXvarIn;
    nModels = Xin->size1;
    double *rdf = new double [nModels];
    unsigned int nP, i, j, k;
    unsigned int ID0, ID1, nP0, nP1;
    unsigned int nRows=tm->nRows, nVars=tm->nVars, nParam=tm->nParam;
    unsigned int mtype = fit->mmRef->model-1;

    dfDiff = new unsigned int [nModels-1];
    anovaStat = gsl_matrix_alloc((nModels-1), nVars+1);
    Panova = gsl_matrix_alloc((nModels-1), nVars+1);
    gsl_vector *bStat = gsl_vector_alloc(nVars+1);
    gsl_matrix_set_zero (anovaStat);    
    gsl_matrix_set_zero (Panova);
    gsl_vector_set_zero (bStat);

    PoissonGlm pNull(fit->mmRef), pAlt(fit->mmRef);
    BinGlm binNull(fit->mmRef), binAlt(fit->mmRef);
    NBinGlm nbNull(fit->mmRef), nbAlt(fit->mmRef);
    PoissonGlm pNullb(fit->mmRef), pAltb(fit->mmRef);
    BinGlm binNullb(fit->mmRef), binAltb(fit->mmRef);
    NBinGlm nbNullb(fit->mmRef), nbAltb(fit->mmRef);
    glm *PtrNull[3] = { &pNull, &nbNull, &binNull };
    glm *PtrAlt[3] = { &pAlt, &nbAlt, &binAlt };
    glm *bNull[3] = { &pNullb, &nbNullb, &binNullb };
    glm *bAlt[3] = { &pAltb, &nbAltb, &binAltb };

    double *suj, *buj, *puj;
    gsl_vector_view teststat, unitstat,ref1, ref0; 
    gsl_matrix *X0=NULL, *X1=NULL, *L1=NULL, *tmp1=NULL, *BetaO=NULL;
    gsl_matrix *bO=NULL, *bY=gsl_matrix_alloc(nRows, nVars);
    bO = gsl_matrix_alloc(nRows, nVars);

    gsl_permutation *sortid=NULL;
    if (tm->punit==FREESTEP) sortid = gsl_permutation_alloc(nVars);

    // ======= Fit the (first) Alt model =========//
    for (i=0; i<nModels; i++) {
        nP = 0;
        for (k=0; k<nParam; k++) 
	     if (gsl_matrix_get(Xin,i,k)!=FALSE) nP++;   
        rdf[i] = nRows-nP;
    }

    for (i=1; i<nModels; i++) {       
        // ======= Fit the Null model =========//
        ID0 = i; ID1 = i-1;
        nP0 = nRows - (unsigned int)rdf[ID0];
        nP1 = nRows - (unsigned int)rdf[ID1];

        // Degrees of freedom
        dfDiff[i-1] = nP1 - nP0;

        ref1=gsl_matrix_row(Xin, ID1);
        ref0=gsl_matrix_row(Xin, ID0);
        X0 = gsl_matrix_alloc(nRows, nP0);
        subX(fit->Xref, &ref0.vector, X0);
        X1 = gsl_matrix_alloc(nRows, nP1);
        subX(fit->Xref, &ref1.vector, X1);

	// ======= Get multivariate test statistics =======//
        // Estimate shrinkage parametr only once under H1 
        // See "FW: Doubts R package "mvabund" (12/14/11)
        teststat = gsl_matrix_row(anovaStat, (i-1));
        PtrNull[mtype]->regression(fit->Yref, X0, fit->Oref, NULL); 
        if (tm->test == SCORE) {
           lambda = gsl_vector_get(tm->anova_lambda, ID0);
           GetR(PtrNull[mtype]->Res, tm->corr, lambda, Rlambda);
           GeeScore(X1, PtrNull[mtype], &teststat.vector);
        }
        else if (tm->test==WALD) {
           PtrAlt[mtype]->regression(fit->Yref, X1, fit->Oref, NULL);
           L1 = gsl_matrix_alloc (nP1-nP0, nP1);
           tmp1 = gsl_matrix_alloc (nParam, nP1);
           subX(L, &ref1.vector, tmp1);
           subXrow1(tmp1, &ref0.vector, &ref1.vector, L1);
           lambda = gsl_vector_get(tm->anova_lambda, ID1);
           GetR(PtrAlt[mtype]->Res, tm->corr, lambda, Rlambda);
           GeeWald(PtrAlt[mtype], L1, &teststat.vector);
        }
        else {              
           BetaO = gsl_matrix_alloc(nP1, nVars);
           addXrow2(PtrNull[mtype]->Beta, &ref1.vector, BetaO); 
           PtrAlt[mtype]->regression(fit->Yref, X1, fit->Oref, BetaO);
           GeeLR(PtrAlt[mtype], PtrNull[mtype], &teststat.vector); 
        }

        if (tm->resamp==MONTECARLO) {
            lambda=gsl_vector_get(tm->anova_lambda,ID0);
            GetR(fit->Res, tm->corr, lambda, Sigma);
            setMonteCarlo (PtrNull[mtype], XBeta, Sigma);
        }

	// ======= Get univariate test statistics =======//
        if (tm->punit == FREESTEP) {  
            unitstat=gsl_vector_subvector(&teststat.vector,1,nVars);
            gsl_sort_vector_index (sortid, &unitstat.vector);
            gsl_permutation_reverse(sortid);        
        }

        // ======= Get resampling distribution under H0 ===== //
	nSamp=0;
        double dif, timelast=0;
        clock_t clk_start=clock();
        if (tm->showtime==TRUE)
           printf("Resampling begins for test %d.\n", i);
        for (j=0; j<tm->nboot; j++) {	
//            printf("simu %d :", j);
	    gsl_vector_set_zero (bStat);
	    if ( tm->resamp == CASEBOOT ) {
                resampAnovaCase(PtrAlt[mtype],bY,X1,bO,j);
                subX(X1, &ref0.vector, X0);
            } 
            else {
                resampNonCase(PtrNull[mtype], bY, j);
                gsl_matrix_memcpy(bO, fit->Oref);
            }

            if ( tm->test == WALD ) {
                bAlt[mtype]->regression(bY,X1,bO,NULL); 
                lambda = gsl_vector_get(tm->anova_lambda, ID1);
                GetR(bAlt[mtype]->Res, tm->corr, lambda, Rlambda);
                GeeWald(bAlt[mtype], L1, bStat);
            }
            else if ( tm->test == SCORE ) {
                bNull[mtype]->regression(bY,X0,bO,NULL); 
                lambda = gsl_vector_get(tm->anova_lambda, ID0);
                GetR(bNull[mtype]->Res, tm->corr, lambda, Rlambda);
                GeeScore(X1, bNull[mtype], bStat);
            }
            else {
                bNull[mtype]->regression(bY,X0,bO,NULL); 
                addXrow2(bNull[mtype]->Beta, &ref1.vector, BetaO); 
                bAlt[mtype]->regression(bY,X1,bO,BetaO); 
                GeeLR(bAlt[mtype], bNull[mtype], bStat);                    
            }
            // ----- get multivariate counts ------- //   
           buj = gsl_vector_ptr (bStat,0);
           suj = gsl_matrix_ptr (anovaStat, i-1, 0);
           puj = gsl_matrix_ptr (Panova, i-1, 0);
           if ( *(buj) > (*(suj)-1e-8) ) *puj=*puj+1;
           // ------ get univariate counts ---------//            
           calcAdjustP(tm->punit,nVars,buj+1,suj+1,puj+1,sortid);
	   nSamp++;
           // Prompts
           if ((tm->showtime==TRUE)&(j%100==0)) {
              dif = (float)(clock() - clk_start)/(float)CLOCKS_PER_SEC;
              timelast+=(double)dif/60;
              printf("\tResampling run %d finished. Time elapsed: %.2f minutes...\n", j, timelast);
              clk_start=clock();
           }
        } // end j for loop

       // ========= get p-values ======== //
       if ( tm->punit == FREESTEP) {
          puj = gsl_matrix_ptr (Panova, i-1, 1);
          reinforceP(puj, nVars, sortid);
       }

       if (BetaO!=NULL) gsl_matrix_free(BetaO);
       if (X0!=NULL) gsl_matrix_free(X0);   
       if (X1!=NULL) gsl_matrix_free(X1);   
       if (tm->test == WALD) { 
          if (L1!=NULL) gsl_matrix_free(L1);
          if (tmp1!=NULL) gsl_matrix_free(tmp1);
       }
    } // end i for loop  and test for loop

    // p = (#exceeding observed stat + 1)/(#nboot+1)
    gsl_matrix_add_constant (Panova, 1.0);
    gsl_matrix_scale (Panova, (double)1/(nSamp+1.0));

    bAlt[mtype]->releaseGlm();
    PtrAlt[mtype]->releaseGlm();
    if ( tm->test!=WALD ) {
        bNull[mtype]->releaseGlm();
        PtrNull[mtype]->releaseGlm();
    }
    delete []rdf;
    if (sortid != NULL )
        gsl_permutation_free(sortid);
    gsl_vector_free(bStat);
    gsl_matrix_free(bY);   
    if (bO!=NULL) gsl_matrix_free(bO);   
    
    return SUCCESS;
}
コード例 #5
0
int testPlane() {
	int numErr = 0;

	logMessage(_T("TESTING  -  class GM_3dPlane ...\n\n"));

	// Default constructor, plane must be invalid
	GM_3dPlane p;
	if (p.isValid()) {
		logMessage(_T("\tERROR - Default constructor creates valid plane\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Default constructor creates invalid plane\n"));
	}

	// Constructor (coeff)
	GM_3dPlane p1(getRandomDouble(), getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPlane pNull(0.0, 0.0, 0.0, getRandomDouble());
	if (!p1.isValid() || pNull.isValid()) {
		logMessage(_T("\tERROR - Coeff. constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Coeff. constructor working\n"));
	}

	// Copy constructor
	GM_3dPlane copyPlane(p1);
	if (!copyPlane.isValid() || copyPlane != p1) {
		logMessage(_T("\tERROR - Copy constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Copy constructor working\n"));
	}

	// Constructor (coeff vector)
	double pointsVect[4];
	for (int i = 0 ; i < 4 ; i++) {
		pointsVect[i] = getRandomDouble();
	}
	GM_3dPlane p2(pointsVect);
	if (!p2.isValid()) {
		logMessage(_T("\tERROR - Coeff. vector constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Coeff. vector constructor working\n"));
	}

	// Constructor (points)
	GM_3dPoint pt1(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint pt2(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint pt3(getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dLine ln(getRandomDouble(), getRandomDouble(), getRandomDouble(),getRandomDouble(), getRandomDouble(), getRandomDouble());
	GM_3dPoint ptLn1 = ln.begin();
	GM_3dPoint ptLn2 = ln.center();
	GM_3dPoint ptLn3 = ln.end();
	GM_3dPlane p3(pt1, pt2, pt3);
	GM_3dPlane pLine(ptLn2, ptLn2, ptLn3);
	double distPt1 = pt1.x()*p3[0] + pt1.y()*p3[1] + pt1.z()*p3[2] + p3[3];
	double distPt2 = pt2.x()*p3[0] + pt2.y()*p3[1] + pt2.z()*p3[2] + p3[3];
	double distPt3 = pt3.x()*p3[0] + pt3.y()*p3[1] + pt3.z()*p3[2] + p3[3];
	if (!p3.isValid() || pLine.isValid() || fabs(distPt1) > GM_NULL_TOLERANCE || fabs(distPt2) > GM_NULL_TOLERANCE || fabs(distPt3) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - Points constructor not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Points constructor working\n"));
	}

	// Point distance
	GM_3dPlane p4(getRandomDouble(), getRandomDouble(), getRandomDouble(),getRandomDouble());
	GM_3dPoint checkPoint(getRandomDouble(), getRandomDouble(), getRandomDouble());
	if (fabs(p4[0]) > GM_NULL_TOLERANCE) {
		checkPoint.x(-(checkPoint.y()*p4[1] + checkPoint.z()*p4[2] + p4[3]) / p4[0]);
	}
	else if (fabs(p4[1]) > GM_NULL_TOLERANCE) {
		checkPoint.y(-(checkPoint.x()*p4[0] + checkPoint.z()*p4[2] + p4[3]) / p4[1]);
	}
	else if (fabs(p4[2]) > GM_NULL_TOLERANCE) {
		checkPoint.z(-(checkPoint.x()*p4[0] + checkPoint.y()*p4[1] + p4[3]) / p4[2]);
	}
	else {
		p4.invalidate();
	}
	double checkSignedDist = getRandomDouble();
	double checkDist = fabs(checkSignedDist);
	GM_3dVector p4Norm = p4.normalVector();
	checkPoint = (GM_3dVector)checkPoint + (p4Norm * checkSignedDist);
	GM_3dPoint checkPointOnPlane1;
	GM_3dPoint checkPointOnPlane2;
	double dist = p4.pointDistance(checkPoint);
	double signedDist = p4.pointDistanceSgn(checkPoint);
	double signedDistOnPlane = p4.pointDistanceSgn(checkPoint, checkPointOnPlane1);
	double distOnPlane = p4.pointDistance(checkPoint, checkPointOnPlane2);
	
	distPt1 = checkPointOnPlane1.x()*p4[0] + checkPointOnPlane1.y()*p4[1] + checkPointOnPlane1.z()*p4[2] + p4[3];
	distPt2 = checkPointOnPlane2.x()*p4[0] + checkPointOnPlane2.y()*p4[1] + checkPointOnPlane2.z()*p4[2] + p4[3];
	
	if (!p4.isValid() || !checkPointOnPlane1.isValid() || !checkPointOnPlane2.isValid() ||
		fabs(distPt1) > GM_NULL_TOLERANCE || fabs(distPt2) > GM_NULL_TOLERANCE ||
		fabs(distOnPlane - checkDist) > GM_NULL_TOLERANCE || fabs(signedDistOnPlane - checkSignedDist) > GM_NULL_TOLERANCE ||
		fabs(dist - checkDist) > GM_NULL_TOLERANCE || fabs(signedDist - checkSignedDist) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - Point distance computation not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - Point distance computation working\n"));
	}

	// XY Angle
	double angle = ((((double)rand()) / ((double)RAND_MAX)) * GM_PI) - (GM_PI / 2.0);
	GM_3dVector normVector(angle/* + GM_HALFPI*/);
	normVector.z(normVector.y());
	normVector.y(0.0);
	GM_3dPlane angleP(normVector, GM_3dPoint(getRandomDouble(), getRandomDouble(), getRandomDouble()));
	double checkAngle = angleP.xyAngle();
	if (checkAngle > GM_PI) {
		checkAngle -= 2.0 * GM_PI;
	}
	if (!angleP.isValid() || fabs(angle - checkAngle) > GM_NULL_TOLERANCE) {
		logMessage(_T("\tERROR - XY angle computation not working\n"));
		numErr++;
	}
	else {
		logMessage(_T("\tOK - XY angle computation working\n"));
	}


	return numErr;
}