Skip to content

Instantly share code, notes, and snippets.

@elliptic-shiho
Last active August 29, 2015 14:16
Show Gist options
  • Save elliptic-shiho/663a5f53dcd74701e58c to your computer and use it in GitHub Desktop.
Save elliptic-shiho/663a5f53dcd74701e58c to your computer and use it in GitHub Desktop.
Matrix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define IS_EFFECTIVE_PTR(ptr) (((ptr) != NULL) && (ptr) != ((void*)0xdeadbeef))
#define PTR(x, type) type *x = NULL;
#define MALLOC(x, type, size) do { \
if (IS_EFFECTIVE_PTR(x)) { \
ERROR("Already allocated pointer:%s", #x); \
exit(-1); \
} \
x = (type*) malloc((sizeof(type)) * size); \
} while (0)
#define FREE(x) do { \
if (!IS_EFFECTIVE_PTR(x)) { \
ERROR("Already done free: %s", #x); \
exit(-1); \
} \
free(x); \
x = ((void*)0xdeadbeef); \
} while(0)
# ifdef NDEBUG
# define CHK_DEBUG()
# define DEBUG(x, ...)
# else
# define CHK_DEBUG() fprintf(stderr, "%s:%d <%s>\n", __FILE__, __LINE__, __FUNCTION__)
# define DEBUG(x, ...) do {\
fprintf(stderr, "%s:%d <%s> -> ", __FILE__, __LINE__, __FUNCTION__);\
fprintf(stderr, x, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
# endif /* end of NDEBUG */
# define ERROR(...) fprintf(stderr, "ERROR occured: "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\nat: file: %s, function: %s, line: %d\n\n", __FILE__, __FUNCTION__, __LINE__)
typedef struct _matrix_t {
size_t size;
int *elements;
} Matrix;
Matrix* matrix_new(size_t size) {
PTR(m, Matrix);
MALLOC(m, Matrix, 1);
m->size = size;
MALLOC(m->elements, int, size*size);
return m;
}
void matrix_free(Matrix *m) {
if (IS_EFFECTIVE_PTR(m)) {
FREE(m->elements);
FREE(m);
}
}
void matrix_set_data(Matrix *m, uint x, uint y, int d) {
if (IS_EFFECTIVE_PTR(m)) {
if (x < m->size && y < m->size) {
*(m->elements + (x * m->size + y)) = d;
}
}
}
void matrix_dump(const Matrix *m) {
if (IS_EFFECTIVE_PTR(m)) {
printf("Matrix Size: %1$dx%1$d\n", m->size);
uint i;
uint j;
for (i = 0; i < m->size; i++) {
printf("Row %2d : ", i);
for (j = 0; j < m->size; j++) {
printf("\t%2d", *(m->elements + (i * m->size + j)));
}
printf("\n");
}
}
}
void matrix_add(Matrix *d, const Matrix *s) {
if (IS_EFFECTIVE_PTR(s) && IS_EFFECTIVE_PTR(d) ) {
if (s->size == d->size) {
uint i;
uint j;
size_t size = s->size;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
*(d->elements + (i * size + j)) += *(s->elements + (i * size + j));
}
}
}
}
}
/* d = ds */
void matrix_mul(Matrix *d, const Matrix *s) {
if (IS_EFFECTIVE_PTR(s) && IS_EFFECTIVE_PTR(d) ) {
if (s->size == d->size) {
uint i;
uint j;
uint k;
size_t size = s->size;
PTR(buf, int);
MALLOC(buf, int, size * size);
memset(buf, 0, size*size*sizeof(int));
int pos;
for (i = 0; i < size; i++) {
for (k = 0; k < size; k++) {
pos = i * size + k;
for (j = 0; j < size; j++) {
buf[i * size + j] += *(d->elements + pos) * *(s->elements + k * size + j);
}
}
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
pos = i * size + j;
*(d->elements + pos) = buf[pos];
}
}
}
}
}
int main() {
PTR(m, Matrix);
PTR(m2, Matrix);
int i;
m = matrix_new(2);
m2 = matrix_new(2);
matrix_set_data(m, 0, 0, 1);
matrix_set_data(m, 0, 1, 1);
matrix_set_data(m, 1, 0, 1);
matrix_set_data(m, 1, 1, 0);
matrix_set_data(m2, 0, 0, 1);
matrix_set_data(m2, 0, 1, 1);
matrix_set_data(m2, 1, 0, 1);
matrix_set_data(m2, 1, 1, 0);
for(i = 0; i < 10; i++) {
matrix_mul(m, m2);
matrix_dump(m);
}
matrix_free(m);
matrix_free(m2);
return 0;
}
#include <iostream>
#include <assert.h>
template <typename T, int N, int M>
class Matrix {
private:
T values[N][M];
public:
T get(int x, int y);
void set(int x, int y, T v);
void print();
void fill(T v);
Matrix<T, N, M> operator+(Matrix<T, N, M> another);
template <int P>
Matrix<T, N, M> operator*(Matrix<T, M, P> another);
};
template <typename T, int N, int M>
void Matrix<T, N, M>::set(int x, int y, T v) {
assert(x >= 0);
assert(y >= 0);
assert(x < N);
assert(y < M);
values[x][y] = v;
}
template <typename T, int N, int M>
Matrix<T, N, M> Matrix<T, N, M>::operator+(Matrix<T, N, M> another) {
Matrix<T, N, M> *m = new Matrix<T, N, M>();
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
m->set(i, j, get(i, j) + another.get(i, j));
}
}
return *m;
}
template <typename T, int N, int M>
template <int P>
Matrix<T, N, M> Matrix<T, N, M>::operator*(Matrix<T, M, P> another) {
Matrix<T, N, M> *m = new Matrix<T, N, M>();
m->fill(0);
for(int i = 0; i < N; i++) {
for(int k = 0; k < M; k++) {
for(int j = 0; j < M; j++) {
m->set(i, j, m->get(i, j) + get(i, k) * another.get(k, j));
}
}
}
return *m;
}
template <typename T, int N, int M>
T Matrix<T, N, M>::get(int x, int y) {
assert(x >= 0);
assert(y >= 0);
assert(x < N);
assert(y < M);
return values[x][y];
}
template <typename T, int N, int M>
void Matrix<T, N, M>::fill(T v) {
for(int i = 0; i < N; i++) {
for(int j = 0; j < M; j++) {
values[i][j] = v;
}
}
}
template <typename T, int N, int M>
void Matrix<T, N, M>::print() {
using namespace std;
cout << "Matrix " << N << "x" << M << endl << "[" << endl;
for(int i = 0; i < N; i++) {
cout << "\t[";
for(int j = 0; j < M; j++) {
if(j > 0) {
cout << " ";
}
cout << values[i][j];
}
cout << "]" << endl;
}
cout << "]" << endl;
}
int main(int ac, char** av) {
Matrix<int, 2, 2> m, m2;
m.set(0, 0, 1);
m.set(0, 1, 1);
m.set(1, 0, 1);
m.set(1, 1, 0);
m2 = m;
for(int i = 0; i < 10; i++) {
m2 = m2 * m;
m2.print();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment