This commit is contained in:
angi
2007-07-11 19:58:21 +00:00
parent 9e849f0ba6
commit 9b15bbecb3
12 changed files with 135 additions and 60 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
0, 0, 0
0, 0, 0
0, 0, 0
0, 1, 3
1, 0, 2
3, 2, 0
0, 10, 30
10, 0, 20
30, 20, 0
+9 -1
View File
@@ -33,9 +33,17 @@ librule(
deplibs = ["fastlib:fastlib",":datapack",":metrics",":matcher"]
)
librule(
name = "unit_test",
sources = ["tests.cc"],
headers = ["tests.h"],
deplibs =
["fastlib:fastlib",":datapack",":metrics",":matcher",":naive",":multi_matcher"]
)
binrule(
name = "npoint",
sources = ["main.cc"],
headers = ["globals.h"],
deplibs = ["fastlib:fastlib",":datapack",":metrics",":matcher",":naive"]
deplibs = ["fastlib:fastlib",":datapack",":metrics",":matcher",":naive",":unit_test"]
)
+2 -1
View File
@@ -13,9 +13,10 @@
#define RECURSE 0
#define LEAF_SIZE 20
#define MAX_N 25
#define MAX_N 10
extern FILE *output;
extern int count_all_permutations;
extern char *unit_test;
#endif
+26 -1
View File
@@ -14,6 +14,7 @@
* --n=[size of n-tuple (default 2)]
* --nweights=[number of weights (default 0)]
* --metric=[csv file containing the desired metric]
* --test=[test name]
* etc.
*/
@@ -24,8 +25,10 @@
#include "matcher.h"
#include "datapack.h"
#include "naive.h"
#include "tests.h"
/* Initialize any global variables here. */
/* Note: Probably useless. */
FILE *output = stderr;
int count_all_permutations = 0;
@@ -37,6 +40,29 @@ int main(int argc, char *argv[])
{
fx_init(argc,argv);
/* First we check if we want to run a test */
const char *test = fx_param_str(NULL,"test","none");
String tmp;
tmp.Copy(test);
if ( tmp.CompareTo("none") ) {
if ( !tmp.CompareTo("permutations") ) {
const int n = fx_param_int(NULL,"n",2);
if ( !PASSED(test_permutation_generator(n)) ) {
fprintf(output,"\n\nPermutation generator failed for n = %d.\n\n",n);
}
else {
fprintf(output,"\n\nPermutation generator worked for n = %d.\n\n",n);
}
}
fx_done();
exit(1);
}
tmp.Destruct();
/* After the tests are done get the parameters and run the actual program */
const char *data_file = fx_param_str_req(NULL,"data");
const char *matcher_file = fx_param_str_req(NULL,"matcher");
const char *metric_file = fx_param_str(NULL,"metric","default");
@@ -50,7 +76,6 @@ int main(int argc, char *argv[])
Matcher matcher;
Metric metric;
Vector count;
String tmp;
int i;
tmp.Copy(output_file);
+26 -31
View File
@@ -215,6 +215,7 @@ success_t Matcher::AnyMatch(const DataPack data, const Vector index, const Metri
}
else {
int ready = 0;
index_t i;
success_t match = SUCCESS_PASS;
Vector tau;
tau.Init(n);
@@ -223,15 +224,11 @@ success_t Matcher::AnyMatch(const DataPack data, const Vector index, const Metri
fprintf(output,"Fatal error: could not generate the first permutation\n");
exit(1);
}
/*
for (i=0;i<n;i++) {
tau[i] = i;
}
*/
do {
index_t i,j;
index_t j;
ready = 1; // be optimistic about the current permutation
for (i=0;i<n;i++) {
for (j=i+1;j<n && PASSED(match);j++) {
index_t index_i = index[tau[i]], index_j = index[tau[j]];
@@ -253,6 +250,7 @@ success_t Matcher::AnyMatch(const DataPack data, const Vector index, const Metri
success_t can_make_new_permutation = generate_next_permutation(tau);
ready = 0;
if ( !PASSED(can_make_new_permutation) ) { // we're out of permutations
fprintf(output,"No new permutation avaliable\n\n");
return SUCCESS_FAIL; // report that no match could be found
}
}
@@ -278,11 +276,7 @@ success_t Matcher::AnyMatch(const Matrix data, const Vector index, const Metric
fprintf(output,"Fatal error: could not generate the first permutation\n");
exit(1);
}
/*
for (i=0;i<n;i++) {
tau[i] = i;
}
*/
do {
index_t i,j;
ready = 1; // be optimistic about the current permutation
@@ -335,9 +329,10 @@ success_t Matcher::AnyMatch(const Matrix distances) const {
fprintf(output,"Fatal error: could not generate the first permutation\n");
exit(1);
}
do {
index_t i,j;
ready = 1; // be optimistic about the current permutation
ready = 1;
for (i=0;i<n;i++) {
for (j=i+1;j<n && PASSED(match);j++) {
@@ -350,13 +345,13 @@ success_t Matcher::AnyMatch(const Matrix distances) const {
}
}
if ( PASSED(match) ) { // we got a match... yupii
if ( PASSED(match) ) {
return SUCCESS_PASS;
}
else { // gotta try something new
else {
ready = 0;
if ( !PASSED(generate_next_permutation(distances,tau,dist) ) ) { // out of permutations
return SUCCESS_FAIL; // report that no match was found
if ( !PASSED(generate_next_permutation(distances,tau,dist) ) ) {
return SUCCESS_FAIL;
}
}
}
@@ -436,32 +431,32 @@ success_t generate_first_permutation(Vector &tau) {
success_t generate_next_permutation(Vector &tau) {
index_t i;
index_t n = tau.length();
index_t top = n - 1;
int is_valid = 1;
index_t top = n-1;
int ok_so_far = 0;
do {
if ( is_valid && top < (n-1) ) {
if (ok_so_far) {
top += 1;
tau[top] = -1;
}
is_valid = 1;
tau[top] += 1;
ok_so_far = 1;
if ( tau[top] > (n-1) ) {
if (tau[top] > n-1) {
ok_so_far = 0;
tau[top] = -1;
top -= 1;
if (top < 0) {
return SUCCESS_FAIL;
}
}
if (top < 0) {
return SUCCESS_FAIL;
}
for (i=0;i<top;i++) {
if (tau[i] == tau[top]) {
is_valid = 0;
for (i=0;i<top;i++) {
if (tau[top] == tau[i]) {
ok_so_far = 0;
}
}
}
while ( top < (n-1) && !is_valid );
while (top < (n-1) || !ok_so_far);
return SUCCESS_PASS;
}
+2 -2
View File
@@ -1,6 +1,6 @@
/**
* @author Angela N. Grigoroaia
* @file metrics.h
* @author: Angela N. Grigoroaia
* @file: metrics.h
*
* @description: Stuff that takes care of distance computations.
**/
+2 -2
View File
@@ -16,7 +16,7 @@ void estimate_multi_matcher_list(const Matrix data, const Metric metric) {
}
double estimate_diameter(const Matrix data, const Metric metric) const {
double estimate_diameter(const Matrix data, const Metric metric) {
double diam = -1;
index_t x,y,z;
@@ -31,7 +31,7 @@ double estimate_diameter(const Matrix data, const Metric metric) const {
index_t find_farthest_neighbor(const Matrix data, const index_t x,
const Metric metric) const {
const Metric metric) {
double max_dist_so_far = -1;
index_t result = -1, i;
+3 -3
View File
@@ -20,7 +20,7 @@
* matchers over which we wil run naive or single tree n-point. We can also use
* it for a divide & conquer approach (dual-tree, multi-matcher n-point).
*/
void estimate_multi_matcher_list(const Matrix data, const Metric metric) const;
void estimate_multi_matcher_list(const Matrix data, const Metric metric);
/**
* Estimate the largest distance between any two points. This should be useful
@@ -31,7 +31,7 @@ void estimate_multi_matcher_list(const Matrix data, const Metric metric) const;
* 3. Find z such that dist(y,z) is maximized
* 4. Return dist (y,z)
*/
double estimate_diameter(const Matrix data, const Metric metric) const;
double estimate_diameter(const Matrix data, const Metric metric);
/**
* Given x, find y such that dist(x,y) is maximum.
@@ -40,7 +40,7 @@ double estimate_diameter(const Matrix data, const Metric metric) const;
* the index of y.
*/
index_t find_farthest_neighbor(const Matrix data, const index_t x,
const Metric metric) const;
const Metric metric);
#endif
+2 -16
View File
@@ -13,14 +13,14 @@
Vector naive_npoint(DataPack data, Matcher matcher, Metric metric) {
if ( count_all_permutations && matcher.is_simple() ) {
if (count_all_permutations && matcher.is_simple()) {
Vector tmp;
tmp.Copy(symmetric_naive_npoint(data,matcher,metric));
la::Scale(math::Factorial(matcher.size()),&tmp);
return tmp;
}
if ( count_all_permutations ) {
if (count_all_permutations) {
return asymmetric_naive_npoint(data,matcher,metric);
}
@@ -52,13 +52,6 @@ Vector symmetric_naive_npoint(DataPack data, Matcher matcher, Metric metric)
/* Running the actual naive loop */
do {
if (PASSED(matcher.Matches(data, index, metric))) {
/*
fprintf(output,"Found a match for indexes:");
for (i = 0; i < n; i++) {
fprintf(output," %3.0f", index[i]);
}
fprintf(output,"\n");
*/
results[0] += 1.0;
/* Updating the weighted count(s) if needed. */
@@ -130,13 +123,6 @@ Vector asymmetric_naive_npoint(DataPack data, Matcher matcher, Metric metric)
do {
int is_valid = 1;
if (PASSED(matcher.Matches(data, index, metric))) {
/*
fprintf(output,"Found a match for indexes:");
for (i = 0; i < n; i++) {
fprintf(output," %3.0f", index[i]);
}
fprintf(output,"\n");
*/
results[0] += 1.0;
/* Updating the weighted count(s) if needed. */
+5
View File
@@ -2,6 +2,11 @@ main.cc
- figure out the arguments and call appropriate part of the code
+ depends on: all
tests.c
tests.cc
- unit tests to ensure proper behavior of all code
+ depends on: all
globals.h
- define global variables and handy constants
+ depends on: none
+36
View File
@@ -0,0 +1,36 @@
/**
* @author: Angela Grigoroaia
* @file: tests.cc
*
* @description: Simple unit tests for npoint.
*/
#include "fastlib/fastlib.h"
#include "globals.h"
#include "datapack.h"
#include "metrics.h"
#include "matcher.h"
#include "naive.h"
#include "tests.h"
success_t test_permutation_generator(int n) {
DEBUG_ASSERT (n > 0);
Vector tau;
double count = 0.0;
tau.Init(n);
if ( !PASSED(generate_first_permutation(tau)) ) {
return SUCCESS_FAIL;
}
count += 1.0;
while ( PASSED(generate_next_permutation(tau)) ) {
count += 1.0;
}
if ( count != math::Factorial(n) ) {
return SUCCESS_FAIL;
}
return SUCCESS_PASS;
}
+19
View File
@@ -0,0 +1,19 @@
/**
* @author: Angela Grigoroaia
* @file: tests.h
*
* @description: Simple unit tests for npoint.
*/
#ifndef TESTS_H
#define TEST_H
/**
* This can be used to test if we are properly generating all the possible
* permutations of size n. It counts all the permutations that we generate and
* checks if the final value is n!.
*/
success_t test_permutation_generator(int n);
#endif