#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 | |
static Cmp * | NEW () |
Static Public Attributes | |
static 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 234 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 288 of file cmp.cpp. References dm, ENTERFUNC, EXITFUNC, 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::Cmp::params, EMAN::Dict::set_default(), sqrt(), and EMAN::Cmp::validate_input_args(). Referenced by EMAN::EMData::dot(). 00289 { 00290 ENTERFUNC; 00291 validate_input_args(image, with); 00292 00293 const float *const x_data = image->get_const_data(); 00294 const float *const y_data = with->get_const_data(); 00295 00296 int normalize = params.set_default("normalize", 0); 00297 float negative = (float)params.set_default("negative", 1); 00298 00299 if (negative) negative=-1.0; else negative=1.0; 00300 double result = 0.; 00301 long n = 0; 00302 if(image->is_complex() && with->is_complex()) { 00303 // Implemented by PAP 01/09/06 - please do not change. If in doubts, write/call me. 00304 int nx = with->get_xsize(); 00305 int ny = with->get_ysize(); 00306 int nz = with->get_zsize(); 00307 nx = (nx - 2 + with->is_fftodd()); // nx is the real-space size of the input image 00308 int lsd2 = (nx + 2 - nx%2) ; // Extended x-dimension of the complex image 00309 00310 int ixb = 2*((nx+1)%2); 00311 int iyb = ny%2; 00312 // 00313 if(nz == 1) { 00314 // it looks like it could work in 3D, but does not 00315 for ( int iz = 0; iz <= nz-1; ++iz) { 00316 double part = 0.; 00317 for ( int iy = 0; iy <= ny-1; ++iy) { 00318 for ( int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) { 00319 size_t ii = ix + (iy + iz * ny)* lsd2; 00320 part += x_data[ii] * double(y_data[ii]); 00321 } 00322 } 00323 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00324 size_t ii = (iy + iz * ny)* lsd2; 00325 part += x_data[ii] * double(y_data[ii]); 00326 part += x_data[ii+1] * double(y_data[ii+1]); 00327 } 00328 if(nx%2 == 0) { 00329 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00330 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2; 00331 part += x_data[ii] * double(y_data[ii]); 00332 part += x_data[ii+1] * double(y_data[ii+1]); 00333 } 00334 00335 } 00336 part *= 2; 00337 part += x_data[0] * double(y_data[0]); 00338 if(ny%2 == 0) { 00339 size_t ii = (ny/2 + iz * ny)* lsd2; 00340 part += x_data[ii] * double(y_data[ii]); 00341 } 00342 if(nx%2 == 0) { 00343 size_t ii = lsd2 - 2 + (0 + iz * ny)* lsd2; 00344 part += x_data[ii] * double(y_data[ii]); 00345 if(ny%2 == 0) { 00346 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2; 00347 part += x_data[ii] * double(y_data[ii]); 00348 } 00349 } 00350 result += part; 00351 } 00352 if( normalize ) { 00353 // it looks like it could work in 3D, but does not 00354 double square_sum1 = 0., square_sum2 = 0.; 00355 for ( int iz = 0; iz <= nz-1; ++iz) { 00356 for ( int iy = 0; iy <= ny-1; ++iy) { 00357 for ( int ix = 2; ix <= lsd2 - 1 - ixb; ++ix) { 00358 size_t ii = ix + (iy + iz * ny)* lsd2; 00359 square_sum1 += x_data[ii] * double(x_data[ii]); 00360 square_sum2 += y_data[ii] * double(y_data[ii]); 00361 } 00362 } 00363 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00364 size_t ii = (iy + iz * ny)* lsd2; 00365 square_sum1 += x_data[ii] * double(x_data[ii]); 00366 square_sum1 += x_data[ii+1] * double(x_data[ii+1]); 00367 square_sum2 += y_data[ii] * double(y_data[ii]); 00368 square_sum2 += y_data[ii+1] * double(y_data[ii+1]); 00369 } 00370 if(nx%2 == 0) { 00371 for ( int iy = 1; iy <= ny/2-1 + iyb; ++iy) { 00372 size_t ii = lsd2 - 2 + (iy + iz * ny)* lsd2; 00373 square_sum1 += x_data[ii] * double(x_data[ii]); 00374 square_sum1 += x_data[ii+1] * double(x_data[ii+1]); 00375 square_sum2 += y_data[ii] * double(y_data[ii]); 00376 square_sum2 += y_data[ii+1] * double(y_data[ii+1]); 00377 } 00378 00379 } 00380 square_sum1 *= 2; 00381 square_sum1 += x_data[0] * double(x_data[0]); 00382 square_sum2 *= 2; 00383 square_sum2 += y_data[0] * double(y_data[0]); 00384 if(ny%2 == 0) { 00385 int ii = (ny/2 + iz * ny)* lsd2; 00386 square_sum1 += x_data[ii] * double(x_data[ii]); 00387 square_sum2 += y_data[ii] * double(y_data[ii]); 00388 } 00389 if(nx%2 == 0) { 00390 int ii = lsd2 - 2 + (0 + iz * ny)* lsd2; 00391 square_sum1 += x_data[ii] * double(x_data[ii]); 00392 square_sum2 += y_data[ii] * double(y_data[ii]); 00393 if(ny%2 == 0) { 00394 int ii = lsd2 - 2 +(ny/2 + iz * ny)* lsd2; 00395 square_sum1 += x_data[ii] * double(x_data[ii]); 00396 square_sum2 += y_data[ii] * double(y_data[ii]); 00397 } 00398 } 00399 } 00400 result /= sqrt(square_sum1*square_sum2); 00401 } else result /= ((float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz); 00402 00403 } else { //This 3D code is incorrect, but it is the best I can do now 01/09/06 PAP 00404 int ky, kz; 00405 int ny2 = ny/2; int nz2 = nz/2; 00406 for ( int iz = 0; iz <= nz-1; ++iz) { 00407 if(iz>nz2) kz=iz-nz; else kz=iz; 00408 for ( int iy = 0; iy <= ny-1; ++iy) { 00409 if(iy>ny2) ky=iy-ny; else ky=iy; 00410 for ( int ix = 0; ix <= lsd2-1; ++ix) { 00411 // Skip Friedel related values 00412 if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) { 00413 size_t ii = ix + (iy + iz * ny)* lsd2; 00414 result += x_data[ii] * double(y_data[ii]); 00415 } 00416 } 00417 } 00418 } 00419 if( normalize ) { 00420 // still incorrect 00421 double square_sum1 = 0., square_sum2 = 0.; 00422 int ky, kz; 00423 int ny2 = ny/2; int nz2 = nz/2; 00424 for ( int iz = 0; iz <= nz-1; ++iz) { 00425 if(iz>nz2) kz=iz-nz; else kz=iz; 00426 for ( int iy = 0; iy <= ny-1; ++iy) { 00427 if(iy>ny2) ky=iy-ny; else ky=iy; 00428 for ( int ix = 0; ix <= lsd2-1; ++ix) { 00429 // Skip Friedel related values 00430 if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) { 00431 size_t ii = ix + (iy + iz * ny)* lsd2; 00432 square_sum1 += x_data[ii] * double(x_data[ii]); 00433 square_sum2 += y_data[ii] * double(y_data[ii]); 00434 } 00435 } 00436 } 00437 } 00438 result /= sqrt(square_sum1*square_sum2); 00439 } else result /= ((float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz/2); 00440 } 00441 } else { 00442 size_t totsize = image->get_xsize() * image->get_ysize() * image->get_zsize(); 00443 00444 double square_sum1 = 0., square_sum2 = 0.; 00445 00446 if (params.has_key("mask")) { 00447 EMData* mask; 00448 mask = params["mask"]; 00449 const float *const dm = mask->get_const_data(); 00450 if (normalize) { 00451 for (size_t i = 0; i < totsize; i++) { 00452 if (dm[i] > 0.5) { 00453 square_sum1 += x_data[i]*double(x_data[i]); 00454 square_sum2 += y_data[i]*double(y_data[i]); 00455 result += x_data[i]*double(y_data[i]); 00456 } 00457 } 00458 } else { 00459 for (size_t i = 0; i < totsize; i++) { 00460 if (dm[i] > 0.5) { 00461 result += x_data[i]*double(y_data[i]); 00462 n++; 00463 } 00464 } 00465 } 00466 } else { 00467 // this little bit of manual loop unrolling makes the dot product as fast as sqeuclidean with -O2 00468 for (size_t i=0; i<totsize; i++) result+=x_data[i]*y_data[i]; 00469 00470 if (normalize) { 00471 square_sum1 = image->get_attr("square_sum"); 00472 square_sum2 = with->get_attr("square_sum"); 00473 } else n = totsize; 00474 } 00475 if (normalize) result /= (sqrt(square_sum1*square_sum2)); else result /= n; 00476 } 00477 00478 00479 EXITFUNC; 00480 return (float) (negative*result); 00481 }
|
|
Implements EMAN::Cmp. Definition at line 244 of file cmp.h.
|
|
Get the Cmp's name. Each Cmp is identified by a unique name.
Implements EMAN::Cmp. Definition at line 239 of file cmp.h. References NAME. 00240 { 00241 return NAME; 00242 }
|
|
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 254 of file cmp.h. References EMAN::EMObject::EMDATA, EMAN::EMObject::INT, and EMAN::TypeDict::put(). 00255 { 00256 TypeDict d; 00257 d.put("negative", EMObject::INT, "If set, returns -1 * dot product. Set by default so smaller is better"); 00258 d.put("normalize", EMObject::INT, "If set, returns normalized dot product (cosine of the angle) -1.0 - 1.0."); 00259 d.put("mask", EMObject::EMDATA, "image mask"); 00260 return d; 00261 }
|
|
Definition at line 249 of file cmp.h.
|
|
Definition at line 263 of file cmp.h. Referenced by get_name(). |