mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-11-03 21:40:52 -05:00 
			
		
		
		
	
		
			
	
	
		
			148 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			148 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/* MOD2SPARSE.H - Interface to module for handling sparse mod2 matrices. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Copyright (c) 1995-2012 by Radford M. Neal.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Permission is granted for anyone to copy, use, modify, and distribute
							 | 
						||
| 
								 | 
							
								 * these programs and accompanying documents for any purpose, provided
							 | 
						||
| 
								 | 
							
								 * this copyright notice is retained and prominently displayed, and note
							 | 
						||
| 
								 | 
							
								 * is made of any changes made to these programs.  These programs and
							 | 
						||
| 
								 | 
							
								 * documents are distributed without any warranty, express or implied.
							 | 
						||
| 
								 | 
							
								 * As the programs were written for research purposes only, they have not
							 | 
						||
| 
								 | 
							
								 * been tested to the degree that would be advisable in any important
							 | 
						||
| 
								 | 
							
								 * application.  All use of these programs is entirely at the user's own
							 | 
						||
| 
								 | 
							
								 * risk.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* This module implements operations on sparse matrices of mod2 elements 
							 | 
						||
| 
								 | 
							
								   (bits, with addition and multiplication being done modulo 2).  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								   All procedures in this module display an error message on standard 
							 | 
						||
| 
								 | 
							
								   error and terminate the program if passed an invalid argument (indicative
							 | 
						||
| 
								 | 
							
								   of a programming error), or if memory cannot be allocated.  Errors from 
							 | 
						||
| 
								 | 
							
								   invalid contents of a file result in an error code being returned to the 
							 | 
						||
| 
								 | 
							
								   caller, with no message being printed by this module. 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* DATA STRUCTURES USED TO STORE A SPARSE MATRIX.  Non-zero entries (ie, 1s)
							 | 
						||
| 
								 | 
							
								   are represented by nodes that are doubly-linked both by row and by column,
							 | 
						||
| 
								 | 
							
								   with the headers for these lists being kept in arrays.  Nodes are allocated
							 | 
						||
| 
								 | 
							
								   in blocks to reduce time and space overhead.  Freed nodes are kept for
							 | 
						||
| 
								 | 
							
								   reuse in the same matrix, rather than being freed for other uses, except 
							 | 
						||
| 
								 | 
							
								   that they are all freed when the matrix is cleared to all zeros by the
							 | 
						||
| 
								 | 
							
								   mod2sparse_clear procedure, or copied into by mod2sparse_copy. 
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								   Direct access to these structures should be avoided except in low-level
							 | 
						||
| 
								 | 
							
								   routines.  Use the macros and procedures defined below instead. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct mod2entry /* Structure representing a non-zero entry, or
							 | 
						||
| 
								 | 
							
											      the header for a row or column               */
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int row, col;		  /* Row and column indexes of this entry, starting
							 | 
						||
| 
								 | 
							
								                             at 0, and with -1 for a row or column header  */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  struct mod2entry *left, *right,  /* Pointers to entries adjacent in row  */
							 | 
						||
| 
								 | 
							
								                   *up, *down;     /*   and column, or to headers.  Free   */
							 | 
						||
| 
								 | 
							
								                                   /*   entries are linked by 'left'.      */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  double pr, lr;	  /* Probability and likelihood ratios - not used  */
							 | 
						||
| 
								 | 
							
											  /*   by the mod2sparse module itself             */
							 | 
						||
| 
								 | 
							
								} mod2entry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define Mod2sparse_block 10  /* Number of entries to block together for
							 | 
						||
| 
								 | 
							
								                                memory allocation */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct mod2block /* Block of entries allocated all at once */
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  struct mod2block *next;  /* Next block that has been allocated */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  mod2entry entry[Mod2sparse_block]; /* Entries in this block */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} mod2block;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct		/* Representation of a sparse matrix */
							 | 
						||
| 
								 | 
							
								{ 
							 | 
						||
| 
								 | 
							
								  int n_rows;		  /* Number of rows in the matrix */
							 | 
						||
| 
								 | 
							
								  int n_cols;		  /* Number of columns in the matrix */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  mod2entry *rows;	  /* Pointer to array of row headers */
							 | 
						||
| 
								 | 
							
								  mod2entry *cols;	  /* Pointer to array of column headers */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  mod2block *blocks;	  /* Blocks that have been allocated */
							 | 
						||
| 
								 | 
							
								  mod2entry *next_free;	  /* Next free entry */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} mod2sparse;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* MACROS TO GET AT ELEMENTS OF A SPARSE MATRIX.  The 'first', 'last', 'next',
							 | 
						||
