Last active
August 29, 2015 14:16
-
-
Save elliptic-shiho/663a5f53dcd74701e58c to your computer and use it in GitHub Desktop.
Matrix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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