00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "digcola.h"
00018 #ifdef DIGCOLA
00019 #include "kkutils.h"
00020 #include "matrix_ops.h"
00021 #include "conjgrad.h"
00022
00023 static void
00024 standardize(double* orthog, int nvtxs)
00025 {
00026 double len, avg = 0;
00027 int i;
00028 for (i=0; i<nvtxs; i++)
00029 avg+=orthog[i];
00030 avg/=nvtxs;
00031
00032
00033 for (i=0; i<nvtxs; i++)
00034 orthog[i]-=avg;
00035
00036
00037 len = norm(orthog, 0, nvtxs-1);
00038 vecscale(orthog, 0, nvtxs-1, 1.0 / len, orthog);
00039 }
00040
00041 static void
00042 mat_mult_vec_orthog(float** mat, int dim1, int dim2, double* vec,
00043 double* result, double* orthog)
00044 {
00045
00046 int i,j;
00047 double sum;
00048
00049 for (i=0; i<dim1; i++) {
00050 sum=0;
00051 for (j=0; j<dim2; j++) {
00052 sum += mat[i][j]*vec[j];
00053 }
00054 result[i]=sum;
00055 }
00056 if (orthog!=NULL) {
00057 double alpha=-dot(result,0,dim1-1,orthog);
00058 scadd(result, 0, dim1-1, alpha, orthog);
00059 }
00060 }
00061
00062 static void
00063 power_iteration_orthog(float** square_mat, int n, int neigs,
00064 double** eigs, double* evals, double* orthog, double p_iteration_threshold)
00065 {
00066
00067
00068
00069
00070 int i,j;
00071 double *tmp_vec = N_GNEW(n, double);
00072 double *last_vec = N_GNEW(n, double);
00073 double *curr_vector;
00074 double len;
00075 double angle;
00076 double alpha;
00077 int iteration;
00078 int largest_index;
00079 double largest_eval;
00080
00081 double tol=1-p_iteration_threshold;
00082
00083 if (neigs>=n) {
00084 neigs=n;
00085 }
00086
00087 for (i=0; i<neigs; i++) {
00088 curr_vector = eigs[i];
00089
00090 choose:
00091 for (j=0; j<n; j++) {
00092 curr_vector[j] = rand()%100;
00093 }
00094
00095 if (orthog!=NULL) {
00096 alpha=-dot(orthog,0,n-1,curr_vector);
00097 scadd(curr_vector, 0, n-1, alpha, orthog);
00098 }
00099
00100 for (j=0; j<i; j++) {
00101 alpha = -dot(eigs[j], 0, n-1, curr_vector);
00102 scadd(curr_vector, 0, n-1, alpha, eigs[j]);
00103 }
00104 len = norm(curr_vector, 0, n-1);
00105 if (len<1e-10) {
00106
00107 goto choose;
00108 }
00109 vecscale(curr_vector, 0, n-1, 1.0 / len, curr_vector);
00110 iteration=0;
00111 do {
00112 iteration++;
00113 cpvec(last_vec,0,n-1,curr_vector);
00114
00115 mat_mult_vec_orthog(square_mat,n,n,curr_vector,tmp_vec,orthog);
00116 cpvec(curr_vector,0,n-1,tmp_vec);
00117
00118
00119 for (j=0; j<i; j++) {
00120 alpha = -dot(eigs[j], 0, n-1, curr_vector);
00121 scadd(curr_vector, 0, n-1, alpha, eigs[j]);
00122 }
00123 len = norm(curr_vector, 0, n-1);
00124 if (len<1e-10) {
00125
00126
00127
00128 goto exit;
00129 }
00130
00131 vecscale(curr_vector, 0, n-1, 1.0 / len, curr_vector);
00132 angle = dot(curr_vector, 0, n-1, last_vec);
00133 } while (fabs(angle)<tol);
00134
00135
00136
00137 evals[i]=angle*len;
00138 }
00139 exit:
00140 for (; i<neigs; i++) {
00141
00142
00143
00144
00145 curr_vector = eigs[i];
00146
00147 for (j=0; j<n; j++)
00148 curr_vector[j] = rand()%100;
00149
00150 for (j=0; j<i; j++) {
00151 alpha = -dot(eigs[j], 0, n-1, curr_vector);
00152 scadd(curr_vector, 0, n-1, alpha, eigs[j]);
00153 }
00154 len = norm(curr_vector, 0, n-1);
00155 vecscale(curr_vector, 0, n-1, 1.0 / len, curr_vector);
00156 evals[i]=0;
00157
00158 }
00159
00160
00161 for (i=0; i<neigs-1; i++) {
00162 largest_index=i;
00163 largest_eval=evals[largest_index];
00164 for (j=i+1; j<neigs; j++) {
00165 if (largest_eval<evals[j]) {
00166 largest_index=j;
00167 largest_eval=evals[largest_index];
00168 }
00169 }
00170 if (largest_index!=i) {
00171 cpvec(tmp_vec,0,n-1,eigs[i]);
00172 cpvec(eigs[i],0,n-1,eigs[largest_index]);
00173 cpvec(eigs[largest_index],0,n-1,tmp_vec);
00174
00175 evals[largest_index]=evals[i];
00176 evals[i]=largest_eval;
00177 }
00178 }
00179
00180 free (tmp_vec); free (last_vec);
00181
00182 }
00183
00184 static float*
00185 compute_avgs(DistType** Dij, int n, float* all_avg)
00186 {
00187 float* row_avg = N_GNEW(n, float);
00188 int i,j;
00189 double sum=0, sum_row;
00190
00191 for (i=0; i<n; i++) {
00192 sum_row=0;
00193 for (j=0; j<n; j++) {
00194 sum+=(double)Dij[i][j]*(double)Dij[i][j];
00195 sum_row+=(double)Dij[i][j]*(double)Dij[i][j];
00196 }
00197 row_avg[i]=(float)sum_row/n;
00198 }
00199 *all_avg=(float)sum/(n*n);
00200 return row_avg;
00201 }
00202
00203 static float**
00204 compute_Bij(DistType** Dij, int n)
00205 {
00206 int i,j;
00207 float* storage = N_GNEW(n*n,float);
00208 float** Bij = N_GNEW(n, float*);
00209 float* row_avg;
00210 float all_avg;
00211
00212 for (i=0; i<n; i++)
00213 Bij[i] = storage+i*n;
00214
00215 row_avg = compute_avgs(Dij, n, &all_avg);
00216 for (i=0; i<n; i++) {
00217 for (j=0; j<=i; j++) {
00218 Bij[i][j]=-(float)Dij[i][j]*Dij[i][j]+row_avg[i]+row_avg[j]-all_avg;
00219 Bij[j][i]=Bij[i][j];
00220 }
00221 }
00222 free (row_avg);
00223 return Bij;
00224 }
00225
00226 static void
00227 CMDS_orthog(vtx_data* graph, int n, int dim, double** eigs, double tol,
00228 double* orthog, DistType** Dij)
00229 {
00230 int i,j;
00231 float** Bij = compute_Bij(Dij, n);
00232 double* evals= N_GNEW(dim, double);
00233
00234 double * orthog_aux = NULL;
00235 if (orthog!=NULL) {
00236 orthog_aux = N_GNEW(n, double);
00237 for (i=0; i<n; i++) {
00238 orthog_aux[i]=orthog[i];
00239 }
00240 standardize(orthog_aux,n);
00241 }
00242 power_iteration_orthog(Bij, n, dim, eigs, evals, orthog_aux, tol);
00243
00244 for (i=0; i<dim; i++) {
00245 for (j=0; j<n; j++) {
00246 eigs[i][j]*=sqrt(fabs(evals[i]));
00247 }
00248 }
00249 free (Bij[0]); free (Bij);
00250 free (evals); free (orthog_aux);
00251 }
00252
00253 #define SCALE_FACTOR 256
00254
00255 void IMDS_given_dim(vtx_data* graph, int n, double* given_coords,
00256 double* new_coords, double conj_tol)
00257 {
00258 int iterations2;
00259 int i,j;
00260 DistType** Dij;
00261 float* f_storage = NULL;
00262 double* x = given_coords;
00263 double uniLength;
00264 double* orthog_aux = NULL;
00265 double* y = new_coords;
00266 float** lap = N_GNEW(n, float*);
00267 float degree;
00268 double pos_i;
00269 double* balance = N_GNEW(n, double);
00270 double b;
00271 boolean converged;
00272
00273 #if 0
00274 iterations1=mat_mult_count1=0;
00275 #endif
00276
00277 Dij = compute_apsp(graph, n);
00278
00279
00280
00281
00282 for (i=0; i<n; i++)
00283 for (j=0; j<n; j++)
00284 Dij[i][j]*=SCALE_FACTOR;
00285
00286 assert(x!=NULL);
00287 {
00288 double sum1, sum2;
00289
00290 orthog_aux = N_GNEW(n, double);
00291 for (i=0; i<n; i++) {
00292 orthog_aux[i]=x[i];
00293 }
00294 standardize(orthog_aux,n);
00295
00296 for (sum1=sum2=0,i=1; i<n; i++) {
00297 for (j=0; j<i; j++) {
00298 sum1+=1.0/(Dij[i][j])*fabs(x[i]-x[j]);
00299 sum2+=1.0/(Dij[i][j]*Dij[i][j])*fabs(x[i]-x[j])*fabs(x[i]-x[j]);
00300 }
00301 }
00302 uniLength=sum1/sum2;
00303 for (i=0; i<n; i++)
00304 x[i]*=uniLength;
00305 }
00306
00307
00308 CMDS_orthog(graph, n, 1, &y, conj_tol, x, Dij);
00309
00310
00311 f_storage = N_GNEW(n*n, float);
00312
00313 for (i=0; i<n; i++) {
00314 lap[i]=f_storage+i*n;
00315 degree=0;
00316 for (j=0; j<n; j++) {
00317 if (j==i)
00318 continue;
00319 degree-=lap[i][j]=-1.0f/((float)Dij[i][j]*(float)Dij[i][j]);
00320
00321 }
00322 lap[i][i]=degree;
00323 }
00324
00325
00326
00327
00328 {
00329 double diff;
00330 for (i=1; i<n; i++) {
00331 pos_i=x[i];
00332 for (j=0; j<i; j++) {
00333 diff=(double)Dij[i][j]*(double)Dij[i][j]-(pos_i-x[j])*(pos_i-x[j]);
00334 Dij[i][j]=Dij[j][i]=diff>0 ? (DistType)sqrt(diff) : 0;
00335 }
00336 }
00337 }
00338
00339
00340 for (i=0; i<n; i++) {
00341 pos_i=y[i];
00342 balance[i]=0;
00343 for (j=0; j<n; j++) {
00344 if (j==i)
00345 continue;
00346 if (pos_i>=y[j]) {
00347 balance[i]+=Dij[i][j]*(-lap[i][j]);
00348 }
00349 else {
00350 balance[i]-=Dij[i][j]*(-lap[i][j]);
00351 }
00352 }
00353 }
00354
00355 for (converged=FALSE,iterations2=0; iterations2<200 && !converged; iterations2++) {
00356 conjugate_gradient_f(lap, y, balance, n, conj_tol, n, TRUE);
00357 converged=TRUE;
00358 for (i=0; i<n; i++) {
00359 pos_i=y[i];
00360 b=0;
00361 for (j=0; j<n; j++) {
00362 if (j==i)
00363 continue;
00364 if (pos_i>=y[j]) {
00365 b+=Dij[i][j]*(-lap[i][j]);
00366
00367 }
00368 else {
00369 b-=Dij[i][j]*(-lap[i][j]);
00370
00371 }
00372 }
00373 if ((b != balance[i]) && (fabs(1-b/balance[i])>1e-5)) {
00374 converged=FALSE;
00375 balance[i]=b;
00376 }
00377 }
00378 }
00379
00380 for (i=0; i<n; i++) {
00381 x[i] /= uniLength;
00382 y[i] /= uniLength;
00383 }
00384
00385
00386 free (Dij[0]); free (Dij);
00387 free (lap[0]); free (lap);
00388 free (orthog_aux); free (balance);
00389 }
00390
00391 #endif
00392