aboutsummaryrefslogtreecommitdiff
path: root/nerv/lib/matrix/generic/matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'nerv/lib/matrix/generic/matrix.c')
-rw-r--r--nerv/lib/matrix/generic/matrix.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/nerv/lib/matrix/generic/matrix.c b/nerv/lib/matrix/generic/matrix.c
new file mode 100644
index 0000000..91577e1
--- /dev/null
+++ b/nerv/lib/matrix/generic/matrix.c
@@ -0,0 +1,57 @@
+#ifdef NERV_GENERIC_MATRIX
+#include "../../../common.h"
+#include "matrix.h"
+/* FIXME: malloc failure detection */
+
+static void nerv_matrix_(data_free)(Matrix *self, Status *status) {
+ assert(*self->data_ref > 0);
+ if (--(*self->data_ref) == 0)
+ {
+ /* free matrix data */
+ MATRIX_DATA_FREE(MATRIX_ELEM_PTR(self), status);
+ free(self->data_ref);
+ free(self);
+ }
+ else NERV_SET_STATUS(status, MAT_NORMAL, 0);
+}
+
+static void nerv_matrix_(data_retain)(Matrix *self) {
+ (*self->data_ref)++;
+}
+
+Matrix *nerv_matrix_(create)(long nrow, long ncol, Status *status) {
+ Matrix *self = (Matrix *)malloc(sizeof(Matrix));
+ self->nrow = nrow;
+ self->ncol = ncol;
+ self->nmax = self->nrow * self->ncol;
+ MATRIX_DATA_ALLOC(&MATRIX_ELEM_PTR(self), &self->stride,
+ sizeof(MATRIX_ELEM) * self->ncol, self->nrow,
+ status);
+ if (status->err_code != MAT_NORMAL)
+ {
+ free(self);
+ return NULL;
+ }
+ self->data_ref = (long *)malloc(sizeof(long));
+ *self->data_ref = 0;
+ nerv_matrix_(data_retain)(self);
+ NERV_SET_STATUS(status, MAT_NORMAL, 0);
+ return self;
+}
+
+void nerv_matrix_(destroy)(Matrix *self, Status *status) {
+ nerv_matrix_(data_free)(self, status);
+}
+
+Matrix *nerv_matrix_(getrow)(Matrix *self, int row) {
+ Matrix *prow = (Matrix *)malloc(sizeof(Matrix));
+ prow->ncol = self->ncol;
+ prow->nrow = 1;
+ prow->stride = self->stride;
+ prow->nmax = prow->ncol;
+ MATRIX_ELEM_PTR(prow) = MATRIX_ROW_PTR(self, row);
+ prow->data_ref = self->data_ref;
+ nerv_matrix_(data_retain)(prow);
+ return prow;
+}
+#endif