diff --git a/header.h b/header.h
index ce8bc5a66a5634c3897d9f6ae5ef13d402779762..df2af685171541080c1ea6f5cfad2952aa519748 100644
--- a/header.h
+++ b/header.h
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <math.h>
 #include <errno.h>
+#include <time.h>
 
 #define ARGS_NUM 9
 
@@ -13,6 +14,8 @@ double Pipi = M_PI * M_PI; // Pipi = Pi * Pi
 
 void print_errno(void);
 void getParams(int argc, char* argv[], FILE *fp);
-double f(double x, double y);
-void u(int i, int j, double **u, double **f);
+//double f(double x, double y);
+//void u(int i, int j, double **u, double **f);
 double residueNorm(double *r);
+double timestamp(void);
+//void sor(double *A, double *b, double *x, double w);
diff --git a/pdeSolver.c b/pdeSolver.c
index afd011be23a9e5616b07599227fd9bcf4630377f..c23fca311adc569defc0a6f491ace6b8bfe2a6b4 100644
--- a/pdeSolver.c
+++ b/pdeSolver.c
@@ -4,11 +4,38 @@
 u(i,j) = f(x,y) + (u(i+1,j) + u(i-1,j))/Δx² + (u(i,j+1) + u(i,j-1))/Δy² + (-u(i+1,j)+u(i-1,j))/2Δx + (-u(i,j+1)+u(i,j-1))/2Δy
          --------------------------------------------------------------------------------------------------------------------
                                                           2/Δx² + 2/Δy² + 4π²
-
+Resíduo:
+f(x,y) = (2/Δx² + 2/Δy² + 4π²) * u(i,j) - ((u(i+1,j) + u(i-1,j))/Δx² + (u(i,j+1) + u(i,j-1))/Δy² + (-u(i+1,j)+u(i-1,j))/2Δx + (-u(i,j+1)+u(i,j-1))/2Δy)
 */
 
 //#define MAX_SIZE 100000000 // 100 MB.
 //int inMemory = 0;
+int N = 9;
+
+void print_vector(double *x) {
+	int i;
+	for(i=0; i<N; ++i) {
+		printf("%f ", x[i]);
+	}
+	printf("\n");
+}
+
+void print_matrix(double *A) {
+	int i,j;
+	for(i=0; i<Nx * Ny; ++i) {
+		for(j=0; j<Nx * Ny; ++j) {
+			printf("%.0f ", A[in(i,j)]);
+		}
+		printf("\n");
+	}
+	printf("\n\n\n");
+}
+
+double timestamp(void) {
+    struct timeval tp;
+    gettimeofday(&tp, NULL);
+    return((double)(tp.tv_sec + tp.tv_usec/1000000.0));
+}
 
 void print_errno(void) {
     printf("%s",strerror(errno));
@@ -35,16 +62,22 @@ void getParams(int argc, char* argv[], FILE *fp) {
         }
     }
 }
-
+/*
 double f(double x, double y) { // If stored in memory, it will need Nx * Ny * 8 bytes of memory. Should we do it?
 	return 4 * M_PI * ( ( sin(2 * M_PI * x) ) * ( sinh(M_PI * y) ) + ( sin(2 * Pipi - M_PI * x) ) * ( sinh(Pipi - M_PI * y) ));
 }
+*/
+double f(int n) { // If stored in memory, it will need Nx * Ny * 8 bytes of memory. Should we do it?
+	int i = n / Nx, j = n % Nx;
+	double x = i * Hx, y = j * Hy;
+	return 4 * M_PI * ( ( sin(2 * M_PI * x) ) * ( sinh(M_PI * y) ) + ( sin(2 * Pipi - M_PI * x) ) * ( sinh(Pipi - M_PI * y) ));
+}
 
 inline int in(int i, int j) {
 // Calcula o indice do vetor, como se fosse uma matriz.
 	return i*Ny + j;
 }
