From 5e407d74130accfbbf94d2cabcb03fc126a89410 Mon Sep 17 00:00:00 2001 From: Determinant Date: Wed, 24 Jun 2015 22:48:24 +0800 Subject: separate non-Lua part of matrix code to a dedicated dir --- nerv/lib/matrix/generic/mmatrix.c | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 nerv/lib/matrix/generic/mmatrix.c (limited to 'nerv/lib/matrix/generic/mmatrix.c') diff --git a/nerv/lib/matrix/generic/mmatrix.c b/nerv/lib/matrix/generic/mmatrix.c new file mode 100644 index 0000000..e3d1f93 --- /dev/null +++ b/nerv/lib/matrix/generic/mmatrix.c @@ -0,0 +1,82 @@ +#ifdef NERV_GENERIC_MMATRIX +#include "matrix.h" +#include "elem_type.h" +#define MATRIX_DATA_FREE(ptr, status) host_matrix_(free)(ptr, status) +#define MATRIX_DATA_ALLOC(dptr, stride, width, height, status) \ + host_matrix_(alloc)(dptr, stride, width, height, status) +#define NERV_GENERIC_MATRIX +#include "../../../common.h" +#include "../../io/chunk_file.h" +#include "string.h" + +static void host_matrix_(free)(MATRIX_ELEM *ptr, Status *status) { + free(ptr); + NERV_SET_STATUS(status, MAT_NORMAL, 0); +} + +static void host_matrix_(alloc)(MATRIX_ELEM **dptr, size_t *stride, + long width, long height, Status *status) { + if ((*dptr = (MATRIX_ELEM *)malloc(width * height)) == NULL) + NERV_EXIT_STATUS(status, MAT_INSUF_MEM, 0); + *stride = width; + NERV_SET_STATUS(status, MAT_NORMAL, 0); +} + +#include "matrix.c" +Matrix *nerv_matrix_(load)(ChunkData *cdp, Status *status) { + int i, j; + long nrow, ncol; + FILE *fp = cdp->fp; + Matrix *self; + if (fscanf(fp, "%ld %ld", &nrow, &ncol) != 2) + NERV_EXIT_STATUS(status, MAT_INVALID_FORMAT, 0); + self = nerv_matrix_(create)(nrow, ncol, status); + if (status->err_code != MAT_NORMAL) + return NULL; + for (i = 0; i < nrow; i++) + { + MATRIX_ELEM *row = MATRIX_ROW_PTR(self, i); + for (j = 0; j < ncol; j++) + if (fscanf(fp, MATRIX_ELEM_FMT, row + j) != 1) + { + free(self); + NERV_EXIT_STATUS(status, MAT_INVALID_FORMAT, 0); + } + } + NERV_SET_STATUS(status, MAT_NORMAL, 0); + return self; +} + +void nerv_matrix_(save)(Matrix *self, ChunkFile *cfp, Status *status) { + int i, j; + long nrow = self->nrow, ncol = self->ncol; + FILE *fp = cfp->fp; + if (fprintf(fp, "%ld %ld\n", nrow, ncol) < 0) + NERV_EXIT_STATUS(status, MAT_WRITE_ERROR, 0); + for (i = 0; i < nrow; i++) + { + MATRIX_ELEM *row = MATRIX_ROW_PTR(self, i); + for (j = 0; j < ncol; j++) + if (fprintf(fp, MATRIX_ELEM_WRITE_FMT " ", row[j]) < 0) + NERV_EXIT_STATUS(status, MAT_WRITE_ERROR, 0); + if (fprintf(fp, "\n") < 0) + NERV_EXIT_STATUS(status, MAT_WRITE_ERROR, 0); + } + NERV_SET_STATUS(status, MAT_NORMAL, 0); +} + +void nerv_matrix_(copy_from)(Matrix *a, const Matrix *b, + int a_begin, int b_begin, int b_end, + Status *status) { + if (!(0 <= b_begin && b_begin < b_end && b_end <= b->nrow && + a_begin + b_end - b_begin <= a->nrow)) + NERV_EXIT_STATUS(status, MAT_INVALID_COPY_INTERVAL, 0); + if (a->ncol != b->ncol) + NERV_EXIT_STATUS(status, MAT_MISMATCH_DIM, 0); + memmove(MATRIX_ROW_PTR(a, a_begin), + MATRIX_ROW_PTR(b, b_begin), + sizeof(MATRIX_ELEM) * b->ncol * (b_end - b_begin)); + NERV_SET_STATUS(status, MAT_NORMAL, 0); +} + +#endif -- cgit v1.2.3