Init, Implementation of Create, Destroy, Init and basic get and set functions.
This commit is contained in:
226
tensor.c
Normal file
226
tensor.c
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "tensor.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
tensor tensor_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct _tensor));
|
||||
}
|
||||
|
||||
void tensor_destroy(tensor t)
|
||||
{
|
||||
if (!tensor_is_empty(t)) {
|
||||
free(t->size);
|
||||
free(t->elements);
|
||||
}
|
||||
}
|
||||
|
||||
int tensor_is_empty(tensor t){
|
||||
return t->elements == NULL || t->size == NULL;
|
||||
}
|
||||
|
||||
int _tensor_check_size(const int *size, int dim)
|
||||
{
|
||||
int i;
|
||||
if(dim < 0) return 0;
|
||||
for(i = 0; i < dim; i++) {
|
||||
if(size[i] < 1) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _tensor_set_size(tensor t, const int *size, int dim)
|
||||
{
|
||||
int *temp;
|
||||
t_type *t_temp;
|
||||
int i, num_elem = 1;
|
||||
|
||||
for(i = 0; i < dim; i++) {
|
||||
num_elem *= size[i];
|
||||
}
|
||||
|
||||
if(!_tensor_check_size(size, dim)) return 0;
|
||||
/* Try allocating memory for the size array of the Tensor */
|
||||
temp = realloc(t->size, dim * sizeof(int));
|
||||
if(temp == NULL && dim != 0) return 0;
|
||||
/* Try allocating memory for the Tensor */
|
||||
t_temp = realloc(t->elements, num_elem * sizeof(t_type));
|
||||
if(t_temp == NULL) {
|
||||
/* Revert to before the function call and return */
|
||||
t->size = realloc(temp, t->dimension * sizeof(int));
|
||||
if(t->size == NULL && t->dimension != 0) {
|
||||
printf("Fatal error in _tensor_set_size when reallocating memory.");
|
||||
exit(-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Setting the size array */
|
||||
t->size = temp;
|
||||
if(dim != 0) memcpy(t->size, size, dim * sizeof(int));
|
||||
t->dimension = dim;
|
||||
/* Setting the elements pointer and memory usage */
|
||||
t->elements = t_temp;
|
||||
t->num_elem = num_elem;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tensor_set(tensor t, const int *index, t_type val)
|
||||
{
|
||||
int i, offset = 0;
|
||||
if(tensor_is_empty(t)) return 0;
|
||||
|
||||
for(i = 0; i < t->dimension - 1; i++) {
|
||||
if(t->size[i] >= index[i]) return 0;
|
||||
offset += t->size[i] * index[i];
|
||||
}
|
||||
offset += index[t->dimension - 1];
|
||||
t->elements[offset] = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
t_type tensor_get(tensor t, const int *index, int *success)
|
||||
{
|
||||
int i, offset = 0;
|
||||
if(tensor_is_empty(t)) return 0;
|
||||
|
||||
for(i = 0; i < t->dimension - 1; i++) {
|
||||
if(t->size[i] <= index[i]) {
|
||||
if(success != NULL) *success = 0;
|
||||
return 0;
|
||||
}
|
||||
offset += t->size[i] * index[i];
|
||||
}
|
||||
offset += index[t->dimension - 1];
|
||||
if(success != NULL) *success = 1;
|
||||
return t->elements[offset];
|
||||
}
|
||||
|
||||
int tensor_init_one(tensor t, int dimension, const int *size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!_tensor_set_size(t, size, dimension)) return 0;
|
||||
for(i = 0; i < t->num_elem; i++) {
|
||||
t->elements[i] = (t_type) 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tensor_init_zero(tensor t, int dimension, const int *size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!_tensor_set_size(t, size, dimension)) return 0;
|
||||
for(i = 0; i < t->num_elem; i++) {
|
||||
t->elements[i] = (t_type) 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tensor_init_rand(tensor t, int dimension, const int *size)
|
||||
{
|
||||
int i;
|
||||
srand(time(NULL));
|
||||
|
||||
if(!_tensor_set_size(t, size, dimension)) return 0;
|
||||
for(i = 0; i < t->num_elem; i++) {
|
||||
t->elements[i] = (t_type) rand();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void tensor_for_each_elem(tensor t, t_type (*func)(t_type))
|
||||
{
|
||||
int i;
|
||||
srand(time(NULL));
|
||||
|
||||
for(i = 0; i < t->num_elem; i++) {
|
||||
t->elements[i] = func(t->elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void tensor_print(tensor t)
|
||||
{
|
||||
int i, j;
|
||||
int *indx;
|
||||
|
||||
if(tensor_is_empty(t)){
|
||||
printf("<empty tensor>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Tensor of dimension %i and size (", t->dimension);
|
||||
for(i = 0; i < t->dimension - 1; i++) {
|
||||
printf("%i, ", t->size[i]);
|
||||
}
|
||||
if(t->dimension == 0) printf("): ");
|
||||
else printf("%i): ", t->size[t->dimension - 1]);
|
||||
|
||||
|
||||
if(t->dimension == 0) {
|
||||
/* Skalar */
|
||||
printf(PRINT_STRING, t->elements[0]);
|
||||
putchar('\n');
|
||||
} else if (t->dimension == 1) {
|
||||
/* Spaltenvektor */
|
||||
if(t->size[0] == 1) {
|
||||
putchar('(');
|
||||
printf(PRINT_STRING, t->elements[0]);
|
||||
printf(")\n");
|
||||
} else {
|
||||
printf("\n/");
|
||||
printf(PRINT_STRING, t->elements[0]);
|
||||
printf("\\\n");
|
||||
for(i = 1; i < t->size[0] - 1; i++) {
|
||||
putchar('|');
|
||||
printf(PRINT_STRING, t->elements[i]);
|
||||
printf("|\n");
|
||||
}
|
||||
printf("\\");
|
||||
printf(PRINT_STRING, t->elements[t->size[0] - 1]);
|
||||
printf("/\n");
|
||||
}
|
||||
} else if (t->dimension == 2) {
|
||||
/* Matix */
|
||||
indx = malloc(sizeof(int) * 2);
|
||||
if(t->size[0] == 1) {
|
||||
putchar('(');
|
||||
indx[1] = 0;
|
||||
for(i = 0; i < t->size[1]; i++) {
|
||||
indx[0] = i;
|
||||
printf(PRINT_STRING, tensor_get(t, indx, NULL));
|
||||
}
|
||||
printf(")\n");
|
||||
} else {
|
||||
printf("\n/");
|
||||
indx[1] = 0;
|
||||
for(i = 0; i < t->size[1]; i++) {
|
||||
indx[0] = i;
|
||||
printf(PRINT_STRING, tensor_get(t, indx, NULL));
|
||||
}
|
||||
printf("\\\n");
|
||||
for(i = 1; i < t->size[0] - 1; i++) {
|
||||
putchar('|');
|
||||
indx[1] = i;
|
||||
for(j = 0; j < t->size[1]; j++) {
|
||||
indx[0] = j;
|
||||
printf(PRINT_STRING, tensor_get(t, indx, NULL));
|
||||
}
|
||||
printf("|\n");
|
||||
}
|
||||
printf("\\");
|
||||
indx[t->size[1] - 1] = 0;
|
||||
for(i = 0; i < t->size[1]; i++) {
|
||||
indx[0] = i;
|
||||
printf(PRINT_STRING, tensor_get(t, indx, NULL));
|
||||
}
|
||||
printf("/\n");
|
||||
}
|
||||
free(indx);
|
||||
} else {
|
||||
printf(" print function not yet implemented for dim > 2.");
|
||||
}
|
||||
}
|
||||
|
||||
40
tensor.h
Normal file
40
tensor.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef TENSOR_H_INCLUDED
|
||||
#define TENSOR_H_INCLUDED
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define PRINT_STRING " %4.1f "
|
||||
|
||||
typedef float t_type;
|
||||
|
||||
typedef struct _tensor {
|
||||
t_type *elements;
|
||||
int dimension;
|
||||
int *size;
|
||||
int num_elem;
|
||||
} *tensor;
|
||||
|
||||
|
||||
tensor tensor_new(void);
|
||||
void tensor_destroy(tensor t);
|
||||
|
||||
int tensor_is_empty(tensor t);
|
||||
|
||||
int _tensor_check_size(const int *size, int dim);
|
||||
int _tensor_set_size(tensor t, const int *size, int dim);
|
||||
|
||||
int tensor_set(tensor t, const int *index, t_type val);
|
||||
t_type tensor_get(tensor t, const int *index, int *success);
|
||||
|
||||
int tensor_init_one(tensor t, int dimension, const int *size);
|
||||
int tensor_init_zero(tensor t, int dimension, const int *size);
|
||||
int tensor_init_rand(tensor t, int dimension, const int *size);
|
||||
|
||||
void tensor_for_each_elem(tensor t, t_type (*func)(t_type));
|
||||
void tensor_print(tensor t);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user