-
+/*
 void calcU(int i, int j, double *u) {
 	double res = 0;
 	res += f(i,j) + (u[ in(i+1,j) ] + u[ in(i-1,j) ] ) / Hx * Hx + (u[ in(i,j+1) ] + u[ in(i,j-1) ]) / Hy * Hy;
@@ -52,6 +85,29 @@ void calcU(int i, int j, double *u) {
 	res = res / UDivisor;
 	u[ in(i,j) ] = res;
 }
+*/
+double calcU(int n, double *u) {
+/*
+u(i,j) = f(x,y) + (u(i+1,j) + u(i-1,j))/Δx² + (u(i,j+1) + u(i,j-1))/Δy² + (-u(i+1,j)+u(i-1,j))/2Δx + (-u(i,j+1)+u(i,j-1))/2Δy
+         --------------------------------------------------------------------------------------------------------------------
+                                                          2/Δx² + 2/Δy² + 4π²
+*/
+	double res = 0;
+	res += f(n) + (u[n+Ny] + u[n-Ny] ) / Hx * Hx + (u[n+1] + u[n-1]) / Hy * Hy;
+	res += (u[n-Ny] - u[n+Ny]) / 2 * Hx + (u[n-1] - u[n+1]) / 2 * Hy;
+	res = res / UDivisor;
+	//u[n] = res;
+	return res;
+}
+
+double calcRes(int n, double *u) {
+//f(x,y) = (2/Δx² + 2/Δy² + 4π²) * u(i,j) - ((u(i+1,j) + u(i-1,j))/Δx² + (u(i,j+1) + u(i,j-1))/Δy² + (-u(i+1,j)+u(i-1,j))/2Δx + (-u(i,j+1)+u(i,j-1))/2Δy)
+	double res = 0;
+	//res = (2/Hx*Hx + 2/Hy*Hy + 4*M_PI*M_PI) * u[n];
+	res = UDivisor * u[n];
+	res -= ((u[n+Ny] + u[n-Ny] ) / Hx * Hx + (u[n+1] + u[n-1]) / Hy * Hy + (u[n-Ny] - u[n+Ny]) / 2 * Hx + (u[n-1] - u[n+1]) / 2 * Hy);
+	return res;
+}
 
 double residueNorm(double *r) {
 // u is only a row and r is the last residue
@@ -63,64 +119,145 @@ double residueNorm(double *r) {
 	return sqrt(res);
 }
 
+void generate_matrix(double *A, double *b) {
+	int i,j;
+	for(i=0; i<N*N; ++i) {
+		A[i] = 0;
+	}
+	for(i=0; i<N; ++i) {
+		for(j=0; j<N; ++j) {
+			if(i == j)
+				A[in(i,j)] = -4;
+		}
+	}
+	A[in(0,1)] = 1;
+	A[in(0,3)] = 1;
+	A[in(1,0)] = 1;
+	A[in(1,2)] = 1;
+	A[in(1,4)] = 1;
+	A[in(2,1)] = 1;
+	A[in(2,5)] = 1;
+	A[in(3,0)] = 1;
+	A[in(3,4)] = 1;
+	A[in(3,6)] = 1;
+	A[in(4,1)] = 1;
+	A[in(4,3)] = 1;
+	A[in(4,5)] = 1;
+	A[in(4,7)] = 1;
+	A[in(5,2)] = 1;
+	A[in(5,4)] = 1;
+	A[in(5,8)] = 1;
+	A[in(6,3)] = 1;
+	A[in(6,7)] = 1;
+	A[in(7,4)] = 1;
+	A[in(7,6)] = 1;
+	A[in(7,8)] = 1;
+	A[in(8,5)] = 1;
+	A[in(8,7)] = 1;
+	b[0] = -100;
+	b[1] = -20;
+	b[2] = -20;
+	b[3] = -80;
+	b[4] = 0;
+	b[5] = 0;
+	b[6] = -260;
+	b[7] = -180;
+	b[8] = -180;
+}
+
+
+/*
+a11 * x1 + a12 * x2 + a13 * x3 = b1 -> x1 = (b1 - (a12 * x2 + a13 * x3)) / a11
+x1 = u11;
+x2 = u12;
+x3 = u13;
+x4 = u21;
+x5 = u22;
+x6 = u23;
+
+Res[1] = b1 - (a11 * x1 + a12 * x2 + a13 * x3)
+*/
+
+
+void sor(double *b, double *x, double *r, double *timeSor, double *timeResNorm) {
+	int i,j,k; // Ax = b -> ?u = f
+	double sigma, now, fxy, res, maxRes = 0, tRes = 0; // maxRes is the biggest residue, tRes is total residue in this iteration.
+	for(k=0; k<MaxI; k++) {
+		now = timestamp();
+		for(i=0; i<Nx * Ny; ++i) {
+			//b[i] = f();
+			/*sigma = 0;
+			for(j=0; j<N; ++j) {
+				sigma = sigma + A[in(i,j)] * x[j];
+			}
+			sigma = sigma - A[in(i,i)] * x[i];*/
+			//                  b[1] - somatorio / a11
+			//x[i] = x[i] + W * ((b[i] - sigma)/A[in(i,i)] - x[i]);
+			x[i] = x[i] + W * (calcU(i,x) - x[i]);
+			//res = b[i] - x[i];
+		}
+		*timeSor += timestamp() - now;
+		now = timestamp();
+		res = f(k);
+		printf("Res = %lf - ",res);
+		/*for(i = 0; i < Nx * Ny; ++i)
+			res -= A[in(i,i)] * x[i];*/
+		res -= calcRes(k,x);
+		printf("Res = %lf\n",res);
+		if(res > maxRes)
+			maxRes = res;
+		tRes += res * res;
+		//residueNorm(r);
+		r[k] = sqrt(tRes);
+		tRes = 0;
+		*timeResNorm += timestamp() - now;
+	}
+	*timeSor = *timeSor / MaxI;
+	*timeResNorm = *timeResNorm / MaxI;
+}
+
 int main(int argc, char *argv[]) {
 	int i, j, k;
 	FILE *fpExit;
 
 	getParams(argc,argv,fpExit);
 
-	Nx = (1/Hx);
-	Ny = (1/Hy);
+	Nx = (M_PI/Hx);
+	Ny = (M_PI/Hy);
 	Nx++;
 	Ny++;
-	if(Nx != Ny) {
-		puts("Not a square matrix. Result will be undetermined or impossible.");
-		exit(-1);
-	}
 	W = (2 - (Hx + Hy)) / 2;
-	if(W < 1) {
-		puts("Relaxation factor less than 1 - program may not work as you expect.");
-	}
 	UDivisor = (2 / Hx * Hx) + (2 / Hy * Hy) + 4 * Pipi;
-	/*if((Nx * Ny * 8) <= MAX_SIZE) { // Should we save a matrix with f(x,y) values?
-		inMemory = 1;
-	}*/
 
 	double sigma;
-	//double **u,**f;
+	//double *A = calloc(sizeof(double), Nx * Ny * Nx * Ny);
+	double *b, *x, *r, *timeSor, *timeResNorm;
 
-	/*for(i=0; i<Nx; i++) {
-		for(j=0; i<Ny; i++) {
-			u[i][j] = calloc(sizeof(double));
-			f[i][j] = malloc(sizeof(double));
-			f[i][j] = f(i*Hx,j*Hy);
-		}
-	}*/
+	//generate_matrix(A,b);
 
-	double *u = calloc(sizeof(double), Nx * Ny);
+	b = malloc(Nx * Ny * sizeof(double));
+	x = malloc(Nx * Ny * sizeof(double));
+	r = malloc(MaxI * sizeof(double));
+	timeSor = calloc(1,sizeof(double));
+	timeResNorm = calloc(1,sizeof(double));
 
 	sigma = sinh(M_PI * M_PI);
-	for(i=0; i<Nx; i++) { // Calculate side extremities (top and bottom are always 0).
-		u[ in(i,0) ] = sin(2 * M_PI * (M_PI - (i * Hx))) * sigma;
-		u[ in(i,Nx) ] = sin(2 * M_PI * (i * Hx));
-	}
+	/*for(i=0; i<Nx; ++i) { // Calculate side extremities (top and bottom are always 0, so calloc already took care of it).
+		A[ in(i,0) ] = sin(2 * M_PI * (M_PI - (i * Hx))) * sigma;
+		A[ in(i,Nx) ] = sin(2 * M_PI * (i * Hx));
+	}*/
 
-	// Nx columns and Ny rows.
+	//print_matrix(A);
 
-	/*for(k=0; k<MaxI; k++) {
-		for(i=1; i<Ny; i++) {
-			sigma = 0;
-			for(j=1; j<Nx; j++) {
-				/*if(j != i) {
-					sigma += a[i][j] * fi[i];
-				}*/
-				/*sigma += a[i][j] * fi[i];
-			}
-			sigma -= a[i][i] * fi[i];
-			//fi[i] = (1 - W) * fi[i] + W/a[i][i] * (b[i] - sigma);
-			fi[i] = fi[i] + W * ((b[i] - sigma) / a[i][i] - fi[i])
-		}
-	}*/
+	sor(b,x,r,timeSor,timeResNorm);
+
+	print_vector(x);
+
+	printf("TimeSor: %lf\nTimeResNorm: %lf\n\nNorma do Resíduo\n",*timeSor,*timeResNorm);
+	for(i=0; i<MaxI; ++i) {
+		printf("i=%d: %lf\n",i,r[i]);
+	}
+	// Nx columns and Ny rows.
 
 	return 0;
 }
\ No newline at end of file
diff --git a/sor.c b/sor.c
new file mode 100644
index 0000000000000000000000000000000000000000..779bf5aa0bf5b38f3199e87b8a9d5d801bec22f3
--- /dev/null
+++ b/sor.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define SIZE 9
+
+int N = SIZE;
+int MaxI = 10;
+
+inline int in(int i, int j) {
+	return i*N + j;
+}
+
+void generate_matrix(double *A, double *b) {
+/*	A[in(0,0)] = 10;
+	A[in(0,1)] = 4;
+	A[in(0,2)] = 2;
+	A[in(1,0)] = -2;
+	A[in(1,1)] = 15;
+	A[in(1,2)] = 3;
+	A[in(2,0)] = 2;
+	A[in(2,1)] = -2;
+	A[in(2,2)] = 13;
+	b[0] = 5;
+	b[1] = 3;
+	b[2] = 4;*/
+	int i,j;
+	for(i=0; i<N*N; ++i) {
+		A[i] = 0;
+	}
+	for(i=0; i<N; ++i) {
+		for(j=0; j<N; ++j) {
+			if(i == j)
+				A[in(i,j)] = -4;
+		}
+	}
+	A[in(0,1)] = 1;
+	A[in(0,3)] = 1;
+	A[in(1,0)] = 1;
+	A[in(1,2)] = 1;
+	A[in(1,4)] = 1;
+	A[in(2,1)] = 1;
+	A[in(2,5)] = 1;
+	A[in(3,0)] = 1;
+	A[in(3,4)] = 1;
+	A[in(3,6)] = 1;
+	A[in(4,1)] = 1;
+	A[in(4,3)] = 1;
+	A[in(4,5)] = 1;
+	A[in(4,7)] = 1;
+	A[in(5,2)] = 1;
+	A[in(5,4)] = 1;
+	A[in(5,8)] = 1;
+	A[in(6,3)] = 1;
+	A[in(6,7)] = 1;
+	A[in(7,4)] = 1;
+	A[in(7,6)] = 1;
+	A[in(7,8)] = 1;
+	A[in(8,5)] = 1;
+	A[in(8,7)] = 1;
+	b[0] = -100;
+	b[1] = -20;
+	b[2] = -20;
+	b[3] = -80;
+	b[4] = 0;
+	b[5] = 0;
+	b[6] = -260;
+	b[7] = -180;
+	b[8] = -180;
+}
+
+void print_vector(double *x) {
+	int i;
+	for(i=0; i<N; ++i) {
+		printf("%f ", x[i]);
+	}
+	printf("\n");
+}
+
+void print_matrix(double *A) {
+	int i,j;
+	for(i=0; i<N; ++i) {
+		for(j=0; j<N; ++j) {
+			printf("%.0f ", A[in(i,j)]);
+		}
+		printf("\n");
+	}
+	printf("\n\n\n");
+}
+
+void sor(double *A, double *b, double *x, double w) {
+	int i,j,k;
+	double sigma;
+	for(k=0; k<MaxI; k++) {
+		for(i=0; i<N; ++i) {
+			sigma = 0;
+			for(j=0; j<N; ++j) {
+				sigma = sigma + A[in(i,j)] * x[j];
+			}
+			sigma = sigma - A[in(i,i)] * x[i];
+			x[i] = x[i] + w * ((b[i] - sigma)/A[in(i,i)] - x[i]);
+		}
+	}
+}
+
+int main(int argc, char* argv[]) {
+	double *A,*b,*x,w;
+	int i,j;
+	A = malloc(N * N * sizeof(double));
+	b = malloc(N * sizeof(double));
+	x = malloc(N * sizeof(double));
+	generate_matrix(A,b);
+	for(i=0; i<N; ++i) {
+		x[i] = 1;
+	}
+	print_vector(x);
+	print_matrix(A);
+	print_vector(b);
+	w = 1.25;
+	sor(A,b,x,w);
+
+	print_vector(x);
+}
\ No newline at end of file