Category : Miscellaneous Language Source Code
Archive   : NETS_1.ZIP
Filename : PAIRS.C

 
Output of file : PAIRS.C contained in archive : NETS_1.ZIP
/*=============================*/
/* NETS */
/* */
/* a product of the AI Section */
/* NASA, Johnson Space Center */
/* */
/* principal author: */
/* Paul Baffes */
/* */
/* contributing authors: */
/* Bryan Dulock */
/* Chris Ortiz */
/*=============================*/


/*
----------------------------------------------------------------------
Code For Setting up IO pairs for Network training (Prefix = PA_)
----------------------------------------------------------------------
This code is divided into 4 major sections:

(1) include files
(2) externed functions
(3) global variables
(4) subroutines

Each section is further explained below.
----------------------------------------------------------------------
*/


/*
----------------------------------------------------------------------
INCLUDE FILES
----------------------------------------------------------------------
*/
#include "common.h"
#include "weights.h"
#include "layer.h"
#include "net.h"
#include "netio.h"


/*
----------------------------------------------------------------------
EXTERNED FUNCTIONS
----------------------------------------------------------------------
Below are the functions defined in other files which are used by the
code here. They are organized by section.
----------------------------------------------------------------------
*/
extern int PS_parse_iopairs();
extern float C_Sint_to_float();
extern char *sys_long_alloc();
extern char *sys_alloc();
extern void sys_long_free();
extern void sys_free();
extern void sys_delete_file();
extern void sys_rename_file();
extern long IO_find_file_size();
extern void IO_print();

extern char IO_str[MAX_LINE_SIZE];



/*
----------------------------------------------------------------------
GLOBAL VARIABLES
----------------------------------------------------------------------
Next come the global variables for this code. All of them revolve
around reading information from files. In order to speed things up,
I buffer the input and do block reads into a large space in an array
from which all other routines work (see documentation in 'netio.h').
The 'fd_iofile' is an integer which is used as a file descriptor to
keep track of the INTERMEDIATE file which is created during training.
An intermediate file of IO pairs is created to facilitate training
speeds. These pairs are block read into the buffer (ie, "the_buffer"
below) and then referenced from there.
----------------------------------------------------------------------
*/
static buffer *the_buffer; /* global here but not visible outside */

static FILE *fp_iofile = NULL;/* used by rewind_workfile to close */
/* and reopen the file which has the */
/* IO pairs for teaching the net. */


/*
======================================================================
ROUTINES IN PAIRS.C
======================================================================
The routines in this file are grouped below by function. Each routine
is prefixed by the string "PA_" indicating that it is defined in the
"pairs.c" file. The types returned by the routines are also shown here
so that cross checking is more easily done between these functions
and the other files which intern them.


Type Returned Routine
------------- -------
void PA_initialize
void PA_setup_iopairs
void PA_reset_iopairs
FILE * PA_open_binary
void PA_write_signature
int PA_check_signature
int PA_put_to_workfile
void PA_flush
void PA_rewind_workfile
void PA_done_with_workfile
Sint PA_retrieve
int PA_get_from_workfile (returns Sint via args)
void PA_randomize_file
void PA_build_random_list
void PA_transfer_blocks
void PA_write_iop
void PA_put_ascii_wts
Sint PA_get_ascii_wts
======================================================================
*/


void PA_initialize()
/*
----------------------------------------------------------------------
Because the buffer used for reading and writing Sint values from
temporary files is NOT VISIBLE outside of this code, this init
routine is provided to make sure that space is actually set asside
for the buffer.
----------------------------------------------------------------------
*/
BEGIN
the_buffer = (buffer *) sys_alloc((unsigned)sizeof(buffer));
the_buffer->index = BUFFER_SIZE;
the_buffer->last_elem = -1; /* no elements in buffer */

END /* PA_initialize */


