head     1.1;
branch   ;
access   ;
symbols  ;
locks    ; strict;
comment  @@;


1.1
date     92.07.01.03.54.19;  author fischer;  state Exp;
branches ;
next     ;


desc
@Nicely formatted output of relational tests, exhaustively over
a small range of INTEGER Points, and randomly over a small range
of REAL Points.
@



1.1
log
@Initial revision
@
text
@// Emacs: -*- C++ -*-

#include <Point.h>
#include <ACG.h>

#define TBL_SIZE 100

int main(int argc, char**argv)
{
    void	print_relational_table(char*, Point[], int);
    void	make_INTEGER_points(Point[], int, ACG&);             // random integer valued
    void	make_REAL_points(Point[], int, ACG&);                // random integer valued
    void	sort_points(Point[], int);

    ACG		generator;    
    Point       points_list[TBL_SIZE];
    int		number_real_points;
    int		number_integer_points;


    //////// INTEGER POINTS ////////

    number_integer_points = 0;

    for (Coord c0 = -1; c0 <= 1; c0++) 
	for (Coord c1 = -1; c1 <= 1; c1++)
	    points_list[number_integer_points++] = (c0, c1);

    //  I want to generate these on the end of points_list so
    //  I can check the lexicographic sorting routine built on Pointcmp.
    
    for (c0 = -1; c0 <= 1; c0++) 
	points_list[number_integer_points++] = (c0);
    
    sort_points(points_list, number_integer_points);

    print_relational_table("INTEGER Points relational tests", points_list, number_integer_points);

    //////// REAL POINTS ////////

    cout << "\f";
    number_real_points = 15;
    make_REAL_points(points_list, number_real_points, generator);
    sort_points(points_list, number_real_points);
    print_relational_table("REAL Points relational tests", points_list, number_real_points);
}

void
make_REAL_points(Point point_array[], int number_points, ACG& generator)
{
    Point	make_random_point(int, int, int, NumericType, ACG&); // dimension, bottom, top, type

    for (int i = 0; i < ( 2 * number_points / 3); i++) 
	point_array[i] = make_random_point(2, -1, +1, REAL, generator);
    for (i = ( 2 * number_points / 3); i < number_points;  i++) 
	point_array[i] = make_random_point(1, -1, +1, REAL, generator);
}	

void
make_INTEGER_points(Point point_array[], int number_points, ACG& generator)
{
    Point	make_random_point(int, int, int, NumericType, ACG&); // dimension, bottom, top, type

    for (int i = 0; i < number_points; i++) 
	point_array[i] = make_random_point(2, -2, +2, INTEGER, generator);
}	

void
print_relational_table(char* label, Point point_array[], int number_points)
{
//  Run all relational ops on an array of points, printing a table

    char first_page = 1;
    
    cout << label << "\n" << "<    <=   ==   >=   >    !=\tArguments\n";
    for (int i = 0; i < number_points; i++) {
        for (int j = 0; j < number_points; j++) {

	    if (((i * number_points + j) % 60) == 0) {
		if (first_page)
		    first_page = 0;
		else
		    cout << "\f" << label << "(continued)\n" << "<    <=   ==   >=   >    !=\tArguments\n";
	    }
	    cout << (int) (point_array[i] <  point_array[j]) << "    ";
	    cout << (int) (point_array[i] <= point_array[j]) << "    ";
	    cout << (int) (point_array[i] == point_array[j]) << "    ";
	    cout << (int) (point_array[i] >= point_array[j]) << "    ";
	    cout << (int) (point_array[i] >  point_array[j]) << "    ";
	    cout << (int) (point_array[i] != point_array[j]) << "\t";
	    cout << point_array[i] << "\t" << point_array[j] << "\n";
	}
    }
}


Point
make_random_point(int dimensions, int bottom, int top, NumericType type, ACG& gen)
{
    // There is a fencepost error in the range of random points for integers.
    
    Coord coordinate;
    int   range;

    if (top < bottom) {
	int temp = top;
	top = bottom;
	bottom = temp;
    }
    range = top - bottom;

    if (type == REAL)
      switch (dimensions) {
      case 0:
          return Point();
      case 1:
          coordinate = (bottom +  gen.asFloat() * range);
          return Point(coordinate);
      case 2:
          return Point(bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range);
      case 3:
          return Point(bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range);
      case 4:
          return Point(bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range);
      case 5:
          return Point(bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range,
                       bottom +  gen.asFloat() * range);
      default:
          return Point(0.0, 0.0, 0.0, 0.0, 0.0);    // shouldn't happen
      }
    else if (type == INTEGER)
      switch (dimensions) {
      case 0:
          return Point();
      case 1:
          coordinate = (bottom + int(gen.asFloat() * range));
          return Point(coordinate);
      case 2:
          return Point(bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range));
      case 3:
          return Point(bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range));
      case 4:
          return Point(bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range));
      case 5:
          return Point(bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range),
                       bottom +  int(gen.asFloat() * range));
      default:
          return Point(0, 0, 0, 0, 0);    // shouldn't happen
      }
    else {
      cout << "random_point: NumericType " << type << " is not one of REAL, INTEGER\n";
      exit(1);
    }
    return Point(-1, -1, -1, -1, -1);    // can\'t happen, but make compiler shut up.
}

void
sort_points(Point points[], int size)
{
    // Very stupid bubble sorter. Please fix (where *is* my copy of Sedgwick?).

    char my_less_than(const Point&, const Point&);

    Point temp;
    for (int i = 0; i < size; i++) {
	for (int j = i; j < size; j++) {
	    if (my_less_than(points[i], points[j])) {
		temp = points[i];
		points[i] = points[j];
		points[j] = temp;
	    }
	}
    }
}

char
my_less_than (const Point& p0, const Point& p1)
{
    char bool = Pointcmp(p0, p1);
    if (bool == -1)
	return (char) 1;
    else if (bool == 0) 				// may be equal iff zero extended
	return (p0.dimensions() < p1.dimensions());	// so check
    else
	return (char) 0;
}
@
