include/geometry/weighted-l2distance.h
author Aravindakshan Babu <akshan@stanford.edu>
Thu, 08 Jul 2010 23:50:39 -0700
branchdev
changeset 217 64a272a34cb2
parent 207 6f1ed27850c8
permissions -rw-r--r--
Added extra functionality to Point class( an iterator ) and PersistenceDiagram( dimension property and __len__ func ). persistence-diagram.h: Added a new read-only dimension member and member function to access it. With a new constructor that that takes in an int type to initialize dimension. persistence-diagram.cpp: Added new bp::init constructor. Takes in an integer type to initialize the dimension. Exposed the dimension property. Exposed the size property via a __len__ method. __init__.py: Added an iterator for Point objects. This iterates over the coords and then the data( if present ).

#ifndef __L2_DISTANCE_H__
#define __L2_DISTANCE_H__

#include <utilities/types.h>
#include <utilities/log.h>

#include <vector>
#include <fstream>
#include <functional>
#include <cmath>
#include <string>
#include <sstream>


typedef     std::vector<double>                                     Point;
typedef     std::vector<Point>                                      PointContainer;

struct WeightedL2Distance:
    public std::binary_function<const Point&, const Point&, double>
{
    result_type     operator()(const Point& p1, const Point& p2) const
    {
        AssertMsg(p1.size() == p2.size(), "Points must be in the same dimension (in L2Distance): dim1=%d, dim2=%d", p1.size()-1, p2.size()-1);

        /* the distance of a point to itself is the radius at which the "power distance" ball around it appears:
           d(p,p) := sqrt(-w_p) */
        if (p1 == p2)
            return sqrt(-p1[p1.size()-1]);

        /* otherwise, the distance is the radius at which the power balls around p, q intersect:
           d(p,q) := sqrt( ||p-q||^2 - w_p - w_q ) */
        result_type sq_l2dist = 0;
        for (size_t i = 0; i < p1.size()-1; ++i)
            sq_l2dist += (p1[i] - p2[i])*(p1[i] - p2[i]);
        return sqrt(sq_l2dist - p1[p1.size()-1] - p2[p2.size()-1]);
    }
};

void    read_weighted_points(const std::string& infilename, PointContainer& points)
{
    std::ifstream in(infilename.c_str());
    std::string   line;
    while(std::getline(in, line))
    {
        if (line[0] == '#') continue;               // comment line in the file
        std::stringstream linestream(line);
        double x;
        points.push_back(Point());
        while (linestream >> x)
            points.back().push_back(x);
    }
}

#endif // __L2_DISTANCE_H__