void PA_setup_iopairs(ptr_net, filename)
Net *ptr_net;
char filename[];
/*
----------------------------------------------------------------------
This routine actually does very little of the work involved with
setting up the io pairs. Instead, most of the work is passed to an
IO routine (in netio.c) since so much of io is machine dependent.
(That is, our netio.c was created specifically to isolate any code
dependent on I/O).
All this routine does is setup determine what the expected lenght of
the io-pairs should be (from the sizes of the input and output
layers) and then pass the work on to the IO routines. The result
returned indicates how many io pairs were specified in the input
file, or an ERROR indicating some sort of error in the input file.
----------------------------------------------------------------------
*/
BEGIN
int sum;

ptr_net->num_inputs = ptr_net->input_layer->num_nodes;
ptr_net->num_outputs = ptr_net->output_layer->num_nodes;

sum = ptr_net->num_inputs + ptr_net->num_outputs;
ptr_net->num_io_pairs = PS_parse_iopairs(filename, sum);

if (ptr_net->num_io_pairs == ERROR)
sprintf(IO_str, "\n*** problems with IO pairs specification ***\n");
else
sprintf(IO_str, "\n %d IO pairs read\n", ptr_net->num_io_pairs);
IO_print(0);

END /* PA_setup_iopairs */


void PA_reset_iopairs(ptr_net, bin_filename)
Net *ptr_net;
char bin_filename[];
/*
----------------------------------------------------------------------
This routine resets the values in the ptr_net Net structure to match
the number of iopairs found in the "filename" binary file. Several
assumptions are made. First, it is assumed that the incoming filename
indicates a binary file which was created at some earlier time by a
call to the "i" option of NETS (recall that the "i" option has the
effect of translating an ascii IOP file into a binary Sint format).
This file's length is determined and compared against the number of
inputs and outputs to determine the amount of iopairs in the file.
If the sizes do not map evenly, then this routine fails.
----------------------------------------------------------------------
*/
BEGIN
int in_size, out_size, pair_size, file_len, num_iopairs;

/*---------------------------------------*/
/* get the sizes of the input and output */
/* layers and the size of the file. NOTE */
/* the size of one iopair must be multi- */
/* plied by the size of a Sint in bytes. */
/*---------------------------------------*/
in_size = ptr_net->input_layer->num_nodes;
out_size = ptr_net->output_layer->num_nodes;
pair_size = sizeof(Sint) * (in_size + out_size);
file_len = IO_find_file_size(bin_filename);

/*--------------------------------------*/
/* determine how many iopairs could fit */
/* in file. NOTE that "/" rounds down */
/*--------------------------------------*/
num_iopairs = file_len / pair_size;

/*------------------------------------------*/
/* remultiplying the number of pairs by the */
/* sum of the input and output sizes should */
/* yield the file size if there is a match */
/*------------------------------------------*/
if ( (num_iopairs * pair_size) != file_len )
sprintf(IO_str, "\n*** net configuration does not match '%s' file ***\n", bin_filename);
else BEGIN
ptr_net->num_inputs = in_size;
ptr_net->num_outputs = out_size;
ptr_net->num_io_pairs = num_iopairs;
sprintf(IO_str, "\n %d IO pairs read\n", num_iopairs);
ENDELSE
IO_print(0);

END /* PA_reset_iopairs */


FILE *PA_open_binary(file_name, mode)
char file_name[];
int mode;
/*
----------------------------------------------------------------------
Resets the file given in "file name" using the open call with the
mode specified by "mode". Note, this will only reset for mass IO
reading and writing, and it also assumes the existence of a buffer
for holding all of the IO. The result returned is a file pointer
which can then be used for reading from or writing to the file.
NOTE THAT THE CALLER MUST ENSURE THAT THE FILE IS CLOSED.
----------------------------------------------------------------------
*/
BEGIN
FILE *fp;

if (mode == READ_MODE) BEGIN
fp = fopen(file_name, "rb");
the_buffer->index = BUFFER_SIZE;
the_buffer->last_elem = -1; /* no elements in buffer */
ENDIF
else BEGIN
fp = fopen(file_name, "wb");
the_buffer->index = 0;
ENDELSE
return(fp);

END /* PA_open_binary */


void PA_write_signature(fp, signature)
FILE *fp;
short int signature;
/*
----------------------------------------------------------------------
Writes out the 2-byte signature to the file indicated by "fp." Note
that only 2 bytes are written, regardless of whether Sint or float
format is being used.
----------------------------------------------------------------------
*/
BEGIN

