IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25190


Ignore:
Timestamp:
Aug 25, 2009, 2:55:05 PM (17 years ago)
Author:
Paul Price
Message:

Testing spherical coordinates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/pap_mops/psLib/test/types/tap_psTree.c

    r23259 r25190  
    33#include "pstap.h"
    44
    5 #define NUM 10000                       // Number of points
     5#define NUM 1000000                      // Number of points
     6#define SPHERICAL_DISTANCE 3.0          // Distance of interest for spherical test
    67
    78int main(int argc, char *argv[])
    89{
    910    psLibInit(NULL);
    10     plan_tests(6);
     11    plan_tests(13);
    1112
     13    // Euclidean geometry: 6 tests
    1214    {
    1315        psMemId id = psMemGetId();
     
    2325        psFree(rng);
    2426
    25         psTree *tree = psTreePlant(2, 2, x, y);
     27        psTree *tree = psTreePlant(2, 2, PS_TREE_EUCLIDEAN, x, y);
    2628
    2729        ok(tree, "Tree planted");
     
    3537            long closeIndex = psTreeNearest(tree, coords);
    3638            psFree(coords);
    37             ok(closeIndex >= 0 && closeIndex < tree->numNodes, "found point: %ld", closeIndex);
     39            ok(closeIndex >= 0 && closeIndex < tree->numNodes, "found closest point: %ld", closeIndex);
    3840
    3941            long bestIndex = -1;
     
    6870    }
    6971
     72    // Spherical geometry: 7 tests
     73    {
     74        psMemId id = psMemGetId();
     75
     76        psVector *ra = psVectorAlloc(NUM, PS_TYPE_F64);
     77        psVector *dec = psVectorAlloc(NUM, PS_TYPE_F64);
     78
     79        psRandom *rng = psRandomAllocSpecific(PS_RANDOM_TAUS, 0);
     80        for (int i = 0; i < NUM; i++) {
     81            // Using http://mathworld.wolfram.com/SpherePointPicking.html
     82            ra->data.F64[i] = psRandomUniform(rng);
     83            dec->data.F64[i] = acos(2.0 * psRandomUniform(rng) - 1.0) - M_PI_2;
     84        }
     85
     86        psTree *tree = psTreePlant(2, 2, PS_TREE_SPHERICAL, ra, dec);
     87
     88        ok(tree, "Tree planted");
     89        skip_start(!tree, 4, "tree died");
     90        {
     91            //            psTreePrint(stderr, tree);
     92
     93            psVector *coords = psVectorAlloc(2, PS_TYPE_F64);
     94            coords->data.F64[0] = psRandomUniform(rng);
     95            coords->data.F64[1] = acos(2.0 * psRandomUniform(rng) - 1.0) - M_PI_2;
     96
     97            psVector *indices = psTreeAllWithin(tree, coords, DEG_TO_RAD(SPHERICAL_DISTANCE));
     98            ok(indices && indices->type.type == PS_TYPE_S64, "got list of indices (%ld points)", indices->n);
     99            long closeIndex = psTreeNearest(tree, coords);
     100            ok(closeIndex >= 0 && closeIndex < tree->numNodes, "found closest point: %ld", closeIndex);
     101
     102            ok(psVectorSortInPlace(indices), "sorted indices");
     103
     104            bool allgood = true;        // All points in the appropriate place?
     105            double bestDistance = INFINITY; // Distance to best point
     106            long bestIndex = -1;        // Index of best point
     107            for (long i = 0, j = 0; i < NUM; i++) {
     108#if 1
     109                // Traditional formula
     110                double dist = acos(sin(coords->data.F64[1]) * sin(dec->data.F64[i]) +
     111                                   cos(coords->data.F64[1]) * cos(dec->data.F64[i]) *
     112                                   cos(coords->data.F64[0] - ra->data.F64[i]));
     113#else
     114                // Haversine formula: used in psTree
     115                double dphi = coords->data.F64[1] - dec->data.F64[i];
     116                double sindphi = sin(dphi/2.0);
     117                double dlambda = coords->data.F64[0] - ra->data.F64[i];
     118                double sindlambda = sin(dlambda/2.0);
     119                double dist = 2.0 * asin(sqrt(PS_SQR(sindphi) +
     120                                              cos(coords->data.F64[1]) * cos(dec->data.F64[i]) *
     121                                              PS_SQR(sindlambda)));
     122#endif
     123                                              if (dist < bestDistance) {
     124                    bestDistance = dist;
     125                    bestIndex = i;
     126                }
     127                if (i == indices->data.S64[j]) {
     128                    j++;
     129                    if (dist > DEG_TO_RAD(SPHERICAL_DISTANCE)) {
     130                        diag("%ld is in the list, but shouldn't be (%lf vs %lf)",
     131                             i, RAD_TO_DEG(dist), SPHERICAL_DISTANCE);
     132                        allgood = false;
     133                    }
     134                } else if (dist <= DEG_TO_RAD(SPHERICAL_DISTANCE)) {
     135                    diag("%ld is not in the list, but should be (%lf vs %lf)",
     136                         i, RAD_TO_DEG(dist), SPHERICAL_DISTANCE);
     137                    allgood = false;
     138                }
     139            }
     140            ok(allgood, "list is acurate");
     141            ok(bestIndex == closeIndex, "correct point: %ld vs %ld", closeIndex, bestIndex);
     142
     143            psFree(coords);
     144            psFree(indices);
     145
     146        }
     147        skip_end();
     148
     149        psFree(rng);
     150        psFree(tree);
     151        psFree(ra);
     152        psFree(dec);
     153
     154        ok(!psMemCheckLeaks(id, NULL, NULL, false), "no memory leaks");
     155    }
     156
    70157    psLibFinalize();
    71158}
Note: See TracChangeset for help on using the changeset viewer.