EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes
EMAN::SqEuclideanCmp Class Reference

Squared Euclidean distance normalized by n between 'this' and 'with'. More...

#include <cmp.h>

Inheritance diagram for EMAN::SqEuclideanCmp:
Inheritance graph
[legend]
Collaboration diagram for EMAN::SqEuclideanCmp:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SqEuclideanCmp ()
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 CmpNEW ()

Static Public Attributes

static const string NAME = "sqeuclidean"

Detailed Description

Squared Euclidean distance normalized by n between 'this' and 'with'.

Definition at line 229 of file cmp.h.


Constructor & Destructor Documentation

EMAN::SqEuclideanCmp::SqEuclideanCmp ( ) [inline]

Definition at line 232 of file cmp.h.

Referenced by NEW().

{}

Member Function Documentation

float SqEuclideanCmp::cmp ( EMData image,
EMData with 
) const [virtual]

To compare 'image' with another image passed in through its parameters.

An optional transformation may be used to transform the 2 images.

Parameters:
imageThe first image to be compared.
withThe second image to be comppared.
Returns:
The comparison result. Smaller better by default

Implements EMAN::Cmp.

Definition at line 273 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::Util::goodf(), EMAN::EMData::has_attr(), EMAN::Dict::has_key(), EMAN::EMData::is_complex(), EMAN::EMData::is_fftodd(), nx, ny, EMAN::Cmp::params, EMAN::EMData::process(), EMAN::EMData::set_attr(), EMAN::Dict::set_default(), and EMAN::Cmp::validate_input_args().