/*-----------------------------------------*/
/* the "2" indicates that the signature is */
/* 2-bytes long. "1" means 1 sig written */
/*-----------------------------------------*/
fwrite((char *)(&signature), SIG_SIZE, 1, fp);

END /* PA_write_signature */


int PA_check_signature(filename, format)
char filename[];
int format;
/*
----------------------------------------------------------------------
This routine opens the file "filename" and checks the first two bytes
of the file to determine whether or not the file has a signature. IF
it does, it will have the BIN_SIG of all binary weights files used by
NETS. The format of the file must match the format passed in by the
"format" parameter. If there is no match or if the file cannot be
opened, then an error is returned.
----------------------------------------------------------------------
*/
BEGIN
FILE *fp;
short int signature;
int PA_text_sig_check();

/*--------------------------------------------*/
/* if the file cannot be opened, return error */
/*--------------------------------------------*/
if ( (fp = fopen(filename, "rb")) == NULL ) BEGIN
sprintf(IO_str, "\n*** can't open file %s ***\n", filename);
IO_print(0);
return(ERROR);
ENDIF

/*------------------------------------*/
/* otherwize, read in the signature */
/* NOTE signatures are always 2 bytes */
/*------------------------------------*/
fread((char *)(&signature), SIG_SIZE, 1, fp);
fclose(fp);

/*-------------------------------------*/
/* first check the desired file format */
/*-------------------------------------*/
if (format == FAST_FORMAT) BEGIN

/*--------------------------------*/
/* if signature is correct return */
/*--------------------------------*/
if (signature == BIN_SIG) return(OK);

/*------------------------------------------------*/
/* otherwise, signature could be binary but wrong */
/*------------------------------------------------*/
if (signature == WRONG_SIG) BEGIN
sprintf(IO_str, "\n*** file is not in %s format",
((USE_SCALED_INTS == 1)? "scaled integer" : "floating point") );
IO_print(0);
ENDIF

/*------------------------------------------------*/
/* or, lastly, signature might not even be binary */
/*------------------------------------------------*/
else BEGIN
sprintf(IO_str, "\n*** file is not in FAST format");
IO_print(0);
ENDELSE

/*----------------------------------*/
/* in any case, if you get past the */
/* BIN_SIG case you return an error */
/*----------------------------------*/
return(ERROR);
ENDIF

/*-----------------------------------*/
/* else if format is PORTABLE_FORMAT */
/*-----------------------------------*/
else BEGIN
if ((signature == BIN_SIG) || (signature == WRONG_SIG)) BEGIN
sprintf(IO_str, "\n*** file not in PORTABLE format");
IO_print(0);
return(ERROR);
ENDIF
else
return(PA_text_sig_check(filename));
ENDELSE

END /* PA_check_signature */


int PA_text_sig_check(filename)
char filename[];
/*
----------------------------------------------------------------------
This routine checks PORTABLE format files only. The problem here is
that if a file is written in ascii it cannot be given an initial
signature like a binary file can. Thus, the PA_check_signature routine
must call this routine in the event that a portable file is successfully
found. This routine returns OK or ERROR, depending upon whether or not
the data in the file matches the Sint format (when USE_SCALED_INTS = 1)
or the float format.
----------------------------------------------------------------------
*/
BEGIN
FILE *fp;
char in_str[MAX_WORD_SIZE];
int i, float_present = FALSE;

/*------------------------------------*/
/* get the first string from the file */
/*------------------------------------*/
fp = fopen(filename, "rt");
fgets(in_str, MAX_WORD_SIZE, fp);
fclose(fp);

/*-----------------------------*/
/* try to find a decimal point */
/*-----------------------------*/
i = 0;
while (in_str[i] != '\0') BEGIN
if (in_str[i] == '.') BEGIN
float_present = TRUE;
break;
ENDIF
i++;
ENDWHILE

/*----------------------------*/
/* if formats match return OK */
/*----------------------------*/
if ( ((float_present == FALSE) && (USE_SCALED_INTS == 1))
|| ((float_present == TRUE) && (USE_SCALED_INTS == 0)) )
return(OK);

/*------------------------------------------------*/
/* otherwise, printout error msg and return ERROR */
/*------------------------------------------------*/
sprintf(IO_str, "\n*** file is not in %s format",
((USE_SCALED_INTS == 1) ? "scaled integer" : "floating point") );
IO_print(0);
return(ERROR);

END /* PA_text_sig_check */


int PA_put_to_workfile(fp, Snum)
FILE *fp;
Sint Snum;
/*
----------------------------------------------------------------------
This routine puts out Sints to a temporary storage file for the net.
By default, I have decided to call the file "workfile.net" as it is
named in the above routine 'PS_parse_iopairs'. Instead of putting
out Sints a word at a time, this routine first writes the Sint to a
buffer and then checks to see if the buffer is full. If so, then the
entire buffer is mass written to the temporary file, which is much
quicker than trying to do things a word at a time.

Returns OK if the write goes ok, otherwise returns ERROR.
----------------------------------------------------------------------
*/
BEGIN
int temp;

temp = OK;
if (the_buffer->index >= BUFFER_SIZE) BEGIN /* the buffer is full */
temp = fwrite((char *)the_buffer->values, sizeof(Sint), BUFFER_SIZE, fp);
if (temp != BUFFER_SIZE) BEGIN
sprintf(IO_str, "\n*** Internal Error writing to WorkFile ***\n");
IO_print(0);
temp = ERROR;
ENDIF
else temp = OK;
the_buffer->index = 0;
ENDIF

the_buffer->values[the_buffer->index] = Snum;
the_buffer->index++;
return(temp);

END /* PA_put_to_workfile */


void PA_flush(fp)
FILE *fp;
/*
----------------------------------------------------------------------
This guy will print whatever is left in the buffer out to the temp
file. That is, after the last character is "put" by the routine
above, there is no guarantee that the buffer was also printed to the
(in fact, it would have only been printed in the case that the last
"put" exactly filled the buffer). So this routine is needed to make
sure that nothing gets lost in the buffer.
----------------------------------------------------------------------
*/
BEGIN
fwrite((char *)the_buffer->values, sizeof(Sint), the_buffer->index, fp);
the_buffer->index = 0;

END /* PA_flush */


void PA_rewind_workfile()
/*
----------------------------------------------------------------------
This routine resets the temporary file ("workfile.net") which has
all of the io pairs by opening or rewinding the file. This
must be done EACH TIME through a learning cycle. Also, the input
buffer ('the_buffer') must be reset to indicate that new values are
to be read in. This is done by setting the index of the buffer to
BUFFER_SIZE.
----------------------------------------------------------------------
*/
BEGIN
if (fp_iofile == NULL)
fp_iofile = fopen("workfile.net", "rb");
else if (fseek(fp_iofile, 0L, SEEK_SET) != 0) BEGIN
sprintf(IO_str, "\n*** INTERNAL ERROR: could not rewind WorkFile");
IO_print(0);
ENDELSE

/*----------------------------------------------*/
/* index set to end to force a read of the file */
/*----------------------------------------------*/
the_buffer->index = BUFFER_SIZE;
the_buffer->last_elem = -1;

END /* PA_rewind_workfile */


void PA_done_with_workfile()
/*
----------------------------------------------------------------------
This routine makes sure that the "workfile.net" file is closed before
training is completed. It is only called by "T_teach_net" routine.
----------------------------------------------------------------------
*/
BEGIN
if (fp_iofile != NULL) fclose(fp_iofile);
fp_iofile = NULL;

END /* PA_done_with_workfile */


Sint PA_retrieve()
/*
----------------------------------------------------------------------
This may seem like an absolutely stupid routine, and on one level I
agree; it is so small it seems ridiculous to waste time doing a
routine call just to set up another routine call. However, I wanted
to leave the 'PA_get_from_workfile', or 'get', routine isolated, so that
it could be used for different kinds of IO. For example, if I had
simply called the 'get' routine directly from 'net.c', then it would
have had to assume the existence of the file descriptor 'fp_iofile'
just as this routine does. Of course, then the 'get' routine would
only be good for reading from that file descriptor, which is really
not a good limitation, nor would it be consistent with the routine
'put_to_workfile'. Thus this routine acts as a sort of filter to
any outside routines from other files from having to know any of the
details of the IO.
Note that this routine assumes the existence of a global file des-
criptor called 'fd_iofile' which points to the work file.
Returns positive or 0 if the read goes ok, otherwise returns a -1.
----------------------------------------------------------------------
*/
BEGIN
int PA_get_from_workfile();
Sint result;

if (PA_get_from_workfile(fp_iofile, &result) == ERROR) BEGIN
sprintf(IO_str, "\n*** INTERNAL ERROR: could not access WorkFile");
IO_print(0);
ENDIF
return(result);

END /* PA_retrieve */


int PA_get_from_workfile(fp, ptr_Sint)
FILE *fp;
Sint *ptr_Sint;
/*
----------------------------------------------------------------------
This routine is the converse of 'put_to_workfile' above. Instead of
storing Sints, it reads them out of memory and places them into the
'ptr_Sint' variable passed in. Again, the default file for reading
is the same one where the stuff was written; "workfile.net".
Returns OK if a value can be read, ERROR otherwise.
----------------------------------------------------------------------
*/
BEGIN
int temp;

temp = OK;
/*----------------------------------*/
/* if the buffer contents exhausted */
/* try reading more from file */
/*----------------------------------*/
if (the_buffer->index >= BUFFER_SIZE) BEGIN
temp = fread((char *)the_buffer->values, sizeof(Sint), BUFFER_SIZE, fp);
if (temp == 0) BEGIN
sprintf(IO_str, "\n*** Internal Error reading from file ***\n");
IO_print(0);
temp = ERROR;
ENDIF
else BEGIN
the_buffer->last_elem = temp - 1;
temp = OK;
the_buffer->index = 0;
ENDELSE
ENDIF
/*----------------------------------------*/
/* otherwise, if already read past end of */
/* buffer then return error and message */
/*----------------------------------------*/
else if (the_buffer->index > the_buffer->last_elem) BEGIN
temp = ERROR;
sprintf(IO_str, "\n*** attempt to read past last value of file");
IO_print(0);
ENDELSE

/*----------------------------------*/
/* in any event, read the next elem */
/*----------------------------------*/
*ptr_Sint = the_buffer->values[the_buffer->index];
the_buffer->index++;

return(temp);

END /* PA_get_from_workfile */


void PA_randomize_file(new_file, bin_file, num_blocks, block_size)
char *new_file, *bin_file;
int num_blocks, block_size;
/*
----------------------------------------------------------------------
RANDOMIZE_FILE will take a binary file of I/O pairs and rearrange
the I/O pairs in a random order.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 31-May-1989
Cyclomatic Complexity = 1

Parameters Used
---------------
Num_Blocks - The number of I/O pairs ( Blocks ) in the binary file.
Block_Size - The number of bytes in each I/O pair.
File_Name - Binary file to be sorted.

Variables Used
--------------
Array - Array with the random order for the binary blocks.

Procedures / Functions
----------------------

PA_build_random_list - will take an array, initialize it, and
select and store a group of random block numbers.
PA_transfer_blocks - will take an array and build a new file
using random blocks from the old file.

Algorithm
---------
1. Build array of random numbers corresponding to random I/O pairs.
2. Build I/O pair file in random order corresponding to the array.

----------------------------------------------------------------------
*/
BEGIN
int *array;
void PA_build_random_list(), PA_transfer_blocks();

array = (int *) sys_alloc((unsigned)num_blocks * (unsigned)sizeof(int));
num_blocks = num_blocks - 1; /* Number of Blocks must start at 0 */
PA_build_random_list(array, num_blocks);
PA_transfer_blocks(array, new_file, bin_file, block_size, num_blocks);

sys_free((char *) array);

END /* PA_randomize_file */