| 
								 | 
							
								   and 'prev' macros traverse the elements in a row or column.  Moving past
							 | 
						||
| 
								 | 
							
								   the first/last element gets one to a header element, which can be identified
							 | 
						||
| 
								 | 
							
								   using the 'at_end' macro.  Macros also exist for finding out the row 
							 | 
						||
| 
								 | 
							
								   and column of an entry, and for finding out the dimensions of a matrix. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define mod2sparse_first_in_row(m,i) ((m)->rows[i].right) /* Find the first   */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_first_in_col(m,j) ((m)->cols[j].down)  /* or last entry in */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_last_in_row(m,i) ((m)->rows[i].left)   /* a row or column  */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_last_in_col(m,j) ((m)->cols[j].up)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define mod2sparse_next_in_row(e) ((e)->right)  /* Move from one entry to     */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_next_in_col(e) ((e)->down)   /* another in any of the four */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_prev_in_row(e) ((e)->left)   /* possible directions        */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_prev_in_col(e) ((e)->up)   
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define mod2sparse_at_end(e) ((e)->row<0) /* See if we've reached the end     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define mod2sparse_row(e) ((e)->row)      /* Find out the row or column index */
							 | 
						||
| 
								 | 
							
								#define mod2sparse_col(e) ((e)->col)      /* of an entry (indexes start at 0) */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define mod2sparse_rows(m) ((m)->n_rows)  /* Get the number of rows or columns*/
							 | 
						||
| 
								 | 
							
								#define mod2sparse_cols(m) ((m)->n_cols)  /* in a matrix                      */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* POSSIBLE LU DECOMPOSITION STRATEGIES.  For use with mod2sparse_decomp. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef enum 
							 | 
						||
| 
								 | 
							
								{ Mod2sparse_first, 
							 | 
						||
| 
								 | 
							
								  Mod2sparse_mincol, 
							 | 
						||
| 
								 | 
							
								  Mod2sparse_minprod
							 | 
						||
| 
								 | 
							
								} mod2sparse_strategy;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* PROCEDURES TO MANIPULATE SPARSE MATRICES. */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mod2sparse *mod2sparse_allocate (int, int);
							 | 
						||
| 
								 | 
							
								void mod2sparse_free            (mod2sparse *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mod2sparse_clear    (mod2sparse *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_copy     (mod2sparse *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_copyrows (mod2sparse *, mod2sparse *, int *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_copycols (mod2sparse *, mod2sparse *, int *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mod2sparse_print       (FILE *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								int  mod2sparse_write       (FILE *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								mod2sparse *mod2sparse_read (FILE *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								mod2entry *mod2sparse_find   (mod2sparse *, int, int);
							 | 
						||
| 
								 | 
							
								mod2entry *mod2sparse_insert (mod2sparse *, int, int);
							 | 
						||
| 
								 | 
							
								void mod2sparse_delete       (mod2sparse *, mod2entry *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mod2sparse_transpose (mod2sparse *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_add       (mod2sparse *, mod2sparse *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_multiply  (mod2sparse *, mod2sparse *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								void mod2sparse_mulvec    (mod2sparse *, char *, char *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int mod2sparse_equal (mod2sparse *, mod2sparse *);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int mod2sparse_count_row (mod2sparse *, int);
							 | 
						||
| 
								 | 
							
								int mod2sparse_count_col (mod2sparse *, int);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void mod2sparse_add_row (mod2sparse *, int, mod2sparse *, int);
							 | 
						||
| 
								 | 
							
								void mod2sparse_add_col (mod2sparse *, int, mod2sparse *, int);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int mod2sparse_decomp (mod2sparse *, int, mod2sparse *, mod2sparse *, 
							 | 
						||
| 
								 | 
							
								                       int *, int *, mod2sparse_strategy, int, int);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int mod2sparse_forward_sub  (mod2sparse *, int *, char *, char *);
							 | 
						||
| 
								 | 
							
								int mod2sparse_backward_sub (mod2sparse *, int *, char *, char *);
							 |