144 lines
3.6 KiB
Plaintext
144 lines
3.6 KiB
Plaintext
|
|
|
|
|
|
This document describes, how to include new
|
|
distance functions into the general tree algebra, at the example point.
|
|
|
|
|
|
STEP 1 : Implement a mapping from Secondo data type to void*
|
|
============================================================
|
|
|
|
1.1. Declare the function
|
|
---------------------------
|
|
In the file DistDataReg.h, declare a function like:
|
|
|
|
static DistData *getDataPoint(const void *attr);
|
|
|
|
|
|
1.2 implement the function
|
|
---------------------------
|
|
|
|
This step changes the file DistDataReg.cpp
|
|
|
|
Firstly, add missing include into this file
|
|
|
|
#include "Coord.h"
|
|
#include "Point.h"
|
|
|
|
|
|
Secondly, implement this function
|
|
|
|
DistData* DistDataReg::getDataPoint(const void* attr) {
|
|
// cast to the correct type
|
|
const Point* point = static_cast<const Point*>(attr);
|
|
// special treatment for undefined values
|
|
if(!point->IsDefined()){ // undefined points value
|
|
return new DistData(0,0);
|
|
}
|
|
// serialize the point
|
|
Coord x = point->GetX();
|
|
Coord y = point->GetY();
|
|
|
|
char buffer[2*sizeof(Coord)];
|
|
memcpy(buffer, &x, sizeof(Coord));
|
|
memcpy(buffer + sizeof(Coord), &y, sizeof(Coord));
|
|
return new DistData(2*sizeof(Coord) , buffer);
|
|
}
|
|
|
|
|
|
1.3. Register this function
|
|
-----------------------------
|
|
|
|
Navigate to the function DistDataReg::initialize()
|
|
in file DistDataReg.cpp and add a call like:
|
|
|
|
addInfo(DistDataInfo(
|
|
DDATA_NATIVE, DDATA_NATIVE_DESCR, DDATA_NATIVE_ID,
|
|
Point::BasicType(), getDataPoint));
|
|
|
|
The first parameters are predefined values. If you are not hapy with them,
|
|
define new value and use them here.
|
|
|
|
The fourth parameter contains the Type name used in Secondo.
|
|
The last parameter is the function defined before.
|
|
|
|
|
|
|
|
|
|
STEP 2: Computing the distance
|
|
===============================
|
|
|
|
1.1 Declaring the function
|
|
--------------------------
|
|
|
|
Firstly, change the file DistfunReg.h and add a declaration of the distance function
|
|
and possible new descriptions.
|
|
|
|
static void euclidPoint(
|
|
const DistData *data1, const DistData *data2,
|
|
double &result);
|
|
|
|
|
|
1.2 implement the function in file DistfunReg.cpp
|
|
--------------------------
|
|
|
|
add missing includes
|
|
#include "Coord.h"
|
|
#include "Point.h"
|
|
|
|
void DistfunReg::euclidPoint(
|
|
const DistData *data1, const DistData *data2,
|
|
double &result) {
|
|
|
|
// handle undefined values
|
|
if(data1->size()==0 && data2->size()==0){
|
|
result = 0;
|
|
return ;
|
|
}
|
|
if(data1->size()==0 || data2->size()==0){
|
|
result = numeric_limits<double>::max();
|
|
return;
|
|
}
|
|
|
|
Coord x1;
|
|
Coord y1;
|
|
memcpy(&x1, data1->value(), sizeof(Coord));
|
|
memcpy(&y1, (char*) data1->value() + sizeof(Coord), sizeof(Coord));
|
|
Coord x2;
|
|
Coord y2;
|
|
memcpy(&x2, data2->value(), sizeof(Coord));
|
|
memcpy(&y2, (char*) data2->value() + sizeof(Coord), sizeof(Coord));
|
|
result = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
1.3 register the function
|
|
-------------------------
|
|
|
|
navigate to function DistfunReg::initialize() in file DistfunReg.cpp.
|
|
and add a function call
|
|
|
|
|
|
addInfo(DistfunInfo(
|
|
DFUN_EUCLID, DFUN_EUCLID_DESCR,
|
|
euclidPoint,
|
|
DistDataReg::getInfo(Point::BasicType(), DDATA_NATIVE),
|
|
DFUN_IS_METRIC | DFUN_IS_DEFAULT));
|
|
|
|
The first two parameters are the name and a description of the function.
|
|
If predefined names and descriptions are not sufficient, just add new definitions.
|
|
|
|
The third parameter is the distance function itself.
|
|
|
|
|
|
The next argument is build up from the name of the data type in secondo and the name
|
|
in of the conversion function defined in step1.
|
|
|
|
The last parameter determines that this distance function describes a metric and is to use
|
|
as the default function. See code for additional flags.
|
|
|
|
|