qinv-test.c:


/* qinv-test.c - Routine to test the qinv routines.
 * © Copyright 1999, by John Halleck
 * All rights reserved.
 */
/* Version of August 14th, 1999 */

#include <stdio.h>
 /* We have print problem messages  */

#include "errors.h"
 /* We have to print final problem messages */

#include <math.h>
 /* Trig functions can be used to build good tests. */

#include "matdebug.h"
 /* The matrix debugging routines would be handy */

#include "reportframe.h"
 /* Standard form of our test output */

#include "qinv.h"
 /* And we need, of course, the routines we were testing. */

#define FUDGE (1.0 / 100000.0)
/* How close to arrays have to be to "pass" the inverse**2 = identity
 * tests on this machine.
 */

static double result[3][3], given[3][3], working[3][3];
double check[3][3]; /* This must be as large as the largest we test with */
static int problem;

static double S, C; 
static double  trig1[2][2], trig2[2][2], tfinal[2][2], twork[2][2];
/* Trig functions make the nicest tests... */

static int testone (int size, matrix result, matrix given, matrix working) {
  if ( ERRsize != (problem = invpd (   0, result, given, working)) )
       goterrorstat ("bad size passed", problem);
  if ( ERRnil != (problem = invpd (size,      0, given, working))
    || ERRnil != (problem = invpd (size, result,     0, working))
    || ERRnil != (problem = invpd (size, result, given,       0))
      )
     goterrorstat ("nil array passed?", problem);
  if ( ERRsame != (problem = invpd (size, result,  given, result)) )
     goterrorstat ("array alias problems passed?", problem);

  if ((problem = invpd (size, result, given, working)))
     goterrorstat ("valid call failed", problem);

  if ((problem = invpd (size, check, result, working)))
     goterrorstat ("call failed on valid arguments.", problem);
 
  if ((problem = matisaeq (size, size, given, check, FUDGE))) {
     if (ERRfalse == problem) problem = NoError;
     goterrorstat ("inverse of inverse is not original", problem);
     matprint ("Original", size, size, given);
     matprint ("Inverse", size, size, result);
     matprint ("Inverse of Inverse", size, size, check);
  }

  return problem;
}

int main() {

  inittests("qinv");

  newtest("invpd");

  if ((problem = matidn (3, result)) || (problem = matidn (3, given)))
     goterrorstat ("matidn returned bad problem?", problem);
  testone (3, result, given, working); 
  if ((problem = matiseq(3, 3, given, result))) {
    /* Note that this is an EXACT equality test */
     if (ERRfalse == problem) problem = NoError;
     goterrorstat ("can't get exact inverse of identity?", problem);
     printf ("    (Either it is wrong or arithmetic sucks on this machine.)\n");
     matprint ("given",    3, 3, given);
     matprint ("working:", 3, 3, working);
  }

  S = sin (3.1415926/180.0 * 5);
  C = sqrt (1.0 - S*S);
  trig1[0][0] =  C;   trig1[0][1] = S;
  trig1[1][0] = -S;   trig1[1][1] = C;
  testone (2, tfinal, trig1, twork);
  trig2[0][0] =  C;   trig2[0][1] = -S;
  trig2[1][0] =  S;   trig2[1][1] =  C;
  if ((problem = matisaeq(2, 2, trig2, tfinal, FUDGE))) {
     if (ERRfalse == problem) problem = NoError;
     goterrorstat ("rotation inverse is not inverse", problem);
     matprint ("invpd's version:", 2, 2, tfinal);
     matprint ("real version:", 2, 2, trig2);
  }

  endtest();

/* -------------------------- invns ----------------------------------------- */
/* Test the pivoting version of the above. */

  newtest("invns");
  if ( ERRsize != (problem = invns (   0, result, given, working)) )
     goterrorstat ("bad size accepted", problem);
  if ( ERRnil != (problem = invns (3,      0, given, working))
    || ERRnil != (problem = invns (3, result,     0, working))
    || ERRnil != (problem = invns (3, result, given,       0))
      )
     goterrorstat ("didn't notice nil array?", problem);
  if ( ERRsame != (problem = invpd (3, result,  given, result)) )
     goterrorstat ("alias problems ignored?", problem);

  given[0][0] = 0.0;  given[0][1] = 0.0;  given [0][2] = 1.0;
  given[1][0] = 0.0;  given[1][1] = 1.0;  given [1][2] = 0.0;
  given[2][0] = 1.0;  given[2][1] = 0.0;  given [2][2] = 0.0;

  if ((problem = matcpy (3, 3, check, given)))
     goterrorstat ("matcpy failed during invns test?", problem);

  if ((problem = invns (3, result, given, working)))
     goterrorstat ("rejected valid call", problem);

  if ((problem = matiseq (3, 3, result, check))) {
     if (problem == ERRfalse) problem = NoError;
     goterrorstat ("wrong answer?", problem);
     matprint ("Given:", 3, 3, given);
     matprint ("Answer:", 3, 3, result);
  }

  given[1][1] = 0.0;
  if (ERRnumeric != (problem = invns (3, result, given, working))) {
     goterrorstat ("accepted obviously singular matrix call", problem);
     matprint ("Given:",   3, 3, given);
     matprint ("Working:", 3, 3, working);
     matprint ("Answer:",  3, 3, result);
  }

  given[1][1] = 1.0; given [1][2] = 1.0; given [0][1] = 1.0;
  if (ERRnumeric != (problem = invns (3, result, given, working))) {
     goterrorstat ("accepted subtle singular matrix call", problem);
     matprint ("Given:",   3, 3, given);
     matprint ("Working:", 3, 3, working);
     matprint ("Answer:",  3, 3, result);
  }

/* ========================================================================== */

  endtest();
  finalizetests();
  return progerrors;
}

Go to ...


This page is http://www.cc.utah.edu/~nahaj/cave/survey/code/c/qinv-test.c.html
© Copyright 2000 by John Halleck, All Rights Reserved.
This snapshot was last modified on August 23rd, 2000
And the underlying file was last modified on May 11th, 2000