void PA_build_random_list(array, num_block)
int array[], num_block;
/*
----------------------------------------------------------------------
BUILD_RANDOM_LIST will take an array, select non-repeating random numbers
from 0 to sizeof(array), and store the numbers back into
the array for use later.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 1-Jun-1989
Cyclomatic Complexity = 3

Parameters Used
---------------
Array - Array containing the random order of block Id's. (Output)
Num_Block - Number of blocks in a file. (Input)

Variables Used
--------------
Last - Pointer to tail of array.
Slot - Random Slot in array.
Temp - Storage Variable

Procedures / Functions
----------------------
Rand() - Returns a pseudorandom-number 0..32,767 ( RAND_MAX ).

Algorithm
---------
1. Initialize array with numbers corresponding to the index.
2. Initialize the random number generator.
3. Pick a random index into the array from 0 to the last known element.
4. Swap contents with the last known element in the array
5. Move last known element up one index and goto step 3.
----------------------------------------------------------------------
*/
BEGIN
int last, slot, temp;

for (last =0; last <= num_block; last++)
array[last] = last;

for (last = num_block; last > 0; last--) BEGIN
slot = rand() % last;
temp = array [slot];
array[slot] = array[last];
array[last] = temp;
ENDFOR

END /* PA_build_random_list */


void PA_transfer_blocks (array, new_file, bin_file, block_size, num_blocks)
int array[];
char *new_file, *bin_file;
int block_size, num_blocks;
/*
----------------------------------------------------------------------
TRANSFER_BLOCKS will transfer a block of data from one file to a
new file in a specified order which is contained
in the array argument.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 2-Jun-1989
Cyclomatic Complexity = 2

Parameters Used
---------------
Array - Array containing the random order of block Id's.
File_Name - Binary File (Unsorted) Name
Block_Size - Number of bytes per block of data.
Num_Block - Number of blocks in a file.

Variables Used
--------------
FP_Output - Output File
FP_Input - Input File
Ptr - Element of file to be transfered
Block - Current Block Number
Byte_Offset - Number of Bytes into file before reading.

Procedures / Functions
----------------------
Write_IOP - Write a single I/O pair into an ascii format.

Algorithm
---------
1. Open Files.
2. Read Array to get next random block to read.
3. Jump into input file to the random Block. (Byte_offset)
4. Read Block from input and write to output (Ascii and Binary).
5. If not done with random blocks goto step 2.
6. Close Files
7. Delete input file ( non-random ).
8. Rename output file to the name used for the input file.
----------------------------------------------------------------------
*/
BEGIN
long int byte_offset;
int block;
FILE *fp_input, *fp_output, *fp_ascii;
void PA_write_iop();
Sint *ptr;

ptr = (Sint *) sys_long_alloc((long)(block_size * sizeof(Sint)));

fp_input = fopen(bin_file, "rb");
fp_output = fopen("workfile.rnd", "wb");
fp_ascii = fopen(new_file,"wt");

for (block = 0; block <= num_blocks; block++) BEGIN
byte_offset = (long)(array[block] * block_size * sizeof(Sint));
fseek(fp_input, byte_offset, SEEK_SET);

fread((char *)ptr, sizeof(Sint), block_size, fp_input);
PA_write_iop(ptr, block_size, fp_ascii);
fwrite((char *)ptr, sizeof(Sint), block_size, fp_output);
ENDFOR

fclose(fp_input);
fclose(fp_ascii);
fclose(fp_output);

sys_delete_file(bin_file);
sys_rename_file("workfile.rnd", bin_file);

sys_long_free((char *) ptr);

END /* PA_transfer_blocks */


void PA_write_iop (ptr, num_ptr, fp_ascii)
Sint *ptr;
int num_ptr;
FILE *fp_ascii;
/*
----------------------------------------------------------------------
PA_WRITE_IOP will write the ascii version for the random I/O pairs to a file.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 3-Jun-1989
Cyclomatic Complexity = 3

Parameters Used
---------------
Ptr - Array containing one I/O pairs to be sent to the ascii file.
Num_Ptr - Size of Array.
Fp_Ascii - Ascii file where I/O pairs are to be written.

Variables Used
--------------
N_Row - number of fields to be printed on one line.
byte - loop counter.

Procedures / Functions
----------------------
C_Sint_to_float - converts type SINT to type float.

Algorithm
---------
1. Write '(' to ascii file.
2. Write convert SINT to float and write to file.
3. Write only N_Row number of floats to a line.
4. Write ')' to finish I/O pair.
----------------------------------------------------------------------
*/
BEGIN
int n_row, byte;

