// this matrix_c09.cpp file has the file I/O subroutines. #include #include "matrix_dll.h" #include "StdAfx.h" #include "matrix_h09.h" void matrix_print(FILE *outfile, MAT *array, char *title) { unsigned long i, j, imx, jmx; imx = array->imx; jmx = array->jmx; fprintf(outfile, "%s\n", title); for(i=0; iimx = size; array->jmx = size; y = matrix_zero(array); if(y != 0) goto tie_point; average->imx = 1; average->jmx = size; y = matrix_zero(average); if(y != 0) goto tie_point; for(k=0; kimp = left_size; array->jmp = left_size; array->part = 1; array->sym = 1; array->positive = 1; average->jmp = left_size; average->part = 1; average->sym = 0; tie_point: return(y); }; // writes a matrix to a file, which must be open for writing and pre-positioned. // the title string must not contain any spaces. int matrix_write_array(FILE *array_file, char *title, unsigned long multiplier, MAT *array, MAT *scratch_1) { const unsigned long code=2; double norm, x; unsigned long i, j, imx, jmx, mult; int y=0; y = matrix_validate(array); if(y != 0) goto tie_point; imx = array->imx; jmx = array->jmx; y = matrix_norm(array, 1, &norm, scratch_1); if(y != 0) goto tie_point; mult = (unsigned long) (multiplier / norm); matrix_write_title(array_file, code, title); fprintf(array_file, "%d %d %d %d %d %d %d %d %d %d %d \n", array->imx, array->jmx, array->mx, array->imp, array->jmp, array->sym, array->cmp, array->part, array->positive, array->inh.valid_t, array->inh.valid_d); fprintf(array_file, "%d %.0f %.0f \n", mult, array->inh.trace * mult, array->inh.determinant * mult); for(i=0; iimx = imx; array->jmx = jmx; y = matrix_zero(array); if(y != 0) goto tie_point; fscanf(array_file, "%d %d %d %d %d %d %d %d %d ", &array->mx, &array->imp, &array->jmp, &array->sym, &array->cmp, &array->part, &array->positive, &array->inh.valid_t, &array->inh.valid_d); fscanf(array_file, "%d %lf %lf", &multiplier, &x1, &x2); divisor = ONE / ((double )multiplier); array->inh.trace = x1 * divisor; array->inh.determinant = x2 * divisor; y = matrix_validate(array); if(y != 0) { printf("the array did not validate! \n"); goto tie_point; }; for(i=0; iimx; jmx = array->jmx; y=matrix_cmplx_real(array, scratch_2, scratch_3, scratch_4, scratch_5); if(y != 0) goto tie_point; y = matrix_norm(scratch_2, 1, &norm, scratch_1); if(y != 0) goto tie_point; mult = (unsigned long) (multiplier / norm); matrix_write_title(array_file, code, title); fprintf(array_file, "%d %d %d %d %d %d \n", array->imx, array->jmx, array->mx, array->sym, array->inh.valid_t, array->inh.valid_d); fprintf(array_file, "%d %.0f %.0f \n", mult, array->inh.trace.a * mult, array->inh.trace.b * mult, array->inh.sqmagdet * mult * mult); for(i=0; ia[subs].a * mult; v = array->a[subs].b * mult; fprintf(array_file, "%.0f %.0f ", u, v); }; fprintf(array_file, "\n"); }; fprintf(array_file, "this_is_the_end_of_the_complex_array_file\n"); tie_point: return(y); }; // reads a complex matrix from a file, which must be open for reading and pre-positioned. // yields a title and an array. int matrix_read_complex_array(FILE *array_file, char *title, matrix_cmplx *array, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7) { const double ONE=1.0; const unsigned long code=3; double u, v, x2, divisor; unsigned long multiplier, i, j, imx, jmx, subs; int y=0; y = matrix_read_title(array_file, code, title); if(y != 0) goto tie_point; fscanf(array_file, "%d %d", &imx, &jmx); scratch_1->imx = 2 * imx; scratch_1->jmx = 2 * jmx; y = matrix_zero(scratch_1); if(y != 0) goto tie_point; scratch_1->cmp = 1; scratch_1->imp = imx; scratch_1->jmp = jmx; y = matrix_real_cmplx(scratch_1, array, scratch_2, scratch_3, scratch_4, scratch_5, scratch_6, scratch_7); if(y != 0) goto tie_point; fscanf(array_file, "%d %d %d %d ", &array->mx, &array->sym, &array->inh.valid_t, &array->inh.valid_d); fscanf(array_file, "%d %lf %lf %lf", &multiplier, &u, &v, &x2); divisor = ONE / ((double )multiplier); array->inh.trace.a = u * divisor; array->inh.trace.b = v * divisor; array->inh.sqmagdet = x2 * divisor * divisor; y = matrix_validate_cmplx(array); if(y != 0) { printf("the array did not validate! \n"); goto tie_point; }; for(i=0; ia[subs].a = u * divisor; array->a[subs].b = v * divisor; }; }; tie_point: return(y); }; // reads an event_data_file_x. yields the title_x. // performs the linear transformation y = (x - average_x) * array + average_y. // writes a new event_data_file_y, with the provided title_y. // within the scope of Linear Algebra, the array should be a positive definite // partitioned symmetric matrix; but, this subroutine will accept any array. // also, the partitioning should correspond to that of the event_data_file_x. // the file event_data_file_x must be open for reading and pre-positioned. // the file event_date_file_y must be open for writing and pre-popitioned. // will return an error-code of 64 if the left_size + right_size of the event_data_file_x // is not equal to the jmx (horizontal size) of the average_x. int matrix_read_process_event_data1(FILE *event_data_file_x, char *title_x, MAT *average_x, MAT *array, MAT *average_y, FILE *event_data_file_y, char *title_y, MAT *scratch) { double x_vect[2 * MAX_SIZE], xo_vect[2 * MAX_SIZE], yo_vect[2 * MAX_SIZE], y_vect[2 * MAX_SIZE], divisor; unsigned long j, k, jmx, jmy, left_size_x, right_size_x, size_x, multiplier, amount, left_size_y, right_size_y, size_y; int y; y = matrix_validate(average_x) + matrix_validate(array)+matrix_validate(average_y) + matrix_check_compatibility_multiply(average_x, array); if(y != 0) goto tie_point; y = matrix_transpose(average_y, scratch); if(y != 0) goto tie_point; y = matrix_check_compatibility_multiply(array, scratch); if(y != 0) goto tie_point; jmx = average_x->jmx; for(j=0; jjmx; for(j=0; jpart == 0)? (0): (array->jmp); size_y = array->jmx; right_size_y = size_y - left_size_y; matrix_write_event_data_header(event_data_file_y, title_y, left_size_y, right_size_y, multiplier, amount); for(k=0; kjmx || right_size_x != average_y->jmx) y += 64; if(y != 0) goto tie_point; for(j=0; j residue_symmetric, // this variance to be equal to the variance_in --> relative_var, and // this average to be equal to the average_in. // if construct is zero, will only generate; if one, will actually construct. // the average_in must be a horizontal-vector of the same size and // partitioning as the variance_in. // to be usable directly as an event data-set for a channel, // the partitioning must be in the middle. int matrix_ellipsoidal_events(MAT *array_var_in, MAT *array_ave_in, unsigned long construct, unsigned long multiplier, unsigned long amount, char *ellipsoidal_events_name, char *ellipsoidal_events_title, MAT *array_var, MAT *array_ave, double *residue_symmetric, double *relative_var, double *relative_ave, char *scratch_events_name, char *scratch_events_title, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7) { unsigned long amt; int y=0; FILE *scratch_events, *ellipsoidal_events; unsigned long sort=0, left_size, right_size; char title[200]; y = matrix_validate(array_var_in) + matrix_validate(array_ave_in) + matrix_check_compatibility_multiply(array_ave_in, array_var_in); if(array_var_in->sym != 1 && array_var_in->sym != 4 && array_var_in->sym != 5) y += 16; if(y != 0) goto tie_point; left_size = (array_var_in->part == 0)? (0): (array_var_in->imp); right_size = array_var_in->imx - left_size; if(construct != 0) { amt = (array_var_in->imx + 1) * (array_var_in->imx + 1); if(amount < amt) amount = amt; }; scratch_events = fopen(scratch_events_name, "w"); y = matrix_write_event_data(scratch_events, scratch_events_title, left_size, right_size, multiplier, amount); fclose(scratch_events); if(y != 0) goto tie_point; scratch_events = fopen(scratch_events_name, "r"); y = matrix_read_event_data(scratch_events, title, scratch_1, scratch_3); fclose(scratch_events); if(y != 0) goto tie_point; if(construct == 0) { // generate. scratch_2->imx = scratch_2->imx; scratch_2->jmx = scratch_3->jmx; if(y != 0) goto tie_point; y = matrix_zero(scratch_2); if(y != 0) goto tie_point; matrix_propagate_default(scratch_3, scratch_2); y = matrix_square_root0(array_var_in, sort, scratch_3, scratch_4, scratch_5, scratch_6, scratch_7); if(y != 0) goto tie_point; } else { // construct. y = matrix_copy(scratch_3, scratch_2); if(y != 0) goto tie_point; y = matrix_square_root2(scratch_1, array_var_in, sort, scratch_3, scratch_4, scratch_5, scratch_6, scratch_7, array_var, array_ave); if(y != 0) goto tie_point; }; // array_var and array_ave are employed as scratch. scratch_events = fopen(scratch_events_name, "r"); ellipsoidal_events = fopen(ellipsoidal_events_name, "w"); y = matrix_read_process_event_data1(scratch_events, title, scratch_2, scratch_3, array_ave_in, ellipsoidal_events, ellipsoidal_events_title, scratch_1); fclose(scratch_events); fclose(ellipsoidal_events); if(y != 0) goto tie_point; ellipsoidal_events = fopen(ellipsoidal_events_name, "r"); y = matrix_read_event_data(ellipsoidal_events, title, array_var, array_ave); fclose(ellipsoidal_events); if(y != 0) goto tie_point; y = matrix_isit_symmetric(array_var, residue_symmetric, scratch_1, scratch_2, scratch_3, scratch_4); if(y != 0) goto tie_point; y = matrix_isit_equal(array_var_in, array_var, relative_var, scratch_1, scratch_2); if(y != 0) goto tie_point; y = matrix_isit_equal(array_ave_in, array_ave, relative_ave, scratch_1, scratch_2); if(y != 0) goto tie_point; tie_point: return(y); }; // employing the resources of the channel, performs a linear-regression upon the // ellipsoidal_events. writes the regression into the regress_events and // the residues into the residues. // then, analyzes this residue file, to obtain its variance and average. // also, checks the variance to be symmetric --> residue_symmetric and // the norm of the average. // finally, computes the channel-rate R (and the corresponding Theta and rho) of the variance. // sw: 0=forward x to y, 1=forward y to x, 2=inverse x to y, 3=inverse y to x. // for the results to be meaningful, // the channel should be that obtained by analyzing the events or a relative. int matrix_events_regress(CHN *chan, char *ellipsoidal_events_name, char *regress_events_name, char *regress_events_title, char *residues_name, char *residues_title, unsigned long sw, MAT *array_var, double *residue_symmetric, double *R, double *Theta, double *rho, MAT *array_ave, double *ave_norm, MAT *scratch_1, MAT *scratch_2, MAT *scratch_3, MAT *scratch_4, MAT *scratch_5, MAT *scratch_6, MAT *scratch_7) { FILE *ellipsoidal_events, *regress_events, *residues; unsigned long regression; int y=0; char title_ellipsoidal[200], title_check[200]; y = matrix_validate(&chan->eleven[LAVE]) + matrix_validate(&chan->eleven[RAVE]) + matrix_validate(&chan->eleven[REGRxyFWD]) + matrix_validate(&chan->eleven[REGRxyINV]) + matrix_validate(&chan->eleven[REGRyxFWD]) + matrix_validate(&chan->eleven[REGRyxINV]); if(y != 0) goto tie_point; switch(sw %= 4) { case 0: // x to y, forward. regression = REGRxyFWD; break; case 1: // y to x forward. regression = REGRyxFWD; break; case 2: // x to y inverse. regression = REGRxyINV; break; case 3: // y to x inverse. regression = REGRyxINV; break; }; ellipsoidal_events = fopen(ellipsoidal_events_name, "r"); regress_events = fopen(regress_events_name, "w"); residues = fopen(residues_name, "w"); y = matrix_read_process_event_data2(ellipsoidal_events, title_ellipsoidal, &chan->eleven[LAVE], &chan->eleven[regression], &chan->eleven[RAVE], (sw % 2), regress_events, regress_events_title, residues, residues_title, scratch_1); fclose(ellipsoidal_events); fclose(regress_events); fclose(residues); if(y != 0) goto tie_point; residues = fopen(residues_name, "r"); y = matrix_read_event_data(residues, title_check, array_var, array_ave); fclose(residues); if(y != 0) goto tie_point; y = matrix_channel_rate(array_var, R, Theta, rho, scratch_1, scratch_2, scratch_3, scratch_4, scratch_5, scratch_6); if(y != 0) goto tie_point; y = matrix_isit_symmetric(array_var, residue_symmetric, scratch_1, scratch_2, scratch_3, scratch_4); if(y != 0) goto tie_point; y = matrix_norm(array_ave, 1, ave_norm, scratch_1); if(y != 0) goto tie_point; tie_point: return(y); }; // copyright (c) 2004 by R.I. 'Scibor-Marchocki. last modified Wednesday 28-th April 2004. // eof