00001
00055 #include "apbscfg.h"
00056 #include "apbs/apbs.h"
00057
00058 VEMBED(rcsid="$Id: similarity.c 1552 2010-02-10 17:46:27Z yhuang01 $")
00059
00060
00064 void usage(int rc) {
00065 char *usage = "\n\
00066 A program to calculate similarity metrics between scalar data sets.\n\
00067 Usage: similarity <req args> [opts]\n\
00068 where <req args> are the required arguments:\n\
00069 --format=<format> The input file format. Acceptable values include\n\
00070 dx OpenDX format\n\
00071 --scalar1=<path> The path to the first scalar data file\n\
00072 --scalar2=<path> The path to the second scalar data file\n\
00073 and where [opts] are the options:\n\
00074 --help Print this message\n\
00075 --mask1=<path> A file with scalar values specifying a \"mask\" or\n\
00076 characteristic function for the similarity calculation. This file\n\
00077 contains values between 1 and 0 which are multiplied against the\n\
00078 scalar data set 1 before the similarity calculation is performed.\n\
00079 --mask2=<path> A file with scalar values specifying a \"mask\" or\n\
00080 characteristic function for the similarity calculation. This file\n\
00081 contains values between 1 and 0 which are multiplied against the\n\
00082 scalar data set 1 before the similarity calculation is performed.\n\
00083 --transform=<path> The path to a file containing the coordinate\n\
00084 transformation to place data set 2 in the coordinate frame of data set\n\
00085 1. The format of this file is:\n\
00086 a11 a12 a13\n\
00087 a21 a22 a23\n\
00088 a31 a32 a33\n\
00089 b1 b2 b3\n\
00090 where aij are the elements of a rotation matrix A and bi are the\n\
00091 elements of a displacement vector b. The transformed coordinates (y) of\n\
00092 data set 2 are obtained from the original coordinates (x) by:\n\
00093 y = A*x + v\n\
00094 \n";
00095
00096 Vnm_print(2, usage);
00097 exit(rc);
00098 }
00099
00107 int invertTransform(double A[3][3], double b[3], double C[3][3], double d[3]) {
00108
00109 double detA;
00110
00111
00112 detA = - A[0][2]*A[1][1]*A[2][0] + A[0][1]*A[1][2]*A[2][0] \
00113 + A[0][2]*A[1][0]*A[2][1] - A[0][0]*A[1][2]*A[2][1] \
00114 - A[0][1]*A[1][0]*A[2][2] + A[0][0]*A[1][1]*A[2][2];
00115 if (detA < VSMALL) {
00116 Vnm_print(2, "Error! Your matrix is singular; det = %g!\n", detA);
00117 return 0;
00118 }
00119
00120
00121 C[0][0] = (-A[1][2]*A[2][1]+A[1][1]*A[2][2])/detA;
00122 C[0][1] = ( A[0][2]*A[2][1]-A[0][1]*A[2][2])/detA;
00123 C[0][2] = (-A[0][2]*A[1][1]+A[0][1]*A[1][2])/detA;
00124 C[1][0] = ( A[1][2]*A[2][0]-A[1][0]*A[2][2])/detA;
00125 C[1][1] = (-A[0][2]*A[2][0]+A[0][0]*A[2][2])/detA;
00126 C[1][2] = ( A[0][2]*A[1][0]-A[0][0]*A[1][2])/detA;
00127 C[2][0] = (-A[1][1]*A[2][0]+A[1][0]*A[2][1])/detA;
00128 C[2][1] = ( A[0][1]*A[2][0]-A[0][0]*A[2][1])/detA;
00129 C[2][2] = (-A[0][1]*A[1][0]+A[0][0]*A[1][1])/detA;
00130
00131 printf("%4.3f %4.3f %4.3f\n",
00132 A[0][0]*C[0][0] + A[0][1]*C[1][0] + A[0][2]*C[2][0],
00133 A[0][0]*C[0][1] + A[0][1]*C[1][1] + A[0][2]*C[2][1],
00134 A[0][0]*C[0][2] + A[0][1]*C[1][2] + A[0][2]*C[2][2]);
00135 printf("%4.3f %4.3f %4.3f\n",
00136 A[1][0]*C[0][0] + A[1][1]*C[1][0] + A[1][2]*C[2][0],
00137 A[1][0]*C[0][1] + A[1][1]*C[1][1] + A[1][2]*C[2][1],
00138 A[1][0]*C[0][2] + A[1][1]*C[1][2] + A[1][2]*C[2][2]);
00139 printf("%4.3f %4.3f %4.3f\n",
00140 A[2][0]*C[0][0] + A[2][1]*C[1][0] + A[2][2]*C[2][0],
00141 A[2][0]*C[0][1] + A[2][1]*C[1][1] + A[2][2]*C[2][1],
00142 A[2][0]*C[0][2] + A[2][1]*C[1][2] + A[2][2]*C[2][2]);
00143
00144
00145 d[0] = -(C[0][0]*b[0]+C[0][1]*b[1]+C[0][2]*b[2]);
00146 d[1] = -(C[1][0]*b[0]+C[1][1]*b[1]+C[1][2]*b[2]);
00147 d[2] = -(C[2][0]*b[0]+C[2][1]*b[1]+C[2][2]*b[2]);
00148
00149 return 1;
00150 }
00151
00158 int readTransform(char *path, double rotMat[3][3], double dispVec[3]) {
00159
00160 Vio *sock = VNULL;
00161 char tok[VMAX_BUFSIZE];
00162 int rc;
00163
00164 Vnm_print(1, "Reading coordinate transform from %s...\n", path);
00165 sock = Vio_ctor("FILE", "ASC", VNULL, path, "r");
00166 if (sock == VNULL) {
00167 Vnm_print(2, "Problem opening virtual socket %s!\n", path);
00168 return 0;
00169 }
00170 if (Vio_accept(sock, 0) < 0) {
00171 Vnm_print(2, "Problem accepting virtual socket %s!\n", path);
00172 return 0;
00173 }
00174 Vio_setWhiteChars(sock, " =,;\t\n");
00175 Vio_setCommChars(sock, "#%");
00176 rc = Vio_scanf(sock, "%s", tok);
00177 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[0][0]));
00178 if (rc != 1) {
00179 Vnm_print(1, "Error while reading a11!\n");
00180 return 0;
00181 }
00182 rc = Vio_scanf(sock, "%s", tok);
00183 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[0][1]));
00184 if (rc != 1) {
00185 Vnm_print(1, "Error while reading a12!\n");
00186 return 0;
00187 }
00188 rc = Vio_scanf(sock, "%s", tok);
00189 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[0][2]));
00190 if (rc != 1) {
00191 Vnm_print(1, "Error while reading a13!\n");
00192 return 0;
00193 }
00194 rc = Vio_scanf(sock, "%s", tok);
00195 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[1][0]));
00196 if (rc != 1) {
00197 Vnm_print(1, "Error while reading a21!\n");
00198 return 0;
00199 }
00200 rc = Vio_scanf(sock, "%s", tok);
00201 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[1][1]));
00202 if (rc != 1) {
00203 Vnm_print(1, "Error while reading a22!\n");
00204 return 0;
00205 }
00206 rc = Vio_scanf(sock, "%s", tok);
00207 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[1][2]));
00208 if (rc != 1) {
00209 Vnm_print(1, "Error while reading a23!\n");
00210 return 0;
00211 }
00212 rc = Vio_scanf(sock, "%s", tok);
00213 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[2][0]));
00214 if (rc != 1) {
00215 Vnm_print(1, "Error while reading a31!\n");
00216 return 0;
00217 }
00218 rc = Vio_scanf(sock, "%s", tok);
00219 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[2][1]));
00220 if (rc != 1) {
00221 Vnm_print(1, "Error while reading a32!\n");
00222 return 0;
00223 }
00224 rc = Vio_scanf(sock, "%s", tok);
00225 if (rc == 1) rc = sscanf(tok, "%lf", &(rotMat[2][2]));
00226 if (rc != 1) {
00227 Vnm_print(1, "Error while reading a33!\n");
00228 return 0;
00229 }
00230 rc = Vio_scanf(sock, "%s", tok);
00231 if (rc == 1) rc = sscanf(tok, "%lf", &(dispVec[0]));
00232 if (rc != 1) {
00233 Vnm_print(1, "Error while reading b1!\n");
00234 return 0;
00235 }
00236 rc = Vio_scanf(sock, "%s", tok);
00237 if (rc == 1) rc = sscanf(tok, "%lf", &(dispVec[1]));
00238 if (rc != 1) {
00239 Vnm_print(1, "Error while reading b2!\n");
00240 return 0; } rc = Vio_scanf(sock, "%s", tok);
00241 if (rc == 1) rc = sscanf(tok, "%lf", &(dispVec[2]));
00242 if (rc != 1) {
00243 Vnm_print(1, "Error while reading b3!\n");
00244 return 0;
00245 }
00246 Vio_acceptFree(sock);
00247 Vio_dtor(&sock);
00248
00249 return 1;
00250 }
00251
00258 int readGrid(Vgrid **grid, char *path, Vdata_Format format) {
00259
00260 *grid = Vgrid_ctor(0, 0, 0,
00261 0.0, 0.0, 0.0,
00262 0.0, 0.0, 0.0,
00263 VNULL);
00264
00265 switch (format) {
00266 case VDF_DX:
00267 return Vgrid_readDX(*grid, "FILE", "ASC", VNULL, path);
00268 break;
00269 case VDF_UHBD:
00270 Vnm_print(2, "Sorry, UHBD input not supported yet!\n");
00271 return 0;
00272 break;
00273 case VDF_AVS:
00274 Vnm_print(2, "Sorry, AVS input not supported yet!\n");
00275 return 0;
00276 break;
00277 default:
00278 Vnm_print(2, "Unknown data format (%d)!\n", format);
00279 return 0;
00280 }
00281
00282 return 1;
00283 }
00284
00285 int main(int argc, char **argv) {
00286
00287
00288 int i, j, k, onGridS1, onGridV1, onGridS2, onGridV2, nx, ny, nz;
00289 double hx, hy, hzed, xmin, ymin, zmin, dvol, svol, gvol;
00290 double norm1_L1, norm1_L2, snorm1_H1, norm1_H1;
00291 double norm2_L1, norm2_L2, snorm2_H1, norm2_H1;
00292 double normDiff_L1, normDiff_L2, snormDiff_H1, normDiff_H1;
00293 double ip_L2, ip_H1;
00294 double val1, val2, sval1, sval2, mval1, mval2, p1[3], p2[3];
00295 double dval, gval1[3], gval2[3];
00296 Vgrid *scalar1, *scalar2, *mask1, *mask2;
00297 double rotMat2to1[3][3], dispVec2to1[3];
00298 double rotMat1to2[3][3], dispVec1to2[3];
00299 char scalar1Path[VMAX_ARGLEN];
00300 int gotScalar1 = 0;
00301 char scalar2Path[VMAX_ARGLEN];
00302 int gotScalar2 = 0;
00303 char transformPath[VMAX_ARGLEN];
00304 int gotTransform = 0;
00305 char mask1Path[VMAX_ARGLEN];
00306 int gotMask1 = 0;
00307 char mask2Path[VMAX_ARGLEN];
00308 int gotMask2 = 0;
00309 Vdata_Format format;
00310 int gotFormat = 0;
00311 char *tstr, *targ;
00312
00313
00314 Vio_start();
00315
00316 for (i=1; i<argc; i++) {
00317 targ = argv[i];
00318
00319 tstr = strstr(targ, "format");
00320 if (tstr != NULL) {
00321 tstr = tstr + 7;
00322 if (strcmp(tstr, "dx") == 0) {
00323 format = VDF_DX;
00324 gotFormat = 1;
00325 } else {
00326 Vnm_print(2, "Error! Unknown format (%s)!\n", tstr);
00327 usage(2);
00328 }
00329 }
00330
00331 tstr = strstr(targ, "scalar1");
00332 if (tstr != NULL) {
00333 tstr = tstr + 8;
00334 strncpy(scalar1Path, tstr, VMAX_ARGLEN);
00335 gotScalar1 = 1;
00336 }
00337
00338 tstr = strstr(targ, "scalar2");
00339 if (tstr != NULL) {
00340 tstr = tstr + 8;
00341 strncpy(scalar2Path, tstr, VMAX_ARGLEN);
00342 gotScalar2 = 1;
00343 }
00344
00345 tstr = strstr(targ, "transform");
00346 if (tstr != NULL) {
00347 tstr = tstr + 10;
00348 strncpy(transformPath, tstr, VMAX_ARGLEN);
00349 gotTransform = 1;
00350 }
00351
00352 tstr = strstr(targ, "help");
00353 if (tstr != NULL) usage(0);
00354
00355 tstr = strstr(targ, "mask1");
00356 if (tstr != NULL) {
00357 tstr = tstr + 6;
00358 strncpy(mask1Path, tstr, VMAX_ARGLEN);
00359 gotMask1 = 1;
00360 }
00361
00362 tstr = strstr(targ, "mask2");
00363 if (tstr != NULL) {
00364 tstr = tstr + 6;
00365 strncpy(mask2Path, tstr, VMAX_ARGLEN);
00366 gotMask2 = 1;
00367 }
00368 }
00369
00370 if (!gotFormat) {
00371 Vnm_print(2, "Error! --format not specified!\n");
00372 usage(2);
00373 } else {
00374 switch (format) {
00375 case VDF_DX:
00376 Vnm_print(1, "format: OpenDX\n");
00377 break;
00378 case VDF_UHBD:
00379 Vnm_print(1, "format: UHBD\n");
00380 break;
00381 case VDF_AVS:
00382 Vnm_print(1, "format: AVS\n");
00383 break;
00384 default:
00385 Vnm_print(2, "Error! Unknown format (%d)!\n", format);
00386 usage(2);
00387 }
00388 }
00389 if (!gotScalar1) {
00390 Vnm_print(2, "Error! --scalar1 not specified!\n");
00391 usage(2);
00392 } else {
00393 Vnm_print(1, "Data set 1: %s\n", scalar1Path);
00394 }
00395 if (!gotScalar2) {
00396 Vnm_print(2, "Error! --scalar2 not specified!\n");
00397 usage(2);
00398 } else {
00399 Vnm_print(1, "Data set 2: %s\n", scalar2Path);
00400 }
00401 if (gotTransform) {
00402 Vnm_print(1, "Transform: %s\n", transformPath);
00403 }
00404 if (gotMask1) {
00405 Vnm_print(1, "Mask 1: %s\n", mask1Path);
00406 }
00407 if (gotMask2) {
00408 Vnm_print(1, "Mask 2: %s\n", mask2Path);
00409 }
00410
00411
00412 if (!gotTransform) {
00413 Vnm_print(1, "Setting coordinate transform to identity...\n");
00414 rotMat2to1[0][0] = 1.0; rotMat2to1[0][1] = 0.0; rotMat2to1[0][2] = 0.0;
00415 rotMat2to1[1][0] = 0.0; rotMat2to1[1][1] = 1.0; rotMat2to1[1][2] = 0.0;
00416 rotMat2to1[2][0] = 0.0; rotMat2to1[2][1] = 0.0; rotMat2to1[2][2] = 1.0;
00417 dispVec2to1[0] = 0.0; dispVec2to1[1] = 0.0; dispVec2to1[2] = 0.0;
00418 } else {
00419 if (!readTransform(transformPath, rotMat2to1, dispVec2to1)) {
00420 Vnm_print(2, "Error reading transformation matrix!\n");
00421 return 2;
00422 }
00423 }
00424 Vnm_print(1, "Rotation matrix for set 2 into set 1:\n");
00425 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00426 rotMat2to1[0][0], rotMat2to1[0][1], rotMat2to1[0][2]);
00427 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00428 rotMat2to1[1][0], rotMat2to1[1][1], rotMat2to1[1][2]);
00429 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00430 rotMat2to1[2][0], rotMat2to1[2][1], rotMat2to1[2][2]);
00431 Vnm_print(1, "Displacement vector for set 2 into set 1:\n");
00432 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00433 dispVec2to1[0], dispVec2to1[1], dispVec2to1[2]);
00434
00435
00436 Vnm_print(1, "Inverting coordinate transform...\n");
00437 if (!invertTransform(rotMat2to1, dispVec2to1, rotMat1to2, dispVec1to2)) {
00438 Vnm_print(2, "Error inverting transformation!\n");
00439 return 2;
00440 }
00441 Vnm_print(1, "Rotation matrix for set 1 into set 2:\n");
00442 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00443 rotMat1to2[0][0], rotMat1to2[0][1], rotMat1to2[0][2]);
00444 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00445 rotMat1to2[1][0], rotMat1to2[1][1], rotMat1to2[1][2]);
00446 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00447 rotMat1to2[2][0], rotMat1to2[2][1], rotMat1to2[2][2]);
00448 Vnm_print(1, "Displacement vector for set 2 into set 1:\n");
00449 Vnm_print(1, " %1.12E %1.12E %1.12E\n",
00450 dispVec1to2[0], dispVec1to2[1], dispVec1to2[2]);
00451
00452
00453
00454 Vnm_print(1, "Reading scalar data set 1 from %s...\n", scalar1Path);
00455 if (!readGrid(&scalar1, scalar1Path, format)) {
00456 Vnm_print(2, "Error reading scalar data set 1!\n");
00457 return 2;
00458 }
00459 Vnm_print(1, "Read %d x %d x %d grid.\n",
00460 scalar1->nx, scalar1->ny, scalar1->nz);
00461
00462
00463 Vnm_print(1, "Reading scalar data set 2 from %s...\n", scalar2Path);
00464 if (!readGrid(&scalar2, scalar2Path, format)) {
00465 Vnm_print(2, "Error reading scalar data set 2!\n");
00466 return 2;
00467 }
00468 Vnm_print(1, "Read %d x %d x %d grid.\n",
00469 scalar2->nx, scalar2->ny, scalar2->nz);
00470
00471
00472 if (gotMask1) {
00473 Vnm_print(1, "Reading mask data set 1 from %s...\n", mask1Path);
00474 if (!readGrid(&mask1, mask1Path, format)) {
00475 Vnm_print(2, "Error reading mask data set 1!\n");
00476 return 2;
00477 }
00478 Vnm_print(1, "Read %d x %d x %d grid.\n",
00479 mask1->nx, mask1->ny, mask1->nz);
00480 }
00481
00482
00483 if (gotMask2) {
00484 Vnm_print(1, "Reading mask data set 2 from %s...\n", mask2Path);
00485 if (!readGrid(&mask2, mask2Path, format)) {
00486 Vnm_print(2, "Error reading mask data set 2!\n");
00487 return 2;
00488 }
00489 Vnm_print(1, "Read %d x %d x %d grid.\n",
00490 mask2->nx, mask2->ny, mask2->nz);
00491 }
00492
00493
00494 Vnm_print(1, "Calculating similarity measures...\n");
00495 nx = scalar1->nx; ny = scalar1->ny; nz = scalar1->nz;
00496 hx = scalar1->hx; hy = scalar1->hy; hzed = scalar1->hzed;
00497 dvol = (hx*hy*hzed);
00498 xmin = scalar1->xmin; ymin = scalar1->ymin; zmin = scalar1->zmin;
00499 norm1_L1 = 0; norm1_L2 = 0; snorm1_H1 = 0; norm1_H1 = 0;
00500 norm2_L1 = 0; norm2_L2 = 0; snorm2_H1 = 0; norm2_H1 = 0;
00501 normDiff_L1 = 0; normDiff_L2 = 0; snormDiff_H1 = 0; normDiff_H1 = 0;
00502 ip_L2 = 0; ip_H1 = 0;
00503 svol = 0; gvol = 0;
00504 for (i=0; i<nx; i++) {
00505 p1[0] = i*hx + xmin;
00506 for (j=0; j<ny; j++) {
00507 p1[1] = j*hy + ymin;
00508 for (k=0; k<nz; k++) {
00509
00510
00511 p1[2] = k*hzed + zmin;
00512 onGridS1 = Vgrid_value(scalar1, p1, &sval1);
00513 onGridV1 = Vgrid_gradient(scalar1, p1, gval1);
00514 if (gotMask1) onGridS1 = Vgrid_value(mask1, p1, &mval1);
00515 else mval1 = 1.0;
00516
00517
00518 p2[0] = rotMat1to2[0][0]*p1[0] + rotMat1to2[0][1]*p1[1] \
00519 + rotMat1to2[0][2]*p1[2] + dispVec1to2[0];
00520 p2[1] = rotMat1to2[1][0]*p1[0] + rotMat1to2[1][1]*p1[1] \
00521 + rotMat1to2[1][2]*p1[2] + dispVec1to2[1];
00522 p2[2] = rotMat1to2[2][0]*p1[0] + rotMat1to2[2][1]*p1[1] \
00523 + rotMat1to2[2][2]*p1[2] + dispVec1to2[2];
00524 onGridS2 = Vgrid_value(scalar2, p2, &sval2);
00525 onGridV2 = Vgrid_gradient(scalar2, p2, gval2);
00526 if (gotMask2) onGridS2 = Vgrid_value(mask2, p2, &mval2);
00527 else mval2 = 1.0;
00528
00529
00530 if (onGridS1 && onGridS2) {
00531 val1 = sval1*mval1;
00532 val2 = sval2*mval2;
00533 dval = mval1*mval2*(sval1 - sval2);
00534
00535
00536 norm1_L2 += VSQR(val1);
00537 norm2_L2 += VSQR(val2);
00538 normDiff_L2 += VSQR(dval);
00539 ip_L2 += (val2*val1);
00540
00541 norm1_L1 += VABS(val1);
00542 norm2_L1 += VABS(val2);
00543 normDiff_L1 += VABS(dval);
00544
00545 svol += dvol;
00546
00547 if (isnan(norm1_L2) || isnan(norm2_L2)) {
00548 Vnm_print(2, "ERROR! Got NaN!\n");
00549 Vnm_print(2, "p1 = (%1.12E, %1.12E, %1.12E)\n",
00550 p1[0], p1[1], p1[2]);
00551 Vnm_print(2, "p2 = (%1.12E, %1.12E, %1.12E)\n",
00552 p2[0], p2[1], p2[2]);
00553 Vnm_print(2, "mval1 = %1.12E\n", mval1);
00554 Vnm_print(2, "mval2 = %1.12E\n", mval2);
00555 Vnm_print(2, "sval1 = %1.12E\n", sval1);
00556 Vnm_print(2, "sval2 = %1.12E\n", sval2);
00557 Vnm_print(2, "val1 = %1.12E\n", val1);
00558 Vnm_print(2, "val2 = %1.12E\n", val2);
00559 Vnm_print(2, "dval = %1.12E\n", dval);
00560 VASSERT(0);
00561 }
00562 }
00563
00564
00565 if (onGridV1 && onGridV2 && onGridS1 && onGridS2) {
00566 val1 = mval1*(VSQR(gval1[0]) + VSQR(gval1[1]) \
00567 + VSQR(gval1[2]));
00568 val2 = mval2*(VSQR(gval2[0]) + VSQR(gval2[1]) \
00569 + VSQR(gval2[2]));
00570 dval = mval1*mval2*(VSQR(gval1[0]-gval2[0]) \
00571 + VSQR(gval1[1]-gval2[1]) \
00572 + VSQR(gval1[2]-gval2[2]));
00573 snorm1_H1 += VSQR(val1);
00574 snorm2_H1 += VSQR(val2);
00575 snormDiff_H1 += VSQR(dval);
00576 ip_H1 += (val1*val2);
00577 gvol += dvol;
00578 }
00579 }
00580 }
00581 }
00582
00583 Vnm_print(1, "Volume used to calculate L2 and L1 measures = %1.12E\n",
00584 svol);
00585 Vnm_print(1, "Volume used to calculate H1 measures = %1.12E\n",
00586 gvol);
00587
00588 printf("norm1_L2^2 = %1.12E\n", norm1_L2);
00589 norm1_L2 = VSQRT(norm1_L2*dvol);
00590 printf("norm1_L2 = %1.12E\n", norm1_L2);
00591 printf("norm2_L2^2 = %1.12E\n", norm2_L2);
00592 norm2_L2 = VSQRT(norm2_L2*dvol);
00593 printf("norm2_L2 = %1.12E\n", norm2_L2);
00594 printf("normDiff_L2^2 = %1.12E\n", normDiff_L2);
00595 normDiff_L2 = VSQRT(normDiff_L2*dvol);
00596 printf("normDiff_L2 = %1.12E\n", normDiff_L2);
00597 ip_L2 = ip_L2*dvol;
00598 Vnm_print(1, "Set 1 absolute L2 norm = %1.12E\n", norm1_L2);
00599 Vnm_print(1, "Set 2 absolute L2 norm = %1.12E\n", norm2_L2);
00600 Vnm_print(1, "Difference absolute L2 norm = %1.12E\n", normDiff_L2);
00601 Vnm_print(1, "Difference relative L2 norm = %1.12E\n",
00602 VSQR(normDiff_L2)/(norm1_L2*norm2_L2));
00603 Vnm_print(1, "Absolute L2 inner product = %1.12E\n", ip_L2);
00604 Vnm_print(1, "Hodgkin L2 inner product = %1.12E\n",
00605 2*ip_L2/(VSQR(norm1_L2)+VSQR(norm2_L2)));
00606 Vnm_print(1, "Carbo L2 inner product = %1.12E\n",
00607 ip_L2/(norm1_L2*norm2_L2));
00608
00609 norm1_L1 = (norm1_L2*dvol);
00610 norm2_L1 = (norm2_L2*dvol);
00611 normDiff_L1 = (normDiff_L2*dvol);
00612 Vnm_print(1, "Set 1 absolute L1 norm = %1.12E\n", norm1_L1);
00613 Vnm_print(1, "Set 2 absolute L1 norm = %1.12E\n", norm2_L1);
00614 Vnm_print(1, "Difference absolute L1 norm = %1.12E\n", normDiff_L1);
00615 Vnm_print(1, "Difference relative L1 norm = %1.12E\n",
00616 VSQR(normDiff_L1)/(norm1_L1*norm2_L1));
00617
00618 snorm1_H1 = VSQRT(snorm1_H1*dvol);
00619 snorm2_H1 = VSQRT(snorm2_H1*dvol);
00620 snormDiff_H1 = VSQRT(snormDiff_H1*dvol);
00621 norm1_H1 = VSQRT(VSQR(snorm1_H1)+VSQR(norm1_L2));
00622 norm2_H1 = VSQRT(VSQR(snorm2_H1)+VSQR(norm2_L2));
00623 normDiff_H1 = VSQRT(VSQR(snormDiff_H1)+VSQR(normDiff_L2));
00624 ip_H1 = ip_H1*dvol;
00625 Vnm_print(1, "Set 1 absolute H1 norm = %1.12E\n", norm1_H1);
00626 Vnm_print(1, "Set 2 absolute H1 norm = %1.12E\n", norm2_H1);
00627 Vnm_print(1, "Difference absolute H1 norm = %1.12E\n", normDiff_H1);
00628 Vnm_print(1, "Difference relative H1 norm = %1.12E\n",
00629 VSQR(normDiff_H1)/(norm1_L2*norm2_H1));
00630 Vnm_print(1, "Set 1 absolute H1 semi-norm = %1.12E\n", snorm1_H1);
00631 Vnm_print(1, "Set 2 absolute H1 semi-norm = %1.12E\n", snorm2_H1);
00632 Vnm_print(1, "Difference absolute H1 semi-norm = %1.12E\n", snormDiff_H1);
00633 Vnm_print(1, "Absolute H1 inner product = %1.12E\n", ip_H1);
00634 Vnm_print(1, "Hodgkin H1 inner product = %1.12E\n",
00635 2*ip_H1/(VSQR(snorm1_H1)+VSQR(snorm2_H1)));
00636 Vnm_print(1, "Carbo H1 inner product = %1.12E\n",
00637 ip_H1/(snorm1_H1*snorm2_H1));
00638 Vnm_print(1, "Absolute H1+L2 inner product = %1.12E\n",
00639 (ip_H1+ip_L2));
00640 Vnm_print(1, "Hodgkin H1+L2 inner product = %1.12E\n",
00641 2*(ip_H1+ip_L2)/(VSQR(norm1_H1)+VSQR(norm2_H1)));
00642 Vnm_print(1, "Carbo H1+L2 inner product = %1.12E\n",
00643 (ip_H1+ip_L2)/(norm1_H1*norm2_H1));
00644
00645 return 0;
00646 }