/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/neatogen/matrix_ops.c

Go to the documentation of this file.
00001 /* $Id: matrix_ops.c,v 1.5 2006/12/07 22:49:37 erg Exp $ $Revision: 1.5 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 #include "matrix_ops.h"
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <math.h>
00022 
00023 static double p_iteration_threshold = 1e-3;
00024 
00025 boolean
00026 power_iteration(double **square_mat, int n, int neigs, double **eigs,
00027                 double *evals, boolean initialize)
00028 {
00029     /* compute the 'neigs' top eigenvectors of 'square_mat' using power iteration */
00030 
00031     int i, j;
00032     double *tmp_vec = N_GNEW(n, double);
00033     double *last_vec = N_GNEW(n, double);
00034     double *curr_vector;
00035     double len;
00036     double angle;
00037     double alpha;
00038     int iteration = 0;
00039     int largest_index;
00040     double largest_eval;
00041     int Max_iterations = 30 * n;
00042 
00043     double tol = 1 - p_iteration_threshold;
00044 
00045     if (neigs >= n) {
00046         neigs = n;
00047     }
00048 
00049     for (i = 0; i < neigs; i++) {
00050         curr_vector = eigs[i];
00051         /* guess the i-th eigen vector */
00052       choose:
00053         if (initialize)
00054             for (j = 0; j < n; j++)
00055                 curr_vector[j] = rand() % 100;
00056         /* orthogonalize against higher eigenvectors */
00057         for (j = 0; j < i; j++) {
00058             alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00059             scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00060         }
00061         len = norm(curr_vector, 0, n - 1);
00062         if (len < 1e-10) {
00063             /* We have chosen a vector colinear with prvious ones */
00064             goto choose;
00065         }
00066         vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00067         iteration = 0;
00068         do {
00069             iteration++;
00070             cpvec(last_vec, 0, n - 1, curr_vector);
00071 
00072             right_mult_with_vector_d(square_mat, n, n, curr_vector,
00073                                      tmp_vec);
00074             cpvec(curr_vector, 0, n - 1, tmp_vec);
00075 
00076             /* orthogonalize against higher eigenvectors */
00077             for (j = 0; j < i; j++) {
00078                 alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00079                 scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00080             }
00081             len = norm(curr_vector, 0, n - 1);
00082             if (len < 1e-10 || iteration > Max_iterations) {
00083                 /* We have reached the null space (e.vec. associated with e.val. 0) */
00084                 goto exit;
00085             }
00086 
00087             vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00088             angle = dot(curr_vector, 0, n - 1, last_vec);
00089         } while (fabs(angle) < tol);
00090         evals[i] = angle * len; /* this is the Rayleigh quotient (up to errors due to orthogonalization):
00091                                    u*(A*u)/||A*u||)*||A*u||, where u=last_vec, and ||u||=1
00092                                  */
00093     }
00094   exit:
00095     for (; i < neigs; i++) {
00096         /* compute the smallest eigenvector, which are  */
00097         /* probably associated with eigenvalue 0 and for */
00098         /* which power-iteration is dangerous */
00099         curr_vector = eigs[i];
00100         /* guess the i-th eigen vector */
00101         for (j = 0; j < n; j++)
00102             curr_vector[j] = rand() % 100;
00103         /* orthogonalize against higher eigenvectors */
00104         for (j = 0; j < i; j++) {
00105             alpha = -dot(eigs[j], 0, n - 1, curr_vector);
00106             scadd(curr_vector, 0, n - 1, alpha, eigs[j]);
00107         }
00108         len = norm(curr_vector, 0, n - 1);
00109         vecscale(curr_vector, 0, n - 1, 1.0 / len, curr_vector);
00110         evals[i] = 0;
00111 
00112     }
00113 
00114 
00115     /* sort vectors by their evals, for overcoming possible mis-convergence: */
00116     for (i = 0; i < neigs - 1; i++) {
00117         largest_index = i;
00118         largest_eval = evals[largest_index];
00119         for (j = i + 1; j < neigs; j++) {
00120             if (largest_eval < evals[j]) {
00121                 largest_index = j;
00122                 largest_eval = evals[largest_index];
00123             }
00124         }
00125         if (largest_index != i) {       /* exchange eigenvectors: */
00126             cpvec(tmp_vec, 0, n - 1, eigs[i]);
00127             cpvec(eigs[i], 0, n - 1, eigs[largest_index]);
00128             cpvec(eigs[largest_index], 0, n - 1, tmp_vec);
00129 
00130             evals[largest_index] = evals[i];
00131             evals[i] = largest_eval;
00132         }
00133     }
00134 
00135     free(tmp_vec);
00136     free(last_vec);
00137 
00138     return (iteration <= Max_iterations);
00139 }
00140 
00141 
00142 
00143 void
00144 mult_dense_mat(double **A, float **B, int dim1, int dim2, int dim3,
00145                float ***CC)
00146 {
00147 /*
00148   A is dim1 x dim2, B is dim2 x dim3, C = A x B 
00149 */
00150 
00151     double sum;
00152     int i, j, k;
00153     float *storage;
00154     float **C = *CC;
00155     if (C != NULL) {
00156         storage = (float *) realloc(C[0], dim1 * dim3 * sizeof(A[0]));
00157         *CC = C = (float **) realloc(C, dim1 * sizeof(A));
00158     } else {
00159         storage = (float *) malloc(dim1 * dim3 * sizeof(A[0]));
00160         *CC = C = (float **) malloc(dim1 * sizeof(A));
00161     }
00162 
00163     for (i = 0; i < dim1; i++) {
00164         C[i] = storage;
00165         storage += dim3;
00166     }
00167 
00168     for (i = 0; i < dim1; i++) {
00169         for (j = 0; j < dim3; j++) {
00170             sum = 0;
00171             for (k = 0; k < dim2; k++) {
00172                 sum += A[i][k] * B[k][j];
00173             }
00174             C[i][j] = (float) (sum);
00175         }
00176     }
00177 }
00178 
00179 void
00180 mult_dense_mat_d(double **A, float **B, int dim1, int dim2, int dim3,
00181                  double ***CC)
00182 {
00183 /*
00184   A is dim1 x dim2, B is dim2 x dim3, C = A x B 
00185 */
00186     double **C = *CC;
00187     double *storage;
00188     int i, j, k;
00189     double sum;
00190 
00191     if (C != NULL) {
00192         storage = (double *) realloc(C[0], dim1 * dim3 * sizeof(double));
00193         *CC = C = (double **) realloc(C, dim1 * sizeof(double *));
00194     } else {
00195         storage = (double *) malloc(dim1 * dim3 * sizeof(double));
00196         *CC = C = (double **) malloc(dim1 * sizeof(double *));
00197     }
00198 
00199     for (i = 0; i < dim1; i++) {
00200         C[i] = storage;
00201         storage += dim3;
00202     }
00203 
00204     for (i = 0; i < dim1; i++) {
00205         for (j = 0; j < dim3; j++) {
00206             sum = 0;
00207             for (k = 0; k < dim2; k++) {
00208                 sum += A[i][k] * B[k][j];
00209             }
00210             C[i][j] = sum;
00211         }
00212     }
00213 }
00214 
00215 void
00216 mult_sparse_dense_mat_transpose(vtx_data * A, double **B, int dim1,
00217                                 int dim2, float ***CC)
00218 {
00219 /*
00220   A is dim1 x dim1 and sparse, B is dim2 x dim1, C = A x B 
00221 */
00222 
00223     float *storage;
00224     int i, j, k;
00225     double sum;
00226     float *ewgts;
00227     int *edges;
00228     int nedges;
00229     float **C = *CC;
00230     if (C != NULL) {
00231         storage = (float *) realloc(C[0], dim1 * dim2 * sizeof(A[0]));
00232         *CC = C = (float **) realloc(C, dim1 * sizeof(A));
00233     } else {
00234         storage = (float *) malloc(dim1 * dim2 * sizeof(A[0]));
00235         *CC = C = (float **) malloc(dim1 * sizeof(A));
00236     }
00237 
00238     for (i = 0; i < dim1; i++) {
00239         C[i] = storage;
00240         storage += dim2;
00241     }
00242 
00243     for (i = 0; i < dim1; i++) {
00244         edges = A[i].edges;
00245         ewgts = A[i].ewgts;
00246         nedges = A[i].nedges;
00247         for (j = 0; j < dim2; j++) {
00248             sum = 0;
00249             for (k = 0; k < nedges; k++) {
00250                 sum += ewgts[k] * B[j][edges[k]];
00251             }
00252             C[i][j] = (float) (sum);
00253         }
00254     }
00255 }
00256 
00257 
00258 
00259 /* Copy a range of a double vector to a double vector */
00260 void cpvec(double *copy, int beg, int end, double *vec)
00261 {
00262     int i;
00263 
00264     copy = copy + beg;
00265     vec = vec + beg;
00266     for (i = end - beg + 1; i; i--) {
00267         *copy++ = *vec++;
00268     }
00269 }
00270 
00271 /* Returns scalar product of two double n-vectors. */
00272 double dot(double *vec1, int beg, int end, double *vec2)
00273 {
00274     int i;
00275     double sum;
00276 
00277     sum = 0.0;
00278     vec1 = vec1 + beg;
00279     vec2 = vec2 + beg;
00280     for (i = end - beg + 1; i; i--) {
00281         sum += (*vec1++) * (*vec2++);
00282     }
00283     return (sum);
00284 }
00285 
00286 
00287 /* Scaled add - fills double vec1 with vec1 + alpha*vec2 over range*/
00288 void scadd(double *vec1, int beg, int end, double fac, double *vec2)
00289 {
00290     int i;
00291 
00292     vec1 = vec1 + beg;
00293     vec2 = vec2 + beg;
00294     for (i = end - beg + 1; i; i--) {
00295         (*vec1++) += fac * (*vec2++);
00296     }
00297 }
00298 
00299 /* Scale - fills vec1 with alpha*vec2 over range, double version */
00300 void vecscale(double *vec1, int beg, int end, double alpha, double *vec2)
00301 {
00302     int i;
00303 
00304     vec1 += beg;
00305     vec2 += beg;
00306     for (i = end - beg + 1; i; i--) {
00307         (*vec1++) = alpha * (*vec2++);
00308     }
00309 }
00310 
00311 /* Returns 2-norm of a double n-vector over range. */
00312 double norm(double *vec, int beg, int end)
00313 {
00314     return (sqrt(dot(vec, beg, end, vec)));
00315 }
00316 
00317 
00318 #ifndef __cplusplus
00319 
00320 /* inline */
00321 void orthog1(int n, double *vec /* vector to be orthogonalized against 1 */
00322     )
00323 {
00324     int i;
00325     double *pntr;
00326     double sum;
00327 
00328     sum = 0.0;
00329     pntr = vec;
00330     for (i = n; i; i--) {
00331         sum += *pntr++;
00332     }
00333     sum /= n;
00334     pntr = vec;
00335     for (i = n; i; i--) {
00336         *pntr++ -= sum;
00337     }
00338 }
00339 
00340 #define RANGE 500
00341 
00342 /* inline */
00343 void init_vec_orth1(int n, double *vec)
00344 {
00345     /* randomly generate a vector orthogonal to 1 (i.e., with mean 0) */
00346     int i;
00347 
00348     for (i = 0; i < n; i++)
00349         vec[i] = rand() % RANGE;
00350 
00351     orthog1(n, vec);
00352 }
00353 
00354 /* inline */
00355 void
00356 right_mult_with_vector(vtx_data * matrix, int n, double *vector,
00357                        double *result)
00358 {
00359     int i, j;
00360 
00361     double res;
00362     for (i = 0; i < n; i++) {
00363         res = 0;
00364         for (j = 0; j < matrix[i].nedges; j++)
00365             res += matrix[i].ewgts[j] * vector[matrix[i].edges[j]];
00366         result[i] = res;
00367     }
00368     /* orthog1(n,vector); */
00369 }
00370 
00371 /* inline */
00372 void
00373 right_mult_with_vector_f(float **matrix, int n, double *vector,
00374                          double *result)
00375 {
00376     int i, j;
00377 
00378     double res;
00379     for (i = 0; i < n; i++) {
00380         res = 0;
00381         for (j = 0; j < n; j++)
00382             res += matrix[i][j] * vector[j];
00383         result[i] = res;
00384     }
00385     /* orthog1(n,vector); */
00386 }
00387 
00388 /* inline */
00389 void
00390 vectors_subtraction(int n, double *vector1, double *vector2,
00391                     double *result)
00392 {
00393     int i;
00394     for (i = 0; i < n; i++) {
00395         result[i] = vector1[i] - vector2[i];
00396     }
00397 }
00398 
00399 /* inline */
00400 void
00401 vectors_addition(int n, double *vector1, double *vector2, double *result)
00402 {
00403     int i;
00404     for (i = 0; i < n; i++) {
00405         result[i] = vector1[i] + vector2[i];
00406     }
00407 }
00408 
00409 #ifdef UNUSED
00410 /* inline */
00411 void
00412 vectors_mult_addition(int n, double *vector1, double alpha,
00413                       double *vector2)
00414 {
00415     int i;
00416     for (i = 0; i < n; i++) {
00417         vector1[i] = vector1[i] + alpha * vector2[i];
00418     }
00419 }
00420 #endif
00421 
00422 /* inline */
00423 void
00424 vectors_scalar_mult(int n, double *vector, double alpha, double *result)
00425 {
00426     int i;
00427     for (i = 0; i < n; i++) {
00428         result[i] = vector[i] * alpha;
00429     }
00430 }
00431 
00432 /* inline */
00433 void copy_vector(int n, double *source, double *dest)
00434 {
00435     int i;
00436     for (i = 0; i < n; i++)
00437         dest[i] = source[i];
00438 }
00439 
00440 /* inline */
00441 double vectors_inner_product(int n, double *vector1, double *vector2)
00442 {
00443     int i;
00444     double result = 0;
00445     for (i = 0; i < n; i++) {
00446         result += vector1[i] * vector2[i];
00447     }
00448 
00449     return result;
00450 }
00451 
00452 /* inline */
00453 double max_abs(int n, double *vector)
00454 {
00455     double max_val = -1e50;
00456     int i;
00457     for (i = 0; i < n; i++)
00458         if (fabs(vector[i]) > max_val)
00459             max_val = fabs(vector[i]);
00460 
00461     return max_val;
00462 }
00463 
00464 #ifdef UNUSED
00465 /* inline */
00466 void orthogvec(int n, double *vec1,     /* vector to be orthogonalized */
00467                double *vec2     /* normalized vector to be orthogonalized against */
00468     )
00469 {
00470     double alpha;
00471     if (vec2 == NULL) {
00472         return;
00473     }
00474 
00475     alpha = -vectors_inner_product(n, vec1, vec2);
00476 
00477     vectors_mult_addition(n, vec1, alpha, vec2);
00478 }
00479 
00480  /* sparse matrix extensions: */
00481 
00482 /* inline */
00483 void mat_mult_vec(vtx_data * L, int n, double *vec, double *result)
00484 {
00485     /* compute result= -L*vec */
00486     int i, j;
00487     double sum;
00488     int *edges;
00489     float *ewgts;
00490 
00491     for (i = 0; i < n; i++) {
00492         sum = 0;
00493         edges = L[i].edges;
00494         ewgts = L[i].ewgts;
00495         for (j = 0; j < L[i].nedges; j++) {
00496             sum -= ewgts[j] * vec[edges[j]];
00497         }
00498         result[i] = sum;
00499     }
00500 }
00501 #endif
00502 
00503 /* inline */
00504 void
00505 right_mult_with_vector_transpose(double **matrix,
00506                                  int dim1, int dim2,
00507                                  double *vector, double *result)
00508 {
00509     /* matrix is dim2 x dim1, vector has dim2 components, result=matrix^T x vector */
00510     int i, j;
00511 
00512     double res;
00513     for (i = 0; i < dim1; i++) {
00514         res = 0;
00515         for (j = 0; j < dim2; j++)
00516             res += matrix[j][i] * vector[j];
00517         result[i] = res;
00518     }
00519 }
00520 
00521 /* inline */
00522 void
00523 right_mult_with_vector_d(double **matrix,
00524                          int dim1, int dim2,
00525                          double *vector, double *result)
00526 {
00527     /* matrix is dim1 x dim2, vector has dim2 components, result=matrix x vector */
00528     int i, j;
00529 
00530     double res;
00531     for (i = 0; i < dim1; i++) {
00532         res = 0;
00533         for (j = 0; j < dim2; j++)
00534             res += matrix[i][j] * vector[j];
00535         result[i] = res;
00536     }
00537 }
00538 
00539 
00540 /*****************************
00541 ** Single precision (float) **
00542 ** version                  **
00543 *****************************/
00544 
00545 /* inline */
00546 void orthog1f(int n, float *vec)
00547 {
00548     int i;
00549     float *pntr;
00550     float sum;
00551 
00552     sum = 0.0;
00553     pntr = vec;
00554     for (i = n; i; i--) {
00555         sum += *pntr++;
00556     }
00557     sum /= n;
00558     pntr = vec;
00559     for (i = n; i; i--) {
00560         *pntr++ -= sum;
00561     }
00562 }
00563 
00564 #ifdef UNUSED
00565 /* inline */
00566 void right_mult_with_vectorf
00567     (vtx_data * matrix, int n, float *vector, float *result) {
00568     int i, j;
00569 
00570     float res;
00571     for (i = 0; i < n; i++) {
00572         res = 0;
00573         for (j = 0; j < matrix[i].nedges; j++)
00574             res += matrix[i].ewgts[j] * vector[matrix[i].edges[j]];
00575         result[i] = res;
00576     }
00577 }
00578 
00579 /* inline */
00580 void right_mult_with_vector_fd
00581     (float **matrix, int n, float *vector, double *result) {
00582     int i, j;
00583 
00584     float res;
00585     for (i = 0; i < n; i++) {
00586         res = 0;
00587         for (j = 0; j < n; j++)
00588             res += matrix[i][j] * vector[j];
00589         result[i] = res;
00590     }
00591 }
00592 #endif
00593 
00594 /* inline */
00595 void right_mult_with_vector_ff
00596     (float *packed_matrix, int n, float *vector, float *result) {
00597     /* packed matrix is the upper-triangular part of a symmetric matrix arranged in a vector row-wise */
00598     int i, j, index;
00599     float vector_i;
00600 
00601     float res;
00602     for (i = 0; i < n; i++) {
00603         result[i] = 0;
00604     }
00605     for (index = 0, i = 0; i < n; i++) {
00606         res = 0;
00607         vector_i = vector[i];
00608         /* deal with main diag */
00609         res += packed_matrix[index++] * vector_i;
00610         /* deal with off diag */
00611         for (j = i + 1; j < n; j++, index++) {
00612             res += packed_matrix[index] * vector[j];
00613             result[j] += packed_matrix[index] * vector_i;
00614         }
00615         result[i] += res;
00616     }
00617 }
00618 
00619 /* inline */
00620 void
00621 vectors_substractionf(int n, float *vector1, float *vector2, float *result)
00622 {
00623     int i;
00624     for (i = 0; i < n; i++) {
00625         result[i] = vector1[i] - vector2[i];
00626     }
00627 }
00628 
00629 /* inline */
00630 void
00631 vectors_additionf(int n, float *vector1, float *vector2, float *result)
00632 {
00633     int i;
00634     for (i = 0; i < n; i++) {
00635         result[i] = vector1[i] + vector2[i];
00636     }
00637 }
00638 
00639 /* inline */
00640 void
00641 vectors_mult_additionf(int n, float *vector1, float alpha, float *vector2)
00642 {
00643     int i;
00644     for (i = 0; i < n; i++) {
00645         vector1[i] = vector1[i] + alpha * vector2[i];
00646     }
00647 }
00648 
00649 /* inline */
00650 void vectors_scalar_multf(int n, float *vector, float alpha, float *result)
00651 {
00652     int i;
00653     for (i = 0; i < n; i++) {
00654         result[i] = (float) vector[i] * alpha;
00655     }
00656 }
00657 
00658 /* inline */
00659 void copy_vectorf(int n, float *source, float *dest)
00660 {
00661     int i;
00662     for (i = 0; i < n; i++)
00663         dest[i] = source[i];
00664 }
00665 
00666 /* inline */
00667 double vectors_inner_productf(int n, float *vector1, float *vector2)
00668 {
00669     int i;
00670     double result = 0;
00671     for (i = 0; i < n; i++) {
00672         result += vector1[i] * vector2[i];
00673     }
00674 
00675     return result;
00676 }
00677 
00678 /* inline */
00679 void set_vector_val(int n, double val, double *result)
00680 {
00681     int i;
00682     for (i = 0; i < n; i++)
00683         result[i] = val;
00684 }
00685 
00686 /* inline */
00687 void set_vector_valf(int n, float val, float * result) {
00688     int i;
00689     for (i=0; i<n; i++)
00690         result[i]=val;
00691 }
00692 
00693 /* inline */
00694 double max_absf(int n, float *vector)
00695 {
00696     int i;
00697     float max_val = -1e30f;
00698     for (i = 0; i < n; i++)
00699         if (fabs(vector[i]) > max_val)
00700             max_val = (float) (fabs(vector[i]));
00701 
00702     return max_val;
00703 }
00704 
00705 /* inline */
00706 void square_vec(int n, float *vec)
00707 {
00708     int i;
00709     for (i = 0; i < n; i++) {
00710         vec[i] *= vec[i];
00711     }
00712 }
00713 
00714 /* inline */
00715 void invert_vec(int n, float *vec)
00716 {
00717     int i;
00718     float v;
00719     for (i = 0; i < n; i++) {
00720         if ((v = vec[i]) != 0.0)
00721             vec[i] = 1.0f / v;
00722     }
00723 }
00724 
00725 /* inline */
00726 void sqrt_vec(int n, float *vec)
00727 {
00728     int i;
00729     double d;
00730     for (i = 0; i < n; i++) {
00731         /* do this in two steps to avoid a bug in gcc-4.00 on AIX */
00732         d = sqrt(vec[i]);
00733         vec[i] = (float) d;
00734     }
00735 }
00736 
00737 /* inline */
00738 void sqrt_vecf(int n, float *source, float *target)
00739 {
00740     int i;
00741     double d;
00742     float v;
00743     for (i = 0; i < n; i++) {
00744         if ((v = source[i]) >= 0.0) {
00745             /* do this in two steps to avoid a bug in gcc-4.00 on AIX */
00746             d = sqrt(v);
00747             target[i] = (float) d;
00748         }
00749     }
00750 }
00751 
00752 /* inline */
00753 void invert_sqrt_vec(int n, float *vec)
00754 {
00755     int i;
00756     double d;
00757     float v;
00758     for (i = 0; i < n; i++) {
00759         if ((v = vec[i]) > 0.0) {
00760             /* do this in two steps to avoid a bug in gcc-4.00 on AIX */
00761             d = 1. / sqrt(v);
00762             vec[i] = (float) d;
00763         }
00764     }
00765 }
00766 
00767 #ifdef UNUSED
00768 /* inline */
00769 void init_vec_orth1f(int n, float *vec)
00770 {
00771     /* randomly generate a vector orthogonal to 1 (i.e., with mean 0) */
00772     int i;
00773 
00774     for (i = 0; i < n; i++)
00775         vec[i] = (float) (rand() % RANGE);
00776 
00777     orthog1f(n, vec);
00778 }
00779 
00780 
00781  /* sparse matrix extensions: */
00782 
00783 /* inline */
00784 void mat_mult_vecf(vtx_data * L, int n, float *vec, float *result)
00785 {
00786     /* compute result= -L*vec */
00787     int i, j;
00788     float sum;
00789     int *edges;
00790     float *ewgts;
00791 
00792     for (i = 0; i < n; i++) {
00793         sum = 0;
00794         edges = L[i].edges;
00795         ewgts = L[i].ewgts;
00796         for (j = 0; j < L[i].nedges; j++) {
00797             sum -= ewgts[j] * vec[edges[j]];
00798         }
00799         result[i] = sum;
00800     }
00801 }
00802 #endif
00803 
00804 #endif

Generated on Mon Mar 31 19:03:27 2008 for Graphviz by  doxygen 1.5.1