//======================================================= file = iter.c ===== //= Solver for P*pi = pi and Q*pi = 0 for sparse P and Q = //= - Uses iterative methods = //=========================================================================== //= Notes: = //= 1) Input from input file "in.dat" to stdin (see example below) = //= * Note special format of input file, "-1" denotes end of = //= column, "-999" denotes last entry, and "&" bounds comments = //= 2) Reads matrix Type ('P' or 'Q') as first input value and then = //= reads matrix Size (0...(Size - 1)) as second input value. No = //= initial comment is allowed. = //= 3) Output is to stdout = //= 4) The matrix is NOT checked for validity (i.e., that for a P = //= matrix every row sums to 1.0 and for a Q matrix that every row = //= sums to 0.0). A non-valid matrix will cause unpredicatable = //= results. = //= 5) Assumes that sum of pi is always 1.0. = //= 6) Uses direct iteration for P matrix = //= 7) Converts a Q matrix into a valid P matrix before solving = //=-------------------------------------------------------------------------= //= Example "in.dat" file: = //= = //= P 3 = //= & Example from Kleinrock, Volume 1, pages 31 - 33 & = //= & ---------------- column #0 & = //= 1 0.25 = //= 2 0.25 = //= -1 zero = //= & ---------------- column #1 & = //= 0 0.75 = //= 2 0.25 = //= -1 zero = //= & ---------------- column #2 & = //= 0 0.25 = //= 1 0.75 = //= 2 0.50 = //= -1 zero = //= & ---------------- END FLAG & = //= -999 zero = //=-------------------------------------------------------------------------= //= Example output (for above "in.dat"): = //= = //= -------------------------------------------------- iter.c ----- = //= Iteration count = 10 -- Convergence mean = 0.333333 = //= Iteration count = 20 -- Convergence mean = 1.66151e-06 = //= Iteration count = 30 -- Convergence mean = 3.20145e-12 = //= Iteration count = 40 -- Convergence mean = 0 = //= --------------------------------------------------------------- = //= Results for P matrix (size = 3 and tolerance = 1e-15) = //= Pi[0] = 0.2 = //= Pi[1] = 0.28 = //= Pi[2] = 0.52 = //= --------------------------------------------------------------- = //=-------------------------------------------------------------------------= //= Build: bcc32 iter.c, cl iter.c, gcc iter.c -lm = //=-------------------------------------------------------------------------= //= Execute: iter < in.dat = //=-------------------------------------------------------------------------= //= Author: Ken Christensen = //= University of South Florida = //= WWW: http://www.csee.usf.edu/~christen = //= Email: christen@csee.usf.edu = //=-------------------------------------------------------------------------= //= History: KJC (02/23/02) - Genesis (from "original" iter.c from 1991) = //= KJC (05/01/05) - Fixed a problem with solving Q matrices = //= KJC (05/11/05) - Now can have multiple sequential comments = //= KJC (06/16/06) - Cleaned-up some comments = //=========================================================================== //----- Include files ------------------------------------------------------- #include // Needed for printf() #include // Needed for fabs() #include // Needed for exit(), atoi(), and atof() #include // Needed for strcmp() //----- Defines ------------------------------------------------------------- #define P_TYPE 0 // P matrix type is 0 #define Q_TYPE 1 // Q matrix type is 1 #define MAX_SIZE 50 // Max size of Q array (0...(MAX_SIZE - 1)) #define MAX_ENTRY 1000 // Max number of non-zero entries #define TOLERANCE 1.0e-15 // Converence tolerance for pi values #define NUM_LOOP 10 // Iterations between convergence checks //----- Globals ------------------------------------------------------------- struct Col_type // Data structure for matrix columns { int row_num; // ** Row number for this column entry double value; // ** Value for this column entry }; struct Col_type Column[MAX_ENTRY]; // Columns of matrix int Matrix_type; // Matrix type (P or Q) int Size; // Size of matrix (0...(Size - 1)) int Count; // Count for iterations int Done; // Flag for convergence double Pi[MAX_SIZE]; // pi vector double Pi_old[MAX_SIZE]; // pi vector from previous iteration double Converge_sum; // Convergence sum //----- Prototypes ---------------------------------------------------------- void load_matrix(void); // Load matrix void iterate(void); // Perform one iteration int check_convergence(void); // Check for convergence of Pi to Pi_old //=========================================================================== //= Main program = //=========================================================================== void main(void) { int i; // Loop counter // Load the matrix printf("-------------------------------------------------- iter.c -----\n"); load_matrix(); // Initialize Pi for (i=0; i MAX_SIZE)) { printf("*** ERROR - Size is invalid (Size = %d) \n", Size); exit(1); } // Main loop to read contents of file into matrix max_val = 0; index = 0; do { scanf("%s", temp_string); // This handles a comment (multiple comments are handled) if (strcmp(temp_string, "&") == 0) { while(1) { do { scanf("%s", temp_string); } while (strcmp(temp_string, "&") != 0); scanf("%s", temp_string); if (strcmp(temp_string, "&") != 0) break; } } // Input row number Column[index].row_num = atoi(temp_string); if (Column[index].row_num == -999) break; // Input value for this row number scanf("%s", temp_string); Column[index].value = atof(temp_string); // Find the maximum sum value (for Q matrix adjustment only) if (-Column[index].value > max_val) max_val = -Column[index].value; // Increment index index++; } while (1); // If Q type then need to convert to a valid P matrix if (Matrix_type == Q_TYPE) { index = 0; for(col_num=0; col_num= MAX_ENTRY) { printf("*** ERROR - exceeded MAX_ENTRY elements (MAX_ENTRY = %d) \n", MAX_ENTRY); exit(1); } // row = -1 means no more values in this column if (row < 0) break; // An iteration sum = sum + (Pi[row] * val); } while (1); // Determine next value of pi_temp pi_temp[col_num] = sum; } // Normalize pi_temp sum = 0; for (i=0; i