/* This is -*- C -*- */
/* vim: set sw=2: */
/* $Id: datatable1.c,v 1.4 2002/01/14 05:01:25 trow Exp $ */
/*
* datatable1.c
*
* Copyright (C) 2001 The Free Software Foundation, Inc.
*
* Developed by Jon Trowbridge <trow@gnu.org>
*/
/*
* This program 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 2 of the
* License, or (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#include <config.h>
#include <math.h>
#include <string.h>
#include "guppi-test-framework.h"
#include <guppi-data-table.h>
#include <guppi-useful.h>
#include <guppi-data-init.h>
#define eq(x,y) (fabs((x)-(y))<1e-12*MIN(1+fabs(x),1+fabs(y)))
static gboolean
plugins (gpointer foo)
{
guppi_plug_in_path_set ("../../plug-ins/data_impl/data_table");
guppi_plug_in_spec_find_all ();
return guppi_plug_in_count () > 0;
}
static gboolean
construct (gpointer foo)
{
GuppiData *d;
guppi_test_subtest ("Create");
d = guppi_data_new ("GuppiDataTableCore");
if (d == NULL)
return FALSE;
guppi_test_subtest ("Destroy");
guppi_unref (d);
return TRUE;
}
static gboolean
sanity_check (GuppiDataTable *tab, gint r, gint c)
{
gint R, C, i, j;
guppi_test_subtest ("sanity-checking dimensions");
guppi_data_table_get_dimensions (tab, &R, &C);
if (r != R || c != C || R != guppi_data_table_get_row_count (tab) || C != guppi_data_table_get_col_count (tab)) {
g_print ("have (%d, %d), expected (%d, %d)\n", R, C, r, c);
return FALSE;
}
guppi_test_subtest ("checking initialization to zero");
for (i = 0; i < R; ++i) {
for (j = 0; j < C; ++j) {
if (guppi_data_table_get_entry (tab, i, j) > 1e-16)
return FALSE;
}
}
guppi_test_subtest ("checking label initialization to null");
for (i = 0; i < R; ++i) {
if (guppi_data_table_get_row_label (tab, i) != NULL)
return FALSE;
}
for (i = 0; i < C; ++i) {
if (guppi_data_table_get_col_label (tab, i) != NULL)
return FALSE;
}
return TRUE;
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
static gint changed = 0;
static gint changed_r = -1, changed_c = -1;
static void
changed_entry_cb (GuppiDataTable *tab, gint r0, gint c0, gint r1, gint c1)
{
++changed;
if (r0 != r1)
r0 = r1 = -1;
if (c0 != c1)
c0 = c1 = -1;
changed_r = r0;
changed_c = c0;
}
static gboolean
basic_ops (gpointer foo)
{
GuppiDataTable *tab;
gint i, j, k;
gchar *str;
guppi_test_subtest ("Constructing table");
tab = GUPPI_DATA_TABLE (guppi_data_new ("GuppiDataTableCore"));
if (tab == NULL)
return FALSE;
gtk_signal_connect (GTK_OBJECT (tab),
"changed_table_entries",
GTK_SIGNAL_FUNC (changed_entry_cb),
NULL);
for (k = 0; k < 2; ++k) {
gint R = 10 + 5 * k, C = 20 - 10 * k;
str = guppi_strdup_printf ("Setting dimensions (pass #%d)", k+1);
guppi_test_subtest (str);
guppi_free (str);
guppi_data_table_set_dimensions (tab, R, C);
if (! sanity_check (tab, R, C))
return FALSE;
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
guppi_test_subtest ("Get/Set entries");
for (i = 0; i < guppi_data_table_get_row_count (tab); ++i) {
for (j = 0; j < guppi_data_table_get_col_count (tab); ++j) {
changed = 0;
guppi_data_table_set_entry (tab, i, j, 18*i - 7*j);
if (changed != 1 || changed_r != i || changed_c != j) {
g_print ("changed=%d changed_r=%d changed_c=%d i=%d j=%d\n", changed, changed_r, changed_c, i, j);
return FALSE;
}
}
}
for (i = 0; i < guppi_data_table_get_row_count (tab); ++i) {
for (j = 0; j < guppi_data_table_get_col_count (tab); ++j) {
if (guppi_data_table_get_entry (tab, i, j) != 18*i - 7*j)
return FALSE;
}
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
guppi_test_subtest ("Get/Set labels");
for (i = 0; i < guppi_data_table_get_row_count (tab); ++i) {
str = guppi_strdup_printf ("Row Label #%d", i);
guppi_data_table_set_row_label (tab, i, str);
guppi_free (str);
}
for (i = 0; i < guppi_data_table_get_col_count (tab); ++i) {
str = guppi_strdup_printf ("Column Label #%d", i);
guppi_data_table_set_col_label (tab, i, str);
guppi_free (str);
}
for (i = 0; i < guppi_data_table_get_row_count (tab); ++i) {
str = guppi_strdup_printf ("Row Label #%d", i);
if (strcmp (guppi_data_table_get_row_label (tab, i), str))
return FALSE;
guppi_free (str);
}
for (i = 0; i < guppi_data_table_get_col_count (tab); ++i) {
str = guppi_strdup_printf ("Column Label #%d", i);
if (strcmp (guppi_data_table_get_col_label (tab, i), str))
return FALSE;
guppi_free (str);
}
}
guppi_test_subtest ("Destroy");
guppi_unref (tab);
return TRUE;
}
static double *
slice (GuppiDataTable *tab, GuppiDataTableSpan span, gint i, gint *N)
{
double *sl;
gint n;
gint j, r, c;
GuppiDataTableSpan perp_span = span == GUPPI_TABLE_ROW ? GUPPI_TABLE_COL : GUPPI_TABLE_ROW;
n = guppi_data_table_get_span_count (tab, perp_span);
if (N)
*N = n;
sl = guppi_new (double, n);
for (j = 0; j < n; ++j) {
if (span == GUPPI_TABLE_ROW) {
r = i;
c = j;
} else {
r = j;
c = i;
}
sl[j] = guppi_data_table_get_entry (tab, r, c);
}
return sl;
}
static gboolean
stats (gpointer ptr)
{
GuppiDataTable *tab;
GuppiDataTableSpan span;
gint i, j, k, N;
double *sl, sum, abs_sum, min, max, x;
gboolean problem = FALSE;
const gint R=62, C=220;
guppi_test_subtest ("Constructing table");
tab = GUPPI_DATA_TABLE (guppi_data_new ("GuppiDataTableCore"));
if (tab == NULL)
return FALSE;
guppi_data_table_set_dimensions (tab, R, C);
for (i = 0; i < R; ++i)
for (j = 0; j < C; ++j)
guppi_data_table_set_entry (tab, i, j, 7 + 38.32 * i - j * j );
sanity_check (tab, R, C);
guppi_test_subtest ("Verifying stats");
for (k = 0; k < 2; ++k) {
span = k ? GUPPI_TABLE_ROW : GUPPI_TABLE_COL;
for (i = 0; i < guppi_data_table_get_span_count (tab, span); ++i) {
sl = slice (tab, span, i, &N);
sum = abs_sum = 0;
min = max = sl[0];
for (j = 0; j < N; ++j) {
sum += sl[j];
abs_sum += fabs (sl[j]);
if (sl[j] < min)
min = sl[j];
if (sl[j] > max)
max = sl[j];
}
if (! eq (sum, x = guppi_data_table_get_sum (tab, span, i))) {
g_print ("bad sum (have %g, expected %g)\n", x, sum);
problem = TRUE;
}
if (! eq (abs_sum, x = guppi_data_table_get_abs_sum (tab, span, i))) {
g_print ("bad abs_sum (have %g, expected %g)\n", x, abs_sum);
problem = TRUE;
}
if (! eq (min, x = guppi_data_table_get_min (tab, span, i))) {
g_print ("bad min (have %g, expected %g)\n", x, min);
problem = TRUE;
}
if (! eq (max, x = guppi_data_table_get_max (tab, span, i))) {
g_print ("bad max (have %g, expected %g)\n", x, max);
problem = TRUE;
}
if (problem) {
for (i = 0; i < N; ++i)
g_print ("%g ", sl[i]);
g_print ("\n");
break;
}
}
if (problem)
break;
}
return ! problem;
}
int
main (int argc, char *argv[])
{
guppi_test_init (&argc, &argv);
guppi_useful_init_without_guile ();
guppi_data_init ();
guppi_test_do ("Locate and load data table plug-ins", plugins, NULL);
guppi_test_do ("Create/destroy a GuppiDataTableCore", construct, NULL);
guppi_test_do ("Basic GuppiDataTable operations", basic_ops, NULL);
guppi_test_do ("GuppiDataTable statistics", stats, NULL);
guppi_test_quit ();
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1