n_row = 3;
fprintf (fp_ascii,"(");

for (byte=1; byte <= num_ptr ; byte++) BEGIN
#if USE_SCALED_INTS
fprintf (fp_ascii, "%7.3f", C_Sint_to_float(ptr[byte - 1]));
#else
fprintf (fp_ascii, " %f", ptr[byte - 1]);
#endif

/*----------------------------------------------*/
/* after each sint is printed, check to see if */
/* you have printed "n_row" of them. If so, */
/* then print a newline. Note that byte starts */
/* at "1" (not 0) because of the comparisons */
/* done here. If it started at 0, you would */
/* printout a newline after the first element */
/* (try it). Of course, you could equally as */
/* well start at "0" and do comparisons here at */
/* byte+1, but that would mean two additions */
/* here, so I opted for byte starting at "1". */
/* Finally, note that this means byte must be */
/* decremented by one to be written out to file */
/*----------------------------------------------*/
if ((byte % n_row == 0) && (byte < num_ptr))
fprintf(fp_ascii,"\n");

ENDFOR
fprintf (fp_ascii," )\n");

END /* PA_write_iop */


Sint PA_get_ascii_wts(fp, weight)
FILE *fp;
Sint *weight;
/*
--------------------------------------------------------------------------------

PA_GET_ASCII_WTS will return a single Sint weight from an ASCII file format.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 4-Aug-1989
Cyclomatic Complexity = 2

Variables Used
--------------
fp - File pointer to ASCII file.
weight - Parameter the weight is sent to.
line - Line of characters from the input file.
tmp - Error condition that is returned from this procedure.

Algorithm
---------
1. Read a line of characters from input file.
2. Convert characters to floating point number. (One Float per line)
3. Convert floating point number to type Sint and store in return var.
4. Return the error condition.

Modified (8-15-89) to read in integer representations of the Sints rather
than floating point representations. The rationale here is that saving floating
point numbers does nothing except cause rounding errors. The user does not really
need to be able to read the numbers in their floating point format since there
is no additional information in the file which indicates what nodes are attached
to the weight. Thus, since the floating point conversion can cause round off
errors, I decided to switch to saving the Sints in ascii (but integer) format.
-----------------------------------------------------------------------------------
*/
BEGIN
char line[MAX_LINE_SIZE];
int tmp;
#if USE_SCALED_INTS
int val;
#else
float val;
#endif

tmp = ERROR;

if ( !feof(fp) ) BEGIN
fgets(line, MAX_LINE_SIZE, fp);
#if USE_SCALED_INTS
if (sscanf(line, "%d", &val) == 1) BEGIN
#else
if (sscanf(line, "%f", &val) == 1) BEGIN
#endif
*weight = (Sint) val;
tmp = OK;
ENDIF
ENDIF
return(tmp);

END /* PA_get_ascii_wts */


void PA_put_ascii_wts(weights, num_weights, fp)
Sint *weights;
int32 num_weights;
FILE *fp;
/*
-------------------------------------------------------------------------------

PA_PUT_ASCII_WTS will write an array of ASCII weights to a file.

Author : Chris Ortiz ( MPAD/AI NASA )
Date : 4-Aug-1989
Cyclomatic Complexity = 2

Variables Used
--------------
fp - File pointer to ASCII file.
weights - array of weights to be written to a file.
num_weights - number of weights in the array.
loop - variable user to index array.

Algorithm
---------
For each location in the weights array
1. convert from SINT to floating point.
2. write floating point number on a single line to the output file.

---------------------------------------------------------------------------------
*/
BEGIN
int32 loop;

for ( loop=0; loop < num_weights ; loop++ )
#if USE_SCALED_INTS
fprintf(fp, "%d\n", (int)(weights[loop]) );
#else
fprintf(fp, "%f\n", (float)(weights[loop]) );
#endif

END /* PA_put_ascii_wts */


  3 Responses to “Category : Miscellaneous Language Source Code
Archive   : NETS_1.ZIP
Filename : PAIRS.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/