{
        ENTERFUNC;
        EMData *with = withorig;
        validate_input_args(image, with);

        int zeromask = params.set_default("zeromask",0);
        int normto = params.set_default("normto",0);

        if (normto) {
                if (zeromask) with = withorig->process("normalize.toimage",Dict("to",image));
                else with = withorig->process("normalize.toimage",Dict("to",image,"ignore_zero",0));
                with->set_attr("deleteme",1);
                if ((float)(with->get_attr("norm_mult"))<=0) {          // This means the normalization inverted the image, a clear probablity of noise bias, so we undo the normalization
                        delete with;
                        with=withorig;
                }
        }

        const float *const y_data = with->get_const_data();
        const float *const x_data = image->get_const_data();
        double result = 0.;
        float n = 0.0f;
        if(image->is_complex() && with->is_complex()) {
        // Implemented by PAP  01/09/06 - please do not change.  If in doubts, write/call me.
                int nx  = with->get_xsize();
                int ny  = with->get_ysize();
                int nz  = with->get_zsize();
                nx = (nx - 2 + with->is_fftodd()); // nx is the real-space size of the input image
                int lsd2 = (nx + 2 - nx%2) ; // Extended x-dimension of the complex image

                int ixb = 2*((nx+1)%2);
                int iyb = ny%2;
                //
                if(nz == 1) {
                //  it looks like it could work in 3D, but it does not, really.
                for ( int iz = 0; iz <= nz-1; iz++) {
                        double part = 0.;
                        for ( int iy = 0; iy <= ny-1; iy++) {
                                for ( int ix = 2; ix <= lsd2 - 1 - ixb; ix++) {
                                                size_t ii = ix + (iy  + iz * ny)* lsd2;
                                                part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                }
                        }
                        for ( int iy = 1; iy <= ny/2-1 + iyb; iy++) {
                                size_t ii = (iy  + iz * ny)* lsd2;
                                part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                part += (x_data[ii+1] - y_data[ii+1])*double(x_data[ii+1] - y_data[ii+1]);
                        }
                        if(nx%2 == 0) {
                                for ( int iy = 1; iy <= ny/2-1 + iyb; iy++) {
                                        size_t ii = lsd2 - 2 + (iy  + iz * ny)* lsd2;
                                        part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                        part += (x_data[ii+1] - y_data[ii+1])*double(x_data[ii+1] - y_data[ii+1]);
                                }

                        }
                        part *= 2;
                        part += (x_data[0] - y_data[0])*double(x_data[0] - y_data[0]);
                        if(ny%2 == 0) {
                                int ii = (ny/2  + iz * ny)* lsd2;
                                part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                        }
                        if(nx%2 == 0) {
                                int ii = lsd2 - 2 + (0  + iz * ny)* lsd2;
                                part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                if(ny%2 == 0) {
                                        int ii = lsd2 - 2 +(ny/2  + iz * ny)* lsd2;
                                        part += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                }
                        }
                        result += part;
                }
                n = (float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz;

                } else { //This 3D code is incorrect, but it is the best I can do now 01/09/06 PAP
                int ky, kz;
                int ny2 = ny/2; int nz2 = nz/2;
                for ( int iz = 0; iz <= nz-1; iz++) {
                        if(iz>nz2) kz=iz-nz; else kz=iz;
                        for ( int iy = 0; iy <= ny-1; iy++) {
                                if(iy>ny2) ky=iy-ny; else ky=iy;
                                for ( int ix = 0; ix <= lsd2-1; ix++) {
                                // Skip Friedel related values
                                if(ix>0 || (kz>=0 && (ky>=0 || kz!=0))) {
                                                size_t ii = ix + (iy  + iz * ny)* (size_t)lsd2;
                                                result += (x_data[ii] - y_data[ii])*double(x_data[ii] - y_data[ii]);
                                        }
                                }
                        }
                }
                n = ((float)nx*(float)ny*(float)nz*(float)nx*(float)ny*(float)nz)/2.0f;
                }
        } else {                // real space
                size_t totsize = (size_t)image->get_xsize()*image->get_ysize()*image->get_zsize();
                if (params.has_key("mask")) {
                  EMData* mask;
                  mask = params["mask"];
                  const float *const dm = mask->get_const_data();
                  for (size_t i = 0; i < totsize; i++) {
                           if (dm[i] > 0.5) {
                                double temp = x_data[i]- y_data[i];
                                result += temp*temp;
                                n++;
                           }
                  }
                } 
                else if (zeromask) {
                        n=0;
                        for (size_t i = 0; i < totsize; i++) {
                                if (x_data[i]==0 || y_data[i]==0) continue;
                                double temp = x_data[i]- y_data[i];
                                result += temp*temp;
                                n++;
                        }
                        
                }
                else {
                  for (size_t i = 0; i < totsize; i++) {
                                double temp = x_data[i]- y_data[i];
                                result += temp*temp;
                   }
                   n = (float)totsize;
                }
        }
        result/=n;

        EXITFUNC;
        if (with->has_attr("deleteme")) delete with;
        float ret = (float)result;
        if (!Util::goodf(&ret)) return FLT_MAX;
        return ret;
}
string EMAN::SqEuclideanCmp::get_desc ( ) const [inline, virtual]

Implements EMAN::Cmp.

Definition at line 241 of file cmp.h.

                {
                        return "Squared Euclidean distance (sum(a - b)^2)/n.";
                }
string EMAN::SqEuclideanCmp::get_name ( ) const [inline, virtual]

Get the Cmp's name.

Each Cmp is identified by a unique name.

Returns:
The Cmp's name.

Implements EMAN::Cmp.

Definition at line 236 of file cmp.h.

References NAME.

                {
                        return NAME;
                }
TypeDict EMAN::SqEuclideanCmp::get_param_types ( ) const [inline, virtual]

Get Cmp parameter information in a dictionary.

Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.

Returns:
A dictionary containing the parameter info.

Implements EMAN::Cmp.

Definition at line 251 of file cmp.h.

References EMAN::EMObject::EMDATA, EMAN::EMObject::INT, and EMAN::TypeDict::put().

                {
                        TypeDict d;
                        d.put("mask", EMObject::EMDATA, "image mask");
                        d.put("zeromask", EMObject::INT, "If set, zero pixels in either image will be excluded from the statistics");
                        d.put("normto",EMObject::INT,"If set, 'with' is normalized to 'this' before computing the distance");
                        return d;
                }
static Cmp* EMAN::SqEuclideanCmp::NEW ( ) [inline, static]

Definition at line 246 of file cmp.h.

References SqEuclideanCmp().

                {
                        return new SqEuclideanCmp();
                }

Member Data Documentation

const string SqEuclideanCmp::NAME = "sqeuclidean" [static]

Definition at line 260 of file cmp.h.

Referenced by get_name().


The documentation for this class was generated from the following files: