#include <cmp.h>
Inheritance diagram for EMAN::DotCmp:
Public Member Functions | |
float | cmp (EMData *image, EMData *with) const |
To compare 'image' with another image passed in through its parameters. | |
string | get_name () const |
Get the Cmp's name. | |
string | get_desc () const |
TypeDict | get_param_types () const |
Get Cmp parameter information in a dictionary. | |
Static Public Member Functions | |
Cmp * | NEW () |
Static Public Attributes | |
const string | NAME = "dot" |
// Added mask option PAP 04/23/06 For complex images, it does not check r/i vs a/p.
negative | Returns -1 * dot product, default true | |
normalize | Returns normalized dot product -1.0 - 1.0 |
Definition at line 270 of file cmp.h.
|
To compare 'image' with another image passed in through its parameters. An optional transformation may be used to transform the 2 images.
Implements EMAN::Cmp. Definition at line 381 of file cmp.cpp. References dm, EMAN::EMData::get_attr(), EMAN::EMData::get_const_data(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), EMAN::EMData::is_complex(), EMAN::EMData::is_fftodd(), nx, ny, EMAN::Dict::set_default(), sqrt(), and EMAN::Cmp::validate_input_args(). Referenced by EMAN::EMData::dot(). 00382 { 00383 ENTERFUNC; 00384 validate_input_args(image, with); 00385 00386 const float *const x_data = image->get_const_data(); 00387 const float *const y_data = with->get_const_data(); 00388 00389 int normalize = params.set_default("normalize", 0); 00390 float negative = (float)params.set_default("negative", 1); 00391 00392 if (negative) negative=-1.0; else negative=1.0; 00393 double result = 0.; 00394 long n = 0; 00395 if(image->is_complex() && with->is_complex()) { 00396 // Implemented by PAP 01/09/06 - please do not change. If in doubts, write/call me. 00397 int nx = with->get_xsize(); 00398 int ny = with->get_ysize(); 00399 int nz = with->get_zsize(); 00400 nx = (nx - 2 + with->is_fftodd()); // nx is the real-space size of the input image 00401 int lsd2 = (nx + 2 - nx%2) ; // Extended x-dimension of the complex image 00402 00403 int ixb = 2*((nx+1)%2); 00404 int iyb = ny%2; 00405 // 00406 if(nz == 1) { 00407 // it looks like it could work in 3D, but does not 00408 for ( int iz = 0; iz <= nz-1; ++iz) { 00409 double part = 0.; 00410 for ( int iy = 0; iy <= ny-1; ++iy) { 00411 for ( int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) { 00412 size_t ii = ix + (iy + iz * ny)* lsd2; 00413 part += x_data[ii] * double(y_data[ii]); 00414 } 00415 } 00416 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00417 size_t ii = (iy + iz * ny)* lsd2; 00418 part += x_data[ii] * double(y_data[ii]); 00419 part += x_data[ii+1] * double(y_data[ii+1]); 00420 } 00421 if(nx%2 == 0) { 00422 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00423 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2; 00424 part += x_data[ii] * double(y_data[ii]); 00425 part += x_data[ii+1] * double(y_data[ii+1]); 00426 } 00427 00428 } 00429 part *= 2; 00430 part += x_data[0] * double(y_data[0]); 00431 if(ny%2 == 0) { 00432 size_t ii = (ny/2 + iz * ny)* lsd2; 00433 part += x_data[ii] * double(y_data[ii]); 00434 } 00435 if(nx%2 == 0) { 00436 size_t ii = lsd2 - 2 + (0 + iz * ny)* lsd2; 00437 part += x_data[ii] * double(y_data[ii]); 00438 if(ny%2 == 0) { 00439 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2; 00440 part += x_data[ii] * double(y_data[ii]); 00441 } 00442 } 00443 result += part; 00444 } 00445 if( normalize ) { 00446 // it looks like it could work in 3D, but does not 00447 double square_sum1 = 0., square_sum2 = 0.; 00448 for ( int iz = 0; iz <= nz-1; ++iz) { 00449 for ( int iy = 0; iy <= ny-1; ++iy) { 00450 for ( int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) { 00451 size_t ii = ix + (iy + iz * ny)* lsd2; 00452 square_sum1 += x_data[ii] * double(x_data[ii]); 00453 square_sum2 += y_data[ii] * double(y_data[ii]); 00454 } 00455 } 00456 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00457 size_t ii = (iy + iz * ny)* lsd2; 00458 square_sum1 += x_data[ii] * double(x_data[ii]); 00459 square_sum1 += x_data[ii+1] * double(x_data[ii+1]); 00460 square_sum2 += y_data[ii] * double(y_data[ii]); 00461 square_sum2 += y_data[ii+1] * double(y_data[ii+1]); 00462 } 00463 if(nx%2 == 0) { 00464 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00465 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2; 00466 square_sum1 += x_data[ii] * double(x_data[ii]); 00467 square_sum1 += x_data[ii+1] * double(x_data[ii+1]); 00468 square_sum2 += y_data[ii] * double(y_data[ii]); 00469 square_sum2 += y_data[ii+1] * double(y_data[ii+1]); 00470 } 00471 00472 } 00473 square_sum1 *= 2; 00474 square_sum1 += x_data[0] * double(x_data[0]); 00475 square_sum2 *= 2; 00476 square_sum2 += y_data[0] * double(y_data[0]); 00477 if(ny%2 == 0) { 00478 int ii = (ny/2 + iz * ny)* lsd2; 00479 square_sum1 += x_data[ii] * double(x_data[ii]); 00480 square_sum2 += y_data[ii] * double(y_data[ii]); 00481 } 00482 if(nx%2 == 0) { 00483 int ii = lsd2 - 2 + (0 + iz * ny)* lsd2; 00484 square_sum1 += x_data[ii] * double(x_data[ii]); 00485 square_sum2 += y_data[ii] * double(y_data[ii]); 00486 if(ny%2 == 0) { 00487 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2; 00488 square_sum1 += x_data[ii] * double(x_data[ii]); 00489 square_sum2 += y_data[ii] * double(y_data[ii]); 00490 } 00491 } 00492 } 00493 result /= sqrt(square_sum1*square_sum2); 00494 } else result /= ((float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz); 00495 00496 } else { //This 3D code is incorrect, but it is the best I can do now 01/09/06 PAP 00497 int ky, kz; 00498 int ny2 = ny/2; int nz2 = nz/2; 00499 for ( int iz = 0; iz <= nz-1; ++iz) { 00500 if(iz>nz2) kz=iz-nz; else kz=iz; 00501 for ( int iy = 0; iy <= ny-1; ++iy) { 00502 if(iy>ny2) ky=iy-ny; else ky=iy; 00503 for ( int ix = 0; ix <= lsd2-1; ++ix) { 00504 // Skip Friedel related values 00505 if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) { 00506 size_t ii = ix + (iy + iz * ny)* lsd2; 00507 result += x_data[ii] * double(y_data[ii]); 00508 } 00509 } 00510 } 00511 } 00512 if( normalize ) { 00513 // still incorrect 00514 double square_sum1 = 0., square_sum2 = 0.; 00515 int ky, kz; 00516 int ny2 = ny/2; int nz2 = nz/2; 00517 for ( int iz = 0; iz <= nz-1; ++iz) { 00518 if(iz>nz2) kz=iz-nz; else kz=iz; 00519 for ( int iy = 0; iy <= ny-1; ++iy) { 00520 if(iy>ny2) ky=iy-ny; else ky=iy; 00521 for ( int ix = 0; ix <= lsd2-1; ++ix) { 00522 // Skip Friedel related values 00523 if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) { 00524 size_t ii = ix + (iy + iz * ny)* lsd2; 00525 square_sum1 += x_data[ii] * double(x_data[ii]); 00526 square_sum2 += y_data[ii] * double(y_data[ii]); 00527 } 00528 } 00529 } 00530 } 00531 result /= sqrt(square_sum1*square_sum2); 00532 } else result /= ((float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz/2); 00533 } 00534 } else { 00535 size_t totsize = image->get_xsize() * image->get_ysize() * image->get_zsize(); 00536 00537 double square_sum1 = 0., square_sum2 = 0.; 00538 00539 if (params.has_key("mask")) { 00540 EMData* mask; 00541 mask = params["mask"]; 00542 const float *const dm = mask->get_const_data(); 00543 if (normalize) { 00544 for (size_t i = 0; i < totsize; i++) { 00545 if (dm[i] > 0.5) { 00546 square_sum1 += x_data[i]*double(x_data[i]); 00547 square_sum2 += y_data[i]*double(y_data[i]); 00548 result += x_data[i]*double(y_data[i]); 00549 } 00550 } 00551 } else { 00552 for (size_t i = 0; i < totsize; i++) { 00553 if (dm[i] > 0.5) { 00554 result += x_data[i]*double(y_data[i]); 00555 n++; 00556 } 00557 } 00558 } 00559 } else { 00560 // this little bit of manual loop unrolling makes the dot product as fast as sqeuclidean with -O2 00561 for (size_t i=0; i<totsize; i++) result+=x_data[i]*y_data[i]; 00562 00563 if (normalize) { 00564 square_sum1 = image->get_attr("square_sum"); 00565 square_sum2 = with->get_attr("square_sum"); 00566 } else n = totsize; 00567 } 00568 if (normalize) result /= (sqrt(square_sum1*square_sum2)); else result /= n; 00569 } 00570 00571 00572 EXITFUNC; 00573 return (float) (negative*result); 00574 }
|
|
Implements EMAN::Cmp. Definition at line 280 of file cmp.h. 00281 { 00282 return "Dot product (default -1 * dot product)"; 00283 }
|
|
Get the Cmp's name. Each Cmp is identified by a unique name.
Implements EMAN::Cmp. Definition at line 275 of file cmp.h. 00276 {
00277 return NAME;
00278 }
|
|
Get Cmp parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Implements EMAN::Cmp. Definition at line 290 of file cmp.h. References EMAN::TypeDict::put(). 00291 { 00292 TypeDict d; 00293 d.put("negative", EMObject::INT, "If set, returns -1 * dot product. Set by default so smaller is better"); 00294 d.put("normalize", EMObject::INT, "If set, returns normalized dot product (cosine of the angle) -1.0 - 1.0."); 00295 d.put("mask", EMObject::EMDATA, "image mask"); 00296 return d; 00297 }
|
|
Definition at line 285 of file cmp.h. 00286 { 00287 return new DotCmp(); 00288 }
|
|
|