Changeset: 019e5733100a for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=019e5733100a Added Files: sql/backends/monet5/k3m/3dtree.c sql/backends/monet5/k3m/3dtree.h sql/backends/monet5/k3m/67_k3m.mal sql/backends/monet5/k3m/67_k3m.sql sql/backends/monet5/k3m/Makefile.ag sql/backends/monet5/k3m/Tests/All sql/backends/monet5/k3m/Tests/k3m.sql sql/backends/monet5/k3m/k3m.c sql/backends/monet5/k3m/k3m.mal sql/backends/monet5/k3m/k3match.h sql/backends/monet5/k3m/median.c sql/backends/monet5/k3m/median.h sql/backends/monet5/k3m/point.c sql/backends/monet5/k3m/point.h Modified Files: configure.ag sql/backends/monet5/Makefile.ag Branch: default Log Message:
K3Match support diffs (truncated from 920 to 300 lines): diff --git a/configure.ag b/configure.ag --- a/configure.ag +++ b/configure.ag @@ -2209,6 +2209,17 @@ if test "x$have_valgrind" != xno; then [if test "x$have_valgrind" = xyes; then AC_MSG_ERROR([no valgrind support found]); fi]) fi +org_have_k3m=no +have_k3m=$org_have_k3m +AC_ARG_WITH(k3m, + AS_HELP_STRING([--with-k3m], + [include Pim Schellart's K3Match library (default=no)]), + have_k3m=$withval) +if test "x$have_k3m" != xno; then + AC_DEFINE(HAVE_K3M, 1, [Define if you want to use the K3Match library]) +fi +AM_CONDITIONAL(HAVE_K3M, test x"$have_k3m" != xno) + # check for sphinxclient org_have_sphinxclient="auto" have_sphinxclient=$org_have_sphinxclient @@ -3454,6 +3465,7 @@ for comp in \ 'java ' \ 'java_control ' \ 'java_jdbc ' \ + 'k3m ' \ 'liblas ' \ 'libxml2 ' \ 'lidar ' \ diff --git a/sql/backends/monet5/Makefile.ag b/sql/backends/monet5/Makefile.ag --- a/sql/backends/monet5/Makefile.ag +++ b/sql/backends/monet5/Makefile.ag @@ -4,7 +4,7 @@ # # Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V. -SUBDIRS = NOT_WIN32?vaults UDF LSST HAVE_GSL?gsl generator +SUBDIRS = NOT_WIN32?vaults UDF LSST HAVE_GSL?gsl generator HAVE_K3M?k3m INCLUDES = ../../include ../../common ../../storage ../../server \ ../../../monetdb5/modules/atoms \ diff --git a/sql/backends/monet5/k3m/3dtree.c b/sql/backends/monet5/k3m/3dtree.c new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/k3m/3dtree.c @@ -0,0 +1,230 @@ +/************************************************************************** + * This file is part of the K3Match library. * + * Copyright (C) 2010 Pim Schellart <p.schell...@astro.ru.nl> * + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this library. If not, see <http://www.gnu.org/licenses/>. * + **************************************************************************/ + +#include <stdlib.h> +#include <stdio.h> + +#include "k3match.h" + +#define SQUARE(x) ((x) * (x)) + +void k3m_build_balanced_tree(node_t *tree, point_t **points, int_t npoints, int axis, int_t *npool) +{ + node_t *current = tree+(*npool); + + int next_axis = (axis + 1) % 3; + + int_t nleft, nright; + + current->left = NULL; + current->right = NULL; + current->axis = axis; + + current->point = k3m_median(points, npoints, current->axis); + + nright = npoints / 2; + nleft = nright - (1 - npoints % 2); + + if (nleft > 0) + { + (*npool)++; + current->left = tree+(*npool); + current->left->parent = &(*current); + k3m_build_balanced_tree(tree, points, nleft, next_axis, npool); + } + + if (nright > 0) + { + (*npool)++; + current->right = tree+(*npool); + current->right->parent = &(*current); + k3m_build_balanced_tree(tree, points+nleft+1, nright, next_axis, npool); + } +} + +void k3m_print_tree(node_t *tree) +{ + if (!tree) return; + + k3m_print_tree(tree->left); + printf("%lu %f %f %f\n", (unsigned long)tree->point->id, tree->point->value[0], tree->point->value[1], tree->point->value[2]); + k3m_print_tree(tree->right); +} + +void k3m_print_dot_tree(node_t *tree) +{ + if (!tree) return; + + if (tree->left != NULL) + { + printf("%lu -> %lu;\n", (unsigned long)tree->point->id, (unsigned long)tree->left->point->id); + } + + if (tree->right != NULL) + { + printf("%lu -> %lu;\n", (unsigned long)tree->point->id, (unsigned long)tree->right->point->id); + } + + printf("%lu [label=\"%lu\\n %f %f %f\"];\n", (unsigned long)tree->point->id, (unsigned long)tree->point->id, + tree->point->value[0], tree->point->value[1], tree->point->value[2]); + + k3m_print_dot_tree(tree->left); + k3m_print_dot_tree(tree->right); +} + +node_t* k3m_closest_leaf(node_t *tree, point_t *point) +{ + node_t* current = tree; + node_t* closest = NULL; + + while (current) + { + closest = current; + + if (point->value[current->axis] > current->point->value[current->axis]) + { + current = current->right; + } + else + { + current = current->left; + } + } + + return closest; +} + +node_t* k3m_nearest_neighbour(node_t *tree, point_t *point) +{ + node_t* nearest = k3m_closest_leaf(tree, point); + node_t* current = nearest; + node_t* sub = NULL; + node_t* last = NULL; + + real_t dn = k3m_distance_squared(nearest->point, point); + real_t dc = dn; + real_t ds; + + while (1) + { + dc = k3m_distance_squared(current->point, point); + if (dc < dn) + { + nearest = current; + dn = dc; + } + + if ((current->point->value[current->axis] - point->value[current->axis]) * (current->point->value[current->axis] - point->value[current->axis]) < dn) + { + if (last == current->left && current->right != NULL) + { + sub = k3m_nearest_neighbour(current->right, point); + + ds = k3m_distance_squared(sub->point, point); + if (ds < dn) + { + nearest = sub; + dn = ds; + } + } + else if (last == current->right && current->left != NULL) + { + sub = k3m_nearest_neighbour(current->left, point); + + ds = k3m_distance_squared(sub->point, point); + if (ds < dn) + { + nearest = sub; + dn = ds; + } + } + } + + if (current == tree) + { + break; + } + else + { + last = current; + current = current->parent; + } + } + + if (nearest == NULL) + { + return tree; + } + else + { + return nearest; + } +} + +int_t k3m_in_range(node_t *tree, point_t **match, point_t *search, real_t ds) +{ + node_t* current = tree; + real_t d[3] = {0, 0, 0}; + int_t nmatch = 0; + real_t dc = 0; + int i = 0; + + while (current) + { + /* calculate distance from current point to search point */ + for (i=0; i<3; i++) + { + d[i] = SQUARE(current->point->value[i] - search->value[i]); + } + dc = d[0] + d[1] + d[2]; + + /* check if current point is within search radius */ + if (dc < ds) + { + current->point->ds = dc; + current->point->neighbour = *match; + *match = &(*current->point); + nmatch++; + } + + /* next point is on the same side of the partition plane as the search point */ + if (search->value[current->axis] > current->point->value[current->axis]) + { + /* check if we need to examine the points on the opposite side */ + if (d[current->axis] < ds) + { + nmatch += k3m_in_range(current->left, match, search, ds); + } + + current = current->right; + } + else + { + /* check if we need to examine the points on the opposite side */ + if (d[current->axis] < ds) + { + nmatch += k3m_in_range(current->right, match, search, ds); + } + + current = current->left; + } + } + + return nmatch; +} + diff --git a/sql/backends/monet5/k3m/3dtree.h b/sql/backends/monet5/k3m/3dtree.h new file mode 100644 --- /dev/null +++ b/sql/backends/monet5/k3m/3dtree.h @@ -0,0 +1,45 @@ +/************************************************************************** + * This file is part of the K3Match library. * + * Copyright (C) 2010 Pim Schellart <p.schell...@astro.ru.nl> * + * * + * This library is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this library. If not, see <http://www.gnu.org/licenses/>. * + **************************************************************************/ + +#ifndef __K3MATCH_3DTREE_H__ _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list