home *** CD-ROM | disk | FTP | other *** search
/ Los Alamos National Laboratory / LANL_CD.ISO / software / compres / src / make_tre.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  6KB  |  224 lines

  1. /****************************************************************
  2.  
  3. COPYRIGHT (C) 1992 UNIVERSITY OF CALIFORNIA
  4.  
  5. ***************************************************************/
  6.  
  7. #define BUCKETSIZE 16
  8. #define NULL 0
  9. #include <math.h>
  10. #include "kdnode.h"
  11.  
  12. int *TreeList;
  13.  
  14. /****************************************************************/
  15.  
  16. struct KDTreeNode *MakeMedianTree(k, ncv, cbook)
  17. int k, ncv;
  18. float *cbook;
  19. {
  20.     struct KDTreeNode *TempNode;
  21.     int i;
  22.     float **Vecs;
  23.     void MedianPartition();
  24.  
  25.     conv2d(cbook, &Vecs, ncv, k);
  26.  
  27.     if(!(TreeList = (int*)malloc(ncv * sizeof(int)))) {
  28.         printf("ERROR: Not enough room for malloc\n");
  29.         exit(-1);
  30.     }
  31.  
  32.     for (i = 0; i < ncv; i++)
  33.         TreeList[i] = i;
  34.  
  35.     if(!(TempNode = (struct KDTreeNode *)malloc(sizeof(struct KDTreeNode)))) {
  36.         printf("ERROR: Not enough room for malloc\n");
  37.         exit(-1);
  38.     }
  39.  
  40.     MedianPartition(TempNode, TreeList, ncv, k, ncv, Vecs);
  41.     return(TempNode);
  42. }
  43.  
  44. /****************************************************************/
  45.  
  46. void MedianPartition(Node, ListStart, ListSize, k, ncv, Vecs)
  47. struct KDTreeNode *Node;
  48. int *ListStart, ListSize, k, ncv;
  49. float **Vecs;
  50. {
  51.     float Median, Val, Vari, MaxVari, StDev();
  52.     int Axis, Middle, *LList, *RList, LSize, RSize, MaxAxis;
  53.     struct KDTreeNode *LTemp, *RTemp;
  54.     void QuickSort();
  55.  
  56.     if (ListSize < BUCKETSIZE)  {
  57.         Node->Left = NULL;
  58.         Node->Right = NULL;
  59.         Node->List = ListStart;
  60.         Node->ListSize = ListSize;
  61.         Node->KeyIndex = 0;
  62.         Node->PartitionValue = 0;
  63.         return;
  64.     }
  65.  
  66.     else  {
  67.         for (Axis = 0; Axis < k; Axis++)  {
  68.             Vari = StDev (ListStart, ListSize, Axis, Vecs);
  69.                 if ((Axis == 0) || (Vari > MaxVari)) {
  70.                     MaxVari = Vari;
  71.                     MaxAxis = Axis;
  72.         }
  73.     }
  74.  
  75.     Axis = MaxAxis;
  76.  
  77. /* Find the median by sorting the list and taking the middle element */
  78.  
  79.     QuickSort(ListStart, 0, (ListSize - 1), Vecs, Axis);
  80.     Middle = (ListSize / 2);
  81.     Median = Vecs[Axis][ListStart[Middle]];
  82.  
  83. /* Partition the array into two lists */
  84.  
  85. /* Move the dividing point up to the last occurrence of Median */
  86.  
  87.     for ( ; Middle < ListSize; Middle++)  {
  88.         Val = Vecs[Axis][ListStart[Middle]];
  89.         if (Val != Median)
  90.             break;
  91.     }
  92.     Middle--;
  93.  
  94. /* Determine the size of each sublist */
  95.  
  96.     LSize = Middle + 1;
  97.     RSize = ListSize - LSize;
  98.  
  99.   /* Check to see if either sublist is of size 0: if so, make this a
  100.    * terminal node. */
  101.  
  102.     if ((LSize == 0) || (RSize == 0))  {
  103.         printf("DUMB CONDITION\n");
  104.         Node->Left = NULL;
  105.         Node->Right = NULL;
  106.         Node->List = ListStart;
  107.         Node->ListSize = ListSize;
  108.         Node->KeyIndex = 0;
  109.         Node->PartitionValue = 0;
  110.         return;
  111.     }
  112.  
  113. /* Get pointers to sublists */
  114.     LList = ListStart;
  115.     RList = &ListStart[Middle + 1];
  116.  
  117. /* Create subnodes */
  118.     LTemp = (struct KDTreeNode*)malloc(sizeof(struct KDTreeNode));
  119.     RTemp = (struct KDTreeNode*)malloc(sizeof(struct KDTreeNode));
  120.     if(!LTemp || !RTemp) {
  121.         printf("ERROR: Not enough room for malloc\n");
  122.         exit(-1);
  123.     }
  124.  
  125. /* Set values for this node */
  126.     Node->Left = LTemp;
  127.     Node->Right = RTemp;
  128.     Node->List = NULL;
  129.     Node->ListSize = 0;
  130.     Node->KeyIndex = Axis;
  131.     Node->PartitionValue = Median;
  132.  
  133. /* Partition the subnodes */
  134.     MedianPartition (LTemp, LList, LSize, k, ncv, Vecs);
  135.     MedianPartition (RTemp, RList, RSize, k, ncv, Vecs);
  136.  
  137.     }
  138. }
  139.  
  140. /****************************************************************/
  141.  
  142. /* Does a Quicksort of a linear array.  The numbers in the array are index
  143.  * numbers for the Vecs[][] array and the datum to sort by is the position
  144.  * of each vector along axis number Axis. */
  145.  
  146. void QuickSort (Array, Start, Finish, Vecs, Axis)
  147. int *Array, Start, Finish, Axis;
  148. float **Vecs;
  149. {
  150.     int Left, Right, Temp;
  151.     float StarterValue;
  152.  
  153.     Left = Start;
  154.     Right = Finish;
  155.     StarterValue = Vecs[Axis][Array[Start]];
  156.  
  157.     while (Left < Right)  {
  158.  
  159.         while (Vecs[Axis][Array[Left]] < StarterValue)
  160.             Left++;
  161.         while (Vecs[Axis][Array[Right]] > StarterValue)
  162.             Right--;
  163.         if (Left <= Right)  {
  164.             Temp = Array[Left];
  165.             Array[Left++] = Array[Right];
  166.             Array[Right--] = Temp;
  167.     }
  168.  
  169. }
  170.  
  171.     if (Start < Right)
  172.         QuickSort (Array, Start, Right, Vecs, Axis);
  173.     if (Left < Finish)
  174.         QuickSort (Array, Left, Finish, Vecs, Axis);
  175.  
  176. }
  177.  
  178. /****************************************************************/
  179.  
  180. /* Accepts a list of vector indices Array and calculates the standard deviation
  181.  * of the indicated vectors in Vecs along the axis Axis. */
  182.  
  183. float StDev (Array, ArraySize, Axis, Vecs)
  184. int *Array, ArraySize, Axis;
  185. float **Vecs;
  186. {
  187.     int Index, i;
  188.     float Mean, Var, xx;
  189.  
  190.     Mean = 0.;
  191.     for (i = 0; i < ArraySize; i++)  {
  192.         Index = Array[i];
  193.         Mean += Vecs[Axis][Index];
  194.     }
  195.     Mean /= (float)ArraySize;
  196.  
  197.     xx = 0.;
  198.     for (i = 0; i < ArraySize; i++)  {
  199.         Index = Array[i];
  200.         Var = Vecs[Axis][Index] - Mean;
  201.         if (Var < 0)
  202.             Var = -Var;
  203.         xx += Var;
  204.     }
  205.     xx /= (float) ArraySize;
  206.  
  207.     return xx;
  208. }
  209.  
  210. /****************************************************************/
  211.  
  212. conv2d(cbook, Vecs, ncv, k)
  213. int ncv, k;
  214. float *cbook, ***Vecs;
  215. {
  216.     int i, j;
  217.     float **matrix();
  218.  
  219.     *Vecs = matrix(k, ncv);
  220.     for(i = 0; i < ncv; i++)
  221.         for(j = 0; j < k; j++)
  222.             (*Vecs)[j][i] = *cbook++;
  223. }
  224.