Changeset 32909
- Timestamp:
- Dec 9, 2011, 3:34:31 AM (15 years ago)
- Location:
- branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/Makefile
r32867 r32909 58 58 $(SRC)/spec.$(ARCH).o \ 59 59 $(SRC)/specpairfit.$(ARCH).o \ 60 $(SRC)/spex2dgas.$(ARCH).o \ 60 61 $(SRC)/mkclusters.$(ARCH).o \ 61 62 $(SRC)/star.$(ARCH).o \ -
branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/init.c
r32867 r32909 46 46 int spec PROTO((int, char **)); 47 47 int specpairfit PROTO((int, char **)); 48 int spex2dgas PROTO((int, char **)); 48 49 int mkclusters PROTO((int, char **)); 49 50 int star PROTO((int, char **)); … … 96 97 {1, "spec", spec, "extract a spectrum"}, 97 98 {1, "specpairfit", specpairfit, "fit spectrum to another spectrum"}, 99 {1, "spex2dgas", spex2dgas, "minimize distances in 2D"}, 98 100 {1, "mkclusters", mkclusters, "group spectra by distance"}, 99 101 {1, "star", star, "star stats at rough coords"}, -
branches/eam_branches/ipp-20111122/Ohana/src/opihi/cmd.astro/spex2dgas.c
r32895 r32909 1 1 # include "astro.h" 2 2 3 /* We have N objects with N(N-1)/2 paired distances. 4 We want to find the locus that best describes the observed distances5 Assume the distances are in a 2D space (though it could be N-D and non-euclidean)3 /* We have N objects with N(N-1)/2 paired distances. We want to find the 2D distribution that 4 best describes the observed distances. Assume the distances are in a 2D space, though in 5 principle it could be N-D or even non-euclidean. 6 6 7 7 Model the points as a gas under pressure. 8 8 9 Start with the realpositions of the objects at some locations in 2D9 Start with the a guess for positions of the objects at some locations in 2D 10 10 11 11 P = (d_now - d_tru) … … 17 17 Move based on dP 18 18 19 */ 19 USAGE: spex2dgas incdex1 index2 distance 20 21 outline: 22 23 * load data 24 * generate the unique objects 25 * determine the max distance needed 26 * place each object in the 2D space 27 28 * iterate: 29 ** calculate dP/dX,dPdY for each object 30 ** move each object proportionally to the pressure gradient 31 32 */ 20 33 21 34 typedef struct { 22 int *friend; // indices for all tested relationships 23 float *dist; // distance for this relationship 24 int Ndist; // number of tested relationships 25 int NDIST; // number of allocated relationships 26 int group; // assigned group 27 int Nfriend; // number of friends brought into group 35 int Nindex; // number of tested relationships 36 int NINDEX; // number of allocated relationships 37 int *index; // indices for all other objects 38 float *Dtgt; // target distance for this relationship 39 float *Dcur; // current distance for this relationship 40 float Xo,Yo; // current X,Y position of this object 41 float dPdX; // pressure in X 42 float dPdY; // pressure in Y 28 43 } Object; 29 30 typedef struct {31 int *entry;32 int Nentry;33 int NENTRY;34 } Group;35 36 static Group *group = NULL;37 static int Ngroup = 0;38 static int NGROUP = 0;39 44 40 45 static Object *object = NULL; … … 42 47 // static int NOBJECT = 0; 43 48 44 void add_to_group (int Nobj, float scale, int Nfriends) { 45 46 int j; 47 48 // fprintf (stderr, "add object %d to group %d\n", Nobj, Ngroup); 49 50 object[Nobj].group = Ngroup; 51 52 // add to this group 53 int N = group[Ngroup].Nentry; 54 group[Ngroup].entry[N] = Nobj; 55 group[Ngroup].Nentry ++; 56 CHECK_REALLOCATE (group[Ngroup].entry, int, group[Ngroup].NENTRY, group[Ngroup].Nentry, 100); 57 58 // add all friends of this object (up to Nfriensd) 59 // friends are already sorted by distance, so we add closest friends first 60 for (j = 0; (object[Nobj].Nfriend < Nfriends) && (j < object[Nobj].Ndist); j++) { 61 if (object[Nobj].dist[j] > scale) continue; 62 63 int Nnew = object[Nobj].friend[j]; 64 65 if (object[Nnew].group != -1) continue; 66 67 // found a friend : 68 object[Nobj].Nfriend ++; 69 add_to_group (Nnew, scale, Nfriends); 70 } 49 void sortfriends (float *X, int *IDX1, int N); 50 51 void get_pressure_gradient (int iObj) { 52 53 int i; 54 55 float dPdX = 0.0; 56 float dPdY = 0.0; 57 58 // only use the first N friends 59 for (i = 0; (i < 10) && (i < object[iObj].Nindex); i++) { 60 int jObj = object[iObj].index[i]; 61 62 // only use the 0th object? 63 // if (jObj != 0) continue; 64 65 66 float Dtgt = object[iObj].Dtgt[i]; 67 float dX = object[jObj].Xo - object[iObj].Xo; 68 float dY = object[jObj].Yo - object[iObj].Yo; 69 float Dcur = hypot(dX,dY); 70 71 // the force law as a function of (Dcur - Dtgt) : if Dcur is too large, dF is negative 72 // float dF = (Dcur < 0.01*Dtgt) ? -100.0 : (Dcur - Dtgt) / Dcur; XXX modified spring constant : too crazy 73 float dF = (Dcur - Dtgt); 74 dF = MIN (100.0, MAX (-100.0, dF)); 75 76 float dPdXi = dF * dX / Dcur; 77 float dPdYi = dF * dY / Dcur; 78 79 // if we are too close, then dX/Dcur is too ill-defined, just jump away 80 if (Dcur < 0.01*Dtgt) { 81 dPdXi = drand48() - 0.5; 82 dPdYi = drand48() - 0.5; 83 } 84 85 // fprintf (stderr, "Dcur,Dtgt : %f %f : dX,dY,dP : %f %f : %f : %f %f\n", Dcur, Dtgt, dX, dY, dF, dPdXi, dPdYi); 86 dPdX += dPdXi; 87 dPdY += dPdYi; 88 } 89 object[iObj].dPdX = dPdX; 90 object[iObj].dPdY = dPdY; 91 71 92 return; 72 93 } 73 94 74 void sortvecset (opihi_flt *X, opihi_int *IDX1, opihi_int *IDX2, int N) { 75 76 # define SWAPFUNC(A,B){ opihi_flt tmp; opihi_int itmp; \ 77 tmp = X[A]; X[A] = X[B]; X[B] = tmp; \ 78 itmp = IDX1[A]; IDX1[A] = IDX1[B]; IDX1[B] = itmp; \ 79 itmp = IDX2[A]; IDX2[A] = IDX2[B]; IDX2[B] = itmp; \ 95 void move_object (int iObj) { 96 97 object[iObj].Xo += 0.25*object[iObj].dPdX; 98 object[iObj].Yo += 0.25*object[iObj].dPdY; 99 return; 80 100 } 81 101 82 # define COMPARE(A,B)(X[A] < X[B]) 83 84 OHANA_SORT (N, COMPARE, SWAPFUNC); 85 86 # undef SWAPFUNC 87 # undef COMPARE 88 89 } 90 91 void sortfriends (float *X, int *IDX1, int N) { 92 93 # define SWAPFUNC(A,B){ float tmp; int itmp; \ 94 tmp = X[A]; X[A] = X[B]; X[B] = tmp; \ 95 itmp = IDX1[A]; IDX1[A] = IDX1[B]; IDX1[B] = itmp; \ 96 } 97 98 # define COMPARE(A,B)(X[A] < X[B]) 99 100 OHANA_SORT (N, COMPARE, SWAPFUNC); 101 102 # undef SWAPFUNC 103 # undef COMPARE 104 105 } 106 107 int mkclusters (int argc, char **argv) { 108 109 int i, j; 102 int spex2dgas (int argc, char **argv) { 103 104 int i, iter; 110 105 Vector *index1, *index2, *distance; 111 106 112 if (argc != 6) goto usage; 107 // init random numbers 108 long A, B; 109 A = time(NULL); 110 for (B = 0; A == time(NULL); B++); 111 srand48(B); 112 113 if (argc != 5) goto usage; 113 114 114 115 if ((index1 = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) goto escape; 115 116 if ((index2 = SelectVector (argv[2], OLDVECTOR, TRUE)) == NULL) goto escape; 116 117 if ((distance = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) goto escape; 117 float scale = atof (argv[4]); 118 int Nfriends = atoi (argv[5]); 119 118 int Niter = atoi (argv[4]); 120 119 // XXX enforce matching lengths on the three vectors 121 120 … … 123 122 CastVector (index2, OPIHI_INT); 124 123 124 // how many objects do we have? 125 125 Nobject = 0; 126 126 for (i = 0; i < index1->Nelements; i++) { … … 133 133 ALLOCATE (object, Object, Nobject); 134 134 for (i = 0; i < Nobject; i++) { 135 ALLOCATE (object[i]. friend, int, Nobject);136 memset (object[i]. friend, 0, Nobject*sizeof(int));137 ALLOCATE (object[i]. dist, float, Nobject);138 memset (object[i]. dist, 0, Nobject*sizeof(float));139 object[i].NDIST = Nobject;140 object[i].Ndist = 0;141 object[i]. group = -1; // unassigned142 object[i].N friend = 0; // no friends yet135 ALLOCATE (object[i].index, int, Nobject); 136 memset (object[i].index, 0, Nobject*sizeof(int)); 137 ALLOCATE (object[i].Dtgt, float, Nobject); 138 memset (object[i].Dtgt, 0, Nobject*sizeof(float)); 139 ALLOCATE (object[i].Dcur, float, Nobject); 140 memset (object[i].Dcur, 0, Nobject*sizeof(float)); 141 object[i].NINDEX = Nobject; 142 object[i].Nindex = 0; 143 143 } 144 144 … … 147 147 for (i = 0; i < index1->Nelements; i++) { 148 148 int N, m; 149 149 150 N = index1->elements.Int[i]; 150 151 if (N >= Nobject) abort(); 151 m = object[N].Ndist; 152 object[N].friend[m] = index2->elements.Int[i]; 153 object[N].dist[m] = distance->elements.Flt[i]; 154 object[N].Ndist ++; 155 if (object[N].Ndist == object[N].NDIST) { 156 object[N].NDIST += 100; 157 REALLOCATE (object[N].dist, float, object[N].NDIST); 158 REALLOCATE (object[N].friend, int, object[N].NDIST); 152 m = object[N].Nindex; 153 object[N].index[m] = index2->elements.Int[i]; 154 object[N].Dtgt[m] = distance->elements.Flt[i]; 155 object[N].Dcur[m] = 0.0; 156 object[N].Nindex ++; 157 if (object[N].Nindex == object[N].NINDEX) { 158 object[N].NINDEX += 100; 159 REALLOCATE (object[N].Dtgt, float, object[N].NINDEX); 160 REALLOCATE (object[N].Dcur, float, object[N].NINDEX); 161 REALLOCATE (object[N].index, int, object[N].NINDEX); 159 162 } 160 163 161 164 N = index2->elements.Int[i]; 162 165 if (N >= Nobject) abort(); 163 m = object[N].Ndist; 164 object[N].friend[m] = index1->elements.Int[i]; 165 object[N].dist[m] = distance->elements.Flt[i]; 166 object[N].Ndist ++; 167 if (object[N].Ndist == object[N].NDIST) { 168 object[N].NDIST += 100; 169 REALLOCATE (object[N].dist, float, object[N].NDIST); 170 REALLOCATE (object[N].friend, int, object[N].NDIST); 171 } 172 } 173 174 for (i = 0; i < Nobject; i++) { 175 sortfriends (object[i].dist, object[i].friend, object[i].Ndist); 176 } 177 178 // generate the set of groups. each group is a list of friends and their friends 179 Ngroup = 0; 180 NGROUP = Nobject; 181 ALLOCATE (group, Group, NGROUP); 182 for (i = 0; i < NGROUP; i++) { 183 group[i].Nentry = 0; 184 group[i].NENTRY = 100; 185 ALLOCATE (group[i].entry, int, group[i].NENTRY); 186 } 187 188 sortvecset (distance->elements.Flt, index1->elements.Int, index2->elements.Int, index2->Nelements); 189 166 m = object[N].Nindex; 167 object[N].index[m] = index1->elements.Int[i]; 168 object[N].Dtgt[m] = distance->elements.Flt[i]; 169 object[N].Dcur[m] = 0.0; 170 object[N].Nindex ++; 171 if (object[N].Nindex == object[N].NINDEX) { 172 object[N].NINDEX += 100; 173 REALLOCATE (object[N].Dtgt, float, object[N].NINDEX); 174 REALLOCATE (object[N].Dcur, float, object[N].NINDEX); 175 REALLOCATE (object[N].index, int, object[N].NINDEX); 176 } 177 } 178 179 for (i = 0; i < Nobject; i++) { 180 // sort so closest friends are first 181 sortfriends (object[i].Dtgt, object[i].index, object[i].Nindex); 182 } 183 184 // find and save the max distance 185 float Dmax = 0; 190 186 for (i = 0; i < distance->Nelements; i++) { 191 int Nnew; 192 int found; 193 194 if (distance->elements.Flt[i] > scale) continue; 195 196 found = FALSE; 197 198 Nnew = index1->elements.Int[i]; 199 if (object[Nnew].group == -1) { 200 add_to_group (Nnew, scale, Nfriends); 201 // fprintf (stderr, "new group %d part 1 with %d elements\n", Ngroup, group[Ngroup].Nentry); 202 found = TRUE; 203 } 204 205 Nnew = index2->elements.Int[i]; 206 if (object[Nnew].group == -1) { 207 add_to_group (Nnew, scale, Nfriends); 208 // fprintf (stderr, "new group %d part 1 with %d elements\n", Ngroup, group[Ngroup].Nentry); 209 found = TRUE; 210 } 211 212 if (found) { 213 fprintf (stderr, "group %d with %d elements\n", Ngroup, group[Ngroup].Nentry); 214 Ngroup ++; 215 if (Ngroup >= NGROUP) abort(); 216 } 217 } 218 219 if (1) { 220 int Nmiss = 0; 187 Dmax = MAX (Dmax, distance->elements.Flt[i]); 188 } 189 190 // place the objects at the initial guess locations 191 // XXX let's try with just a simple grid dividing up the max range 192 // int Ngrid = sqrt(Nobject); 193 // float dgrid = 1.5 * Dmax / Ngrid; // XXX remove the fudge factor 194 for (i = 0; i < Nobject; i++) { 195 // object[i].Xo = dgrid * (int) (i % Ngrid); 196 // object[i].Yo = dgrid * (int) (i / Ngrid); 197 object[i].Xo = Dmax*drand48(); 198 object[i].Yo = Dmax*drand48(); 199 object[i].dPdX = 0.0; 200 object[i].dPdY = 0.0; 201 } 202 203 for (iter = 0; iter < Niter; iter ++) { 204 fprintf (stderr, "iter %d\n", iter); 205 206 // measure (dP/dX),(dP/dY) for all objects 221 207 for (i = 0; i < Nobject; i++) { 222 if (object[i].group > -1) continue; 223 Nmiss ++; 224 // fprintf (stderr, "object %d not assigned\n", i); 225 for (j = 0; FALSE && j < object[i].Ndist; j++) { 226 fprintf (stderr, "friend %d, dist %f\n", object[i].friend[j], object[i].dist[j]); 227 } 228 } 229 fprintf (stderr, "%d objects not assigned\n", Nmiss); 230 } 208 get_pressure_gradient (i); 209 move_object (i); 210 } 211 212 // given (dP/dX),(dP/dY), move each object 213 // for (i = 0; i < Nobject; i++) { 214 // } 215 } 216 217 // save the result 218 FILE *output = fopen ("output.dat", "w"); 219 for (i = 0; i < Nobject; i++) { 220 fprintf (output, "%f %f : %f %f\n", object[i].Xo, object[i].Yo, object[i].dPdX, object[i].dPdY); 221 } 222 fclose (output); 231 223 232 224 return TRUE; 233 225 234 escape:226 escape: 235 227 gprint (GP_ERR, "invalid vector\n"); 236 228 return FALSE;
Note:
See TracChangeset
for help on using the changeset viewer.
