From oleg@nrcbsa.bio.nrc.ca Thu May 23 08:51:47 1991 Return-Path: Received: from nrcnet0.nrc.ca by CS.UTK.EDU with SMTP (5.61++/2.5.1s-UTK) id AA26030; Thu, 23 May 91 08:51:40 -0400 Message-Id: <9105231251.AA28680@ nrcbsa.bio.nrc.ca> Date: Thu, 23 May 91 08:51:14 EDT From: Dr. Oleg Keselyov To: dongarra@cs.utk.edu Subject: vector.shar Status: RO #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command 'sh file'. The files # will be extracted into the current directory owned by # you with default permissions. # The arcive contains low and intermediate Level functions to manage vectors # in C. # In fact, the vector declaration as a special structure and # a wide set of procedures to handle it define a class (in # the sence of C++ or SMALLTALK) but it is still a common C. # Features: high reliability and error-checking, the user can # operate on single elements of the vector in the customary C # manner, or he may wish to handle the vector as a whole # (as an atomary object) with high-effective functions # (that can clear the vector, assign vectors or obtain their # scalar product, find the vector norm(s), etc.). # The contents of the archive # # Header file # vector.h Define the package # # Source code for vector implementation # vec_base.c Basic vector primitives, constructors, destructors # vec_norm.c Computing vector norms and the scalar product # vec_serv.c Comparison and Input/Output functions # # Package verification # vvector.c Test driver # vvector.dat Verification protocol echo 'x - vector.h' sed 's/^X//' << '________This_Is_The_END________' > vector.h X/* X ************************************************************************ X * VECTOR of floats X * Description of data and operations X */ X X#ifndef V$elem_type X X#define V$elem_type float X Xtypedef struct { /* Vector structure */ X short int valid; /* Validation code */ X short int ident; /* Identification */ X int upb; /* Upper bound value */ X int lwb; /* Lower bound value */ X V$elem_type * ptr; /* Ptr to the vector body */ X } X*VECTOR, _VECTOR; X X#define _V$validation_code 23567 /* VECTOR->valid contents */ X X /* Vector identification codes */ X#define _V$id_dynamic 1 /* Storage was obtained via malloc*/ X X/* X *----------------------------------------------------------------------- X * Allocation routines X */ X /* Defining a not-dynamical vector */ X#define Vector(name,lwb,upb) V$elem_type _$_name [(upb)-(lwb)+1]; \ X VECTOR name = &{_V$validation_code, 0, (upb), (lwb), _$_name} X XVECTOR V_new( /* Create a new dynamic vector */ X const int lwb, /* Lower bound */ X const int upb /* Upper bound */ X ); X XVECTOR V_build( /* Build a vector and assign init val */ X const int lwb, /* Lower bound */ X const int upb, /* Upper bound */ X ... /* DOUBLE numbers - values of */ X /* vector components */ X /* List must contain an extra */ X /* argument - string "END" */ X ); X X Xvoid V_free( /* Delete a vector and free its storage */ X VECTOR v /* Dynamic vector to be freed */ X ); X X /* Assure that two vectors are compatible*/ X#define V_are_compatible(v1,v2) {if( v1->lwb != v2->lwb || v1->upb != v2->upb )\ X _error("Vectors [%d:%d] and [%d:%d] are incompatible.\nFile %s, line \ X %d\n",v1->lwb,v1->upb, v2->lwb,v2->upb, __FILE__, __LINE__);} X X X/* X *----------------------------------------------------------------------- X * Access to VECTOR fields X */ X /* Assure the vector having been initialized*/ X#define V_verify(v) if( v->valid != _V$validation_code ) \ X _error("Illegal vector.\nFile %s, line %d\n",__FILE__,__LINE__) X X#define V_lwb(v) v->lwb /* Lower vector bound */ X#define V_upb(v) v->upb /* Upper vector bound */ X#define V_no_elems(v) (v->upb-v->lwb+1) /* No. of vector elements */ X X /* Get ptr to the vector body */ XV$elem_type * V_body( X const VECTOR v /* Vector under operation */ X ); X#define V_pointer(ptr,v) V$elem_type *ptr = V_body(v) X X /* Get ptr to a vector element */ XV$elem_type * V_elem( X const VECTOR v, /* Vector under operation */ X const int i /* Index */ X ); X X/* X *----------------------------------------------------------------------- X * Assignments X */ X Xvoid V_assign( /* Assign vector to vector */ X VECTOR dest, /* Destination vector */ X const VECTOR source /* Source vector */ X ); X Xvoid V_clear( /* Clear the entire vector (fill with 0)*/ X VECTOR v /* Vector being operated */ X ); X Xvoid V_setto( /* Set all vector elements to a given val*/ X VECTOR v, /* Vector being operated */ X const double val /* Value to be set */ X ); X X/* X *----------------------------------------------------------------------- X * Compute vector norms X */ X Xdouble V_1_norm( /* 1. vector norm = SUM[ |vector[i]| ] */ X const VECTOR v /* Vector under operation */ X ); X Xdouble V_2_norm( /* 2. vector norm = MAX[ |vector[i]| ] */ X const VECTOR v /* Vector under operation */ X ); X Xdouble V_e2_norm( /* Square of the Euclid norm = */ X const VECTOR v /* SUM[ vector[i]^2 ] */ X ); X Xdouble V_diff_e2_norm( /* Square of the Euclid norm for */ X const VECTOR v1, /* the difference of 2 vectors */ X const VECTOR v2 X ); X X X X/* X *----------------------------------------------------------------------- X * Vector arithmetics X */ X Xdouble V_scalar_prod( /* Scalar product of two vectors */ X const VECTOR v1, X const VECTOR v2 X ); X X Xvoid V_op2( /* Vector arithmetics: binary operations*/ X VECTOR dest, /* Destination */ X char sign X ); X X/* X *----------------------------------------------------------------------- X * Service functions X */ X Xvoid V_compare( /* Compare two vectors */ X const VECTOR v1, /* Vectors to be compared */ X const VECTOR v2, X const char * message /* Explanation message */ X ); X Xvoid V_print( /* Print a vector */ X const VECTOR v, /* Vector to be printed */ X const char * title /* Explanation message */ X ); X XVECTOR V_read( /* Read a vector from stdin */ X const char * title /* File is assumed to contain */ X ); /* title, counter, and elements */ X X#endif ________This_Is_The_END________ if test `wc -l < vector.h` -ne 161; then echo 'shar: vector.h was damaged during transit (should have had 161 lines)' fi echo 'x - vec_base.c' sed 's/^X//' << '________This_Is_The_END________' > vec_base.c X/* X ************************************************************************ X * VECTOR of floats X * Base operations X */ X X#include "vector.h" X X#include "assert.h" X#include X#include X X/* X * Create a dynamic vector X * X */ X XVECTOR V_new(lwb,upb) Xconst int lwb, upb; X{ X register int no_elements = upb - lwb + 1; X register VECTOR v; X X assure(no_elements>0,"V_new: lwb > upb"); X assure((v = (VECTOR)malloc(sizeof(_VECTOR))) != (VECTOR)0, X "V_new: no memory"); X X v->valid = _V$validation_code; X v->ident = _V$id_dynamic; X v->lwb = lwb; X v->upb = upb; X assure((v->ptr = (V$elem_type *)malloc(no_elements*sizeof(V$elem_type)) X ) != NULL, X "V_new: no memory"); X return v; X} X X X#include X X /* Build a vector and assign init values */ X /* The arg list must contain an extra argument- */ X /* string "END" */ XVECTOR V_build( X const int lwb, /* Lower bound */ X const int upb, /* Upper bound */ X ... X) X{ X va_list args; X VECTOR v = V_new(lwb,upb); X register int i; X X va_start(args,upb); /* Init 'args' to the beginning of */ X /* the variable length list of args*/ X for(i=lwb; i<=upb; i++) X *V_elem(v,i) = (double)va_arg(args,double); X assure( strcmp((char *)va_arg(args,char *),"END") == 0, X "V_build: argument list should be terminated by \"END\" "); X return v; X} X X X/* X * Free a dynamic vector X * X */ X Xvoid V_free(v) XVECTOR v; X{ X assure( v->valid == _V$validation_code && X (v->ident & _V$id_dynamic == _V$id_dynamic), X "V_free: invalid dynamic vector to free" ); X free( v->ptr ); X v->valid = 0; v->lwb = 0; v->upb = -1; X free(v); X} X X X/* X * Get ptr to the VECTOR body X * X */ X XV$elem_type * V_body(v) Xconst VECTOR v; X{ X assure( v->valid == _V$validation_code, "V_body: invalid VECTOR ptr"); X assure( v->upb >= v->lwb, "V_body: VECTOR must have been corrupted"); X return v->ptr; X} X X X/* X * Get ptr to the specified VECTOR element X * X */ X XV$elem_type * V_elem(v,i) Xconst VECTOR v; /* Vector under operation */ Xconst int i; /* Index of the req. elem */ X{ X assure( v->valid == _V$validation_code, "V_elem: invalid VECTOR ptr"); X if( i>V_upb(v) || iptr + (i-V_lwb(v)); X} X X X/* X *======================================================================= X * VECTOR assignments X */ X X X/* X * Clear all the vector elements X * X */ X Xvoid V_clear(v) XVECTOR v; X{ X register int i; X register V$elem_type *p = V_body(v); X X for(i=V_no_elems(v); --i >=0;) X *p++ = 0; X} X X X/* X * Set all the vector elements to a given value X * X */ X Xvoid V_setto(v,val) XVECTOR v; Xconst double val; X{ X register int i; X register V$elem_type *p = V_body(v); X X for(i=V_no_elems(v); --i >= 0;) X *p++ = val; X} X X/* X * Assign one vector to another X * X */ X Xvoid V_assign(dest,src) XVECTOR dest; /* Destination */ Xconst VECTOR src; /* Source */ X{ X register int i; X register V$elem_type *p = V_body(dest); X register V$elem_type *q = V_body(src); X X V_are_compatible(dest,src); X X for(i=V_no_elems(src); --i >= 0;) X (*p++) = (*q++); X X} ________This_Is_The_END________ if test `wc -l < vec_base.c` -ne 167; then echo 'shar: vec_base.c was damaged during transit (should have had 167 lines)' fi echo 'x - vec_norm.c' sed 's/^X//' << '________This_Is_The_END________' > vec_norm.c X/* X ************************************************************************ X * VECTOR of floats X * Compute various vector norms X * and the scalar product X */ X X#include "vector.h" X X#include "math.h" X X Xdouble V_1_norm(v) /* SUM[ |vi| ] */ Xconst VECTOR v; X{ X register int i; X register V$elem_type *p = V_body(v); X register double vi; X double sum = 0; X X for(i=V_no_elems(v); --i >=0;) X { X vi = *p++; X sum += ( vi<0 ? -vi : vi ); X } X X return sum; X} X X Xdouble V_2_norm(v) /* MAX[ |vi| ] */ Xconst VECTOR v; X{ X register int i; X register V$elem_type *p = V_body(v); X register double vi; X double max = -HUGE_VAL; X X for(i=V_no_elems(v); --i >= 0;) X { X vi = *p++; X if( vi < 0 ) X vi = -vi; X if( vi > max ) X max = vi; X } X X return max; X} X X Xdouble V_e2_norm(v) /* SUM[ vi^2 ] */ Xconst VECTOR v; X{ X register int i; X register V$elem_type *p = V_body(v); X register double vi; X double sum = 0; X X for(i=V_no_elems(v); --i >= 0;) X { X vi = *p++; X sum += vi*vi; X } X X return sum; X} X X Xdouble V_diff_e2_norm(v1,v2) /* SUM[ (v1i-v2i)^2 ] */ Xconst VECTOR v1,v2; X{ X register int i; X register V$elem_type *p = V_body(v1); X register V$elem_type *q = V_body(v2); X register double vi; X double sum = 0; X X V_are_compatible(v1,v2); X X for(i=V_no_elems(v1); --i >= 0;) X { X vi = (*p++) - (*q++); X sum += vi*vi; X } X X return sum; X} X X Xdouble V_scalar_prod(v1,v2) /* SUM[ v1i*v2i ] */ Xconst VECTOR v1,v2; X{ X register int i; X register V$elem_type *p = V_body(v1); X register V$elem_type *q = V_body(v2); X double sum = 0; X X V_are_compatible(v1,v2); X X for(i=V_no_elems(v1); --i >= 0;) X sum += (*p++) * (*q++); X X return sum; X} ________This_Is_The_END________ if test `wc -l < vec_norm.c` -ne 105; then echo 'shar: vec_norm.c was damaged during transit (should have had 105 lines)' fi echo 'x - vec_serv.c' sed 's/^X//' << '________This_Is_The_END________' > vec_serv.c X/* X ************************************************************************ X * VECTOR of floats X * Some service functions X */ X X#include "vector.h" X#include "math.h" X#include X X X/* X * Compare two vectors X */ X Xvoid V_compare(v1,v2,msg) Xconst VECTOR v1,v2; /* Vectors to be compared */ Xconst char * msg; /* Explanation message */ X{ X double max_disc = -1; /* Maximal discrepancy */ X int index_max_disc; /* index for the corr. element*/ X register int i; X X printf("\n\nCompare two [%d:%d] vectors - %s\n", X V_lwb(v1), V_upb(v1), msg); X V_are_compatible(v1,v2); X X for(i=V_lwb(v1); i<=V_upb(v1); i++) X { X double delta = fabs( *V_elem(v1,i) - *V_elem(v2,i) ); X if( delta > max_disc ) X { X max_disc = delta; X index_max_disc = i; X } X } X X printf("\nMaximal discrepancy \t\t%g",max_disc); X printf("\n reached at point no.\t\t%d",index_max_disc); X { X double v1i = *V_elem(v1,index_max_disc); X double v2i = *V_elem(v2,index_max_disc); X printf("\n Vector 1 at this point \t\t%g",v1i); X printf("\n Vector 2 at this point \t\t%g",v2i); X printf("\n Absolute error v2[i]-v1[i]\t\t%g",v2i-v1i); X printf("\n Relative error\t\t\t\t%g\n", X (v2i-v1i)/fmax(fabs(v2i+v1i)/2,1e-7) ); X } X { X double v1n = sqrt( V_e2_norm(v1) ); X double v2n = sqrt( V_e2_norm(v2) ); X double vdn = sqrt( V_diff_e2_norm(v1,v2) ); X printf("\n||v1|| \t\t\t%g",v1n); X printf("\n||v2|| \t\t\t%g",v2n); X printf("\n||v1-v2||\t\t\t\t%g",vdn); X printf("\n||v1-v2||/sqrt(||v1|| ||v2||)\t\t%g", X vdn/fmax( sqrt(v1n*v2n), 1e-7 ) ); X } X X} X X X X/* X * Print a vector X */ X Xvoid V_print(v,msg) Xconst VECTOR v; /* Vector to be printed */ Xconst char * msg; /* Explanation message */ X{ X const int elems_per_line = 10; /* No. of elems per line */ X extern const char _Minuses[]; X register int i,j,k; X X printf("\n\nvector [%d:%d] - %s\n\n",V_lwb(v),V_upb(v),msg); X for(i=V_lwb(v); i<=V_upb(v); i+=elems_per_line) X { X k = imin(i+elems_per_line-1,V_upb(v)); /* Index for the last elem at line*/ X for(j=i; j<=k; j++) /* Print indices */ X printf("%6d\t",j); X printf("\n%s\n",_Minuses); X X for(j=i; j<=k; j++) /* Print values */ X printf("%6g\t",*V_elem(v,j)); X printf("\n\n"); X } X} X ________This_Is_The_END________ if test `wc -l < vec_serv.c` -ne 89; then echo 'shar: vec_serv.c was damaged during transit (should have had 89 lines)' fi echo 'x - vvector.c' sed 's/^X//' << '________This_Is_The_END________' > vvector.c X/* Test for VECTOR managing routines */ X X#include "vector.h" X X Xtest_alloc() /* Vector allocating */ X{ X /* Vector(v1,1,20); */ X VECTOR v1, v2, v3, v4; X X printf("\n\n\tTest vector allocating\n"); X X v1 = V_new(1,20); X v2 = V_new(1,20); X v3 = V_new(0,19); X printf("\nv1 is declared as automatic [1:20] vector"); X printf("\nv2[1:20] and v3[0:19] have been constructed dynamically"); X V_are_compatible(v1,v2); X printf("\nv1 and v2 are compatible"); X V_free(v2); X printf("\nv2 has been freed"); X X printf("\nv2 is builded with values (1,2,3,4,5)\n"); X v2 = V_build(1,5,1.,2.,3.,4.,5.,"END"); X V_print(v2,"vector created"); X X printf("\nInvalid call to V_build: V_build(1,5,1,2.,3.,4.,5.,\"END\")\n"); X v2 = V_build(1,5,1,2.,3.,4.,5.,"END"); X X/* X printf("\nAn attempt to compare v1 and v3"); X V_are_compatible(v1,v3); X X printf("\nAn attempt to free automatic vector v1"); X V_free(v1); X */ X} X X Xtest_base() /* Test base vector operations */ X{ X VECTOR v, v1, v2; X double norm; X X printf("\n\nTest base VECTOR operations\n"); X X v = V_new(1,10); X/* v1 = V_new(2,10); */ X v1 = V_new(1,10); X printf("\nCreated vectors v[%d:%d], v1[%d:%d]", X V_lwb(v),V_upb(v),V_lwb(v1),V_upb(v1)); X X V_clear(v); X V_print(v,"v after clear"); X X V_setto(v1,4.2); X V_print(v1,"v1 after all elements are set to 4.2"); X X V_assign(v,v1); X V_print(v,"v after assignments v=v1"); X V_print(v1,"v1 after assignments v=v1"); X X V_setto(v,-2); X *V_elem(v,2) = 4; X V_print(v,"v after been set to -2.0 and v[2]=4"); X printf("\n1. norm of v = %g",V_1_norm(v)); X printf("\n2. norm of v = %g",V_2_norm(v)); X printf("\nE. norm of v ^2 = %g",V_e2_norm(v)); X printf("\ncomputed via v*v = %g",V_scalar_prod(v,v)); X printf("\n||v-v1||^2 = %g",V_diff_e2_norm(v,v1)); X X printf("\n Scalar prod. v*v1 = %g",V_scalar_prod(v,v1)); X X V_compare(v,v1,"Compare v and v1"); X X printf("\nAn attempt to access 13. element of v1"); X V_elem(v1,13); X} X X Xmain() X{ X test_alloc(); X test_base(); X} ________This_Is_The_END________ if test `wc -l < vvector.c` -ne 85; then echo 'shar: vvector.c was damaged during transit (should have had 85 lines)' fi echo 'x - vvector.dat' sed 's/^X//' << '________This_Is_The_END________' > vvector.dat X X X Test vector allocating X Xv1 is declared as automatic [1:20] vector Xv2[1:20] and v3[0:19] have been constructed dynamically Xv1 and v2 are compatible Xv2 has been freed Xv2 is builded with values (1,2,3,4,5) X X Xvector [1:5] - vector created X X 1 2 3 4 5 X------------------------------------------------------------------------------- X 1 2 3 4 5 X X XInvalid call to V_build: V_build(1,5,1,2.,3.,4.,5.,"END") X X XTest base VECTOR operations X XCreated vectors v[1:10], v1[1:10] X Xvector [1:10] - v after clear X X 1 2 3 4 5 6 7 8 9 10 X------------------------------------------------------------------------------- X 0 0 0 0 0 0 0 0 0 0 X X X Xvector [1:10] - v1 after all elements are set to 4.2 X X 1 2 3 4 5 6 7 8 9 10 X------------------------------------------------------------------------------- X 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 X X X Xvector [1:10] - v after assignments v=v1 X X 1 2 3 4 5 6 7 8 9 10 X------------------------------------------------------------------------------- X 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 X X X Xvector [1:10] - v1 after assignments v=v1 X X 1 2 3 4 5 6 7 8 9 10 X------------------------------------------------------------------------------- X 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 4.2 X X X Xvector [1:10] - v after been set to -2.0 and v[2]=4 X X 1 2 3 4 5 6 7 8 9 10 X------------------------------------------------------------------------------- X -2 4 -2 -2 -2 -2 -2 -2 -2 -2 X X X1. norm of v = 22 X2. norm of v = 4 XE. norm of v ^2 = 52 Xcomputed via v*v = 52 X||v-v1||^2 = 346 X Scalar prod. v*v1 = -58.8 X XCompare two [1:10] vectors - Compare v and v1 X XMaximal discrepancy 6.2 X reached at point no. 1 X Vector 1 at this point -2 X Vector 2 at this point 4.2 X Absolute error v2[i]-v1[i] 6.2 X Relative error 5.63636 X X||v1|| 7.2111 X||v2|| 13.2816 X||v1-v2|| 18.6011 X||v1-v2||/sqrt(||v1|| ||v2||) 1.9007 XAn attempt to access 13. element of v1 ________This_Is_The_END________ if test `wc -l < vvector.dat` -ne 85; then echo 'shar: vvector.dat was damaged during transit (should have had 85 lines)' fi .