AvaSmith-CodingSamples / C / OptimizationMatrixChallenge - C / matvec_util.c
matvec_util.c
Raw
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "matvec.h"

// Allocates memory for the parmeter vector vec. Sets its data field
// to point at a proper amount of memory and sets the len field
// according to parameter len. Returns 0 on success and nonzero
// if len is 0 or negative.
int vector_init(vector_t *vec, long len){
  if(len<=0){
    printf("Invalid length: %ld\n",len);
    return 1;
  }
  vec->data = malloc(sizeof(int) * len);
  vec->len = len;
  return 0;
}

// Allocates memory for the parmeter matrix mat. Sets its data field
// to point at a proper amount of memory and sets the rows,cols fields
// according to parameters rows,cols. Returns 0 on success and nonzero
// if rows,cols are 0 or negative.
int matrix_init(matrix_t *mat, long rows, long cols){
  if(rows<=0 || cols<=0){
    printf("Invalid rows or cols: %ld %ld\n",rows,cols);
    return 1;
  }
  mat->data = malloc(sizeof(int) * rows * cols);
  mat->rows = rows;
  mat->cols = cols;
  return 0;
}

// Frees memory associated with the data field of vec.
void vector_free_data(vector_t *vec){
  free(vec->data);
  vec->len = -1;
}

// Frees memory associated with the data field of mat.
void matrix_free_data(matrix_t *mat){
  free(mat->data);
  mat->rows = -1;
  mat->cols = -1;
}

// Reads data from the specified file and initializes specified vector
// with it. Allocated memory and checks for correct dimensions. The
// format of the file is space separated numbers.
// - first long indicates size of vector
// - remaining ints are data in the vector
// Returns 0 on success and non-zero on error.
int vector_read_from_file(char *fname, vector_t *vec_ref){
  FILE *file = fopen(fname,"r");
  if(file == NULL){
    perror("couldn't open vector file");
    return 1;
  }
  long len;
  assert(fscanf(file, "%ld",&len)==1);
  vector_t vec;
  int ret = vector_init(&vec,len);
  if(ret){
    return ret;
  }
  for(int i=0; i<len; i++){
    int x;
    assert(fscanf(file,"%d",&x)==1);
    VSET(vec,i,x);
  }
  fclose(file);
  *vec_ref = vec;
  return 0;
}

// Reads data from the specified file and initializes specified matrix
// with it. Allocates memory and checks for correct dimensions. The
// format of the file is space separated numbers.
// - first two longs indicate size of matrix
// - remaining ints are data in the matrix
// Returns 0 on success and non-zero on error.
int matrix_read_from_file(char *fname, matrix_t *mat_ref){
  FILE *file = fopen(fname,"r");
  if(file == NULL){
    perror("couldn't open matrix file");
    return 1;
  }
  long rows, cols;
  assert(fscanf(file, "%ld %ld",&rows,&cols) == 2);
  matrix_t mat;
  int ret = matrix_init(&mat,rows,cols);
  if(ret){
    return ret;
  }
  for(int i=0; i<rows; i++){
    for(int j=0; j<cols; j++){
      int x;
      assert(fscanf(file,"%d",&x)==1);
      MSET(mat,i,j,x);
    }
  }
  fclose(file);
  *mat_ref = mat;
  return 0;
}

// Writes a vector to an open file handle. Prints some dimension
// information followed by index and data on each line. Use with
// stdout to print to the screen.
void vector_write(FILE *file, vector_t vec){
  fprintf(file,"%ld x 1 vector\n",vec.len);
  for(int i=0; i<vec.len; i++){
    fprintf(file,"%4d: ",i);
    fprintf(file,"%4d\n", VGET(vec,i));
  }
  return;
}

// Writes a matrix to an open file handle. Prints some dimension
// information followed by index and data on each line. Use with
// stdout to print to the screen.
void matrix_write(FILE *file, matrix_t mat){
  fprintf(file,"%ld x %ld matrix\n",mat.rows,mat.cols);
  for(int i=0; i<mat.rows; i++){
    fprintf(file,"%4d: ",i);
    for(int j=0; j<mat.cols; j++){
      fprintf(file,"%6d ", MGET(mat,i,j));
    }
    fprintf(file,"\n");
  }
  return;
}


// Set elements of the given vector to 0,1,2,...,len
void vector_fill_sequential(vector_t vec){
  for(int i=0; i<vec.len; i++){
    VSET(vec,i,i);
  }
}

// Set elements of the given matrix to 0,1,2,...,len. 
void matrix_fill_sequential(matrix_t mat){
  int c = 0;
  for(int i=0; i<mat.rows; i++){
    for(int j=0; j<mat.cols; j++){
      MSET(mat,i,j,c);
      c++;
    }
  }
}

// getter + setters for vectors and matrices
int mget(matrix_t *mat, int i, int j){
  return mat->data[i*mat->cols + j];
}

void mset(matrix_t *mat, int i, int j, int x){
  mat->data[i*mat->cols + j] = x;
}

int vget(vector_t *vec, int i){
  return vec->data[i];
}
void vset(vector_t *vec, int i, int x){
  vec->data[i] = x;
}

// state of the random number generator for phase09 
unsigned long state = 1;

// generate a random integer
unsigned int pb_rand() {
  state = state * 1103515245 + 12345;
  return (unsigned int)(state/65536) % 32768;
}

// set seed for pb_rand()
void pb_srand(unsigned long seed){
  state = seed;
}

void vector_fill_random(vector_t vec, int max){
  for(int i=0; i<vec.len; i++){
    VSET(vec,i,pb_rand() % max);
  }
}

void matrix_fill_random(matrix_t mat, int max){
  for(int i=0; i<mat.rows; i++){
    for(int j=0; j<mat.cols; j++){
      MSET(mat,i,j,pb_rand() % max);
    }
  }
}