Ejemplo n.º 1
0
/*Conjugate gradient method from wikipedia. First version by Jasmin, changes made by Alex*/
int conjugateGradient(struct Matrix* a, struct Vector* b, struct Vector* initialVal, struct Vector** x, int size, double precision, int steps){
	
	copy_Vector(initialVal,x[0]);
	//This could still be optimised
	struct Vector** r = malloc(sizeof(struct Vector*)*steps);	
	for (int j=0; j < steps; j++) {
		r[j] = new_Vector(size);
	}
	struct Vector* p = new_Vector(size);
	struct Vector* help=new_Vector(size);
	struct Vector* help1=new_Vector(size);

	double alpha, beta, sp1, sp2;

	multiply_Matrix_Vector(a,x[0],help);
	scale_Vector(-1,help,help);
	//set r[0]
	add_Vectors(b,help,r[0]);
	copy_Vector(r[0],p);
	int i=0;
	int lastIndex=0;
	for(i=0;i<steps-1;i++){
		sp1 =scalarproductRn(r[i],r[i],size);
		sp2 =scalarproductMatrix(a,p,p,size);
		alpha = sp1/sp2;
		scale_Vector(alpha,p,help1);
		add_Vectors(x[i],help1,x[i+1]);
		multiply_Matrix_Vector(a,p,help);
		scale_Vector(-1*alpha,help,help);
		add_Vectors(r[i],help,r[i+1]);
		lastIndex=i+1;
		if(vectornorm(r[i+1])<precision){
			break;
		}
		sp1=scalarproductRn(r[i+1],r[i+1],size);
		sp2=scalarproductRn(r[i],r[i],size);
		beta = sp1/sp2;
		scale_Vector(beta,p,help);
		add_Vectors(help,r[i+1],p);		
	}
	delete_Vector(p);
	delete_Vector(help);
	delete_Vector(help1);
	for (int j=0; j < steps; j++) {
		delete_Vector(r[j]);
	}
	free(r);
	return lastIndex;

}
Ejemplo n.º 2
0
/*Gives you the gradient in x of function above, result is stored in gradient*/
void getGradient(struct Matrix* a, struct Vector* b, struct Vector* x, struct Vector* gradient, int size){
	struct Vector* help= new_Vector(size);
	struct Vector* help2= new_Vector(size);
	struct Matrix* transposed=new_Matrix(size,size);
	transpose(a,transposed);
	multiply_Matrix_Vector(a,x, help);
	for(int i=0;i<size;i++){
		help->values[i]=help->values[i]-b->values[i];	
	}
	multiply_Matrix_Vector(transposed,help,help2);
	scale_Vector(2,help2,gradient);
	delete_Vector(help);
	delete_Vector(help2);
	delete_Matrix(transposed);	
}
Ejemplo n.º 3
0
/* Explicit Euler Scheme */
void euler (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) {	
	t[0] = t0;
	y[0] = y0;
	struct Vector* tmp1;
	struct Vector* tmp2;
	for (int j=1; j<steps; j++) {
		t[j] = t0+j*h;
		tmp1 = new_Vector(DIM);
		tmp2 = new_Vector(DIM);
		f(t[j-1],y[j-1],tmp1);
		scale_Vector(h,tmp1,tmp2);
		add_Vectors(y[j-1],tmp2,y[j]);
		delete_Vector(tmp1);
		delete_Vector(tmp2);
	}
}
Ejemplo n.º 4
0
float * FonctionsMath::resol_ConjGrad(float ** A,float * b,int n)
{
    float * x,* r,* s,* p,* q,** tA,alpha,beta,normRSqr;

    x=new_Vector(n);
    tA=transp_Mat_Sqr(A,n);
    init_Vector_norm1(x,n,norm_Vector_2(b,n));
    s=minus_Vector(b,prod_MatVector_Sqr(A,x,n),n);
    r=prod_MatVector_Sqr(tA,s,n);
    p=affectValues_Vector(r,n);
    q=prod_MatVector_Sqr(A,p,n);

    do
    {
        normRSqr=dot_Prod(r,r,n);
        alpha=normRSqr/dot_Prod(q,q,n);
        x=plus_Vector(x,scalProd_Vector(alpha,p,n),n);
        s=minus_Vector(s,scalProd_Vector(alpha,q,n),n);
        delete [] r;
        r=prod_MatVector_Sqr(tA,s,n);
        beta=dot_Prod(r,r,n)/normRSqr;
        p=plus_Vector(r,scalProd_Vector(beta,p,n),n);
        q=prod_MatVector_Sqr(A,p,n);
    }
    while(norm_Vector_inf(s,n)/norm_Vector_2(b,n) > PRECISION);

    return x;
}
Ejemplo n.º 5
0
float * FonctionsMath::base_Vector(int i,int n)
{
    float *x;

    x=new_Vector(n);
    x[i]=1;
    return x;
}
Ejemplo n.º 6
0
/*scalarproduct induced by matrix*/
double scalarproductMatrix(struct Matrix* a, struct Vector* x, struct Vector* y, int size){
	struct Vector* help=new_Vector(size);
	multiply_Matrix_Vector(a,x,help);
	double value = scalarproductRn(help,y,size);
	delete_Vector(help);
	return value;


}
Ejemplo n.º 7
0
float * FonctionsMath::affectValues_Vector(float * b,int n)
{
    float * c;
    int i;

    c=new_Vector(n);
    for(i=0;i<n;i++)
        c[i]=b[i];
    return c;
}
Ejemplo n.º 8
0
Order_list* new_Order_list(Streader* sr)
{
    rassert(sr != NULL);

    if (Streader_is_error_set(sr))
        return NULL;

    // Create the base structure
    Order_list* ol = memory_alloc_item(Order_list);
    if (ol == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        return NULL;
    }

    ol->pat_insts = NULL;
    ol->index_map = NULL;

    // Create Pattern instance reference vector
    ol->pat_insts = new_Vector(sizeof(Pat_inst_ref));
    if (ol->pat_insts == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        del_Order_list(ol);
        return NULL;
    }

    // Create reverse index of ol->pat_insts
    ol->index_map = new_AAtree(
            (AAtree_item_cmp*)Pat_inst_ref_cmp, (AAtree_item_destroy*)memory_free);
    if (ol->index_map == NULL)
    {
        Streader_set_memory_error(
                sr, "Could not allocate memory for order list");
        del_Order_list(ol);
        return NULL;
    }

    // List is empty by default
    if (!Streader_has_data(sr))
        return ol;

    // Read the list of Pattern instance references
    if (!Streader_read_list(sr, read_piref, ol))
    {
        del_Order_list(ol);
        return NULL;
    }

    return ol;
}
Ejemplo n.º 9
0
float * FonctionsMath::plus_Vector(float * x,float * y,int n)
{
    int i;
    float * z;

    z=new_Vector(n);

    for(i=0;i<n;i++)
        z[i]=x[i]+y[i];

    return z;
}
Ejemplo n.º 10
0
float * FonctionsMath::extr_Vect_Mat(float ** M,int n,int j)
{
    int i;
    float * x;

    x=new_Vector(n);

    for(i=0;i<n;i++)
        x[i]=M[i][j];

    return x;
}
Ejemplo n.º 11
0
float * FonctionsMath::scalProd_Vector(float a,float * A,int n)
{
    int i;
    float * C;

    C=new_Vector(n);

    for(i=0;i<n;i++)
        C[i]=a*A[i];

    return C;
}
Ejemplo n.º 12
0
/* Adaptive Runge-Kutta Scheme of order 3, uses tol for stepsize-control */
void adaptive_rk3 (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double tol, double* t, struct Vector** y, int steps) {
	t[0] = t0;
	y[0] = y0;
	double h;
	double norm;
	struct Vector* k1;
	struct Vector* k2;
	struct Vector* k3;
	struct Vector* tmp1;
	struct Vector* tmp2;
	struct Vector* tmp3;
	for (int j=1; j<steps; j++) {
		bool adapt = true;
		h = 1;
		k1 = new_Vector(DIM);
		k2 = new_Vector(DIM);
		k3 = new_Vector(DIM);
		tmp1 = new_Vector(DIM);
		tmp2 = new_Vector(DIM);
		tmp3 = new_Vector(DIM);
		while(adapt) {
			f(t[j-1],y[j-1],k1);
			scale_Vector(h,k1,tmp1);
			add_Vectors(y[j-1],tmp1,tmp2);
			f(t[j-1]+h,tmp2,k2);
			add_Vectors(k1,k2,tmp1);
			scale_Vector(h/4,tmp1,tmp2);
			add_Vectors(y[j-1],tmp2,tmp1);
			f(t[j-1]+h/2,tmp1,k3);
			scale_Vector(2,k3,tmp1);
			scale_Vector(-1,k2,tmp2);
			add_Vectors(tmp1,tmp2,tmp3);
			scale_Vector(-1,k1,tmp1);
			add_Vectors(tmp1,tmp3,tmp2);
			norm = vectornorm(tmp2);
			if (h/3*norm < tol) {
				adapt = false;
				add_Vectors(k1,k2,tmp1);
				scale_Vector(4,k3,tmp2);
				add_Vectors(tmp1,tmp2,tmp3);
				scale_Vector(h/6,tmp3,tmp1);
				add_Vectors(y[j-1],tmp1,y[j]);
			} else {
				if (3/2*tol/norm>0) {
					h = 3/2*tol/norm;
				} else {
					h = h/2;
				}
			}
		}
		t[j] = t[j-1]+h;

		delete_Vector(tmp1);
		delete_Vector(tmp2);
		delete_Vector(tmp3);
		delete_Vector(k1);
		delete_Vector(k2);
		delete_Vector(k3);
	}
}
Ejemplo n.º 13
0
float * FonctionsMath::prod_MatVector_Sqr(float ** A,float *b, int n)
{
    int i,j;
    float * x;

    x=new_Vector(n);

    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            x[i]=x[i]+A[i][j]*b[j];

    return x;
}
Ejemplo n.º 14
0
double normAxb_squared(struct Matrix* a, struct Vector* b, struct Vector* x, int size){
	int i=0;
	double scalarprod=0;
	struct Vector* help= new_Vector(size);
	multiply_Matrix_Vector(a,x, help);
	
	for(i=0;i<size;i++){
		help->values[i]=help->values[i]-b->values[i];	
		help->values[i]*=help->values[i];
		scalarprod+=help->values[i];
	}	
	delete_Vector(help);
	return scalarprod;

}
Ejemplo n.º 15
0
/*   Gradient Descent Method, assuming gamma is given?*/
void gradientDescent(struct Matrix* a, struct Vector* b, struct Vector* initialVal, struct Vector** x, double gamma, int size, int steps){

	copy_Vector(initialVal,x[0]);
	int i=0;
	struct Vector* gradient=new_Vector(size);
		
	for(i=1;i<steps;i++){
		getGradient(a,b,x[i-1],gradient,size);
		scale_Vector(-gamma,gradient,gradient);
		
		add_Vectors(x[i-1],gradient,x[i]);
	}
	delete_Vector(gradient);


}
Ejemplo n.º 16
0
float * FonctionsMath::resol_Up(float ** A,float *b,int n)
{
    int i,j;
    float *x,s;

    x=new_Vector(n);

    x[n-1]=b[n-1]/A[n-1][n-1];

    for(i=(n-2);i >= 0;i--)
    {
        s=0;
        for(j=(i+1);j<n;j++)
            s=s+A[i][j]*x[j];
        x[i]=(b[i]-s)/A[i][i];
    }
    return x;
}
Ejemplo n.º 17
0
float * FonctionsMath::sign_Vector(float * x,int n)
{
    int i;
    float * s;

    s=new_Vector(n);

    for(i=0;i<n;i++)
    {
        if(x[i] > 0)
            s[i]=1;
        else if(x[i]==0)
            s[i]=0;
        else
            s[i]=-1;
    }

    return s;
}
Ejemplo n.º 18
0
Visual* link_Scene( Scene*      sc, 
                    pointer     tag, 
                    uint32      mask,
                    Drawable*   dr, 
                    Shader_Arg* argv ) {

	struct Bucket* bucket = lookup_Map( sc->buckets, 
	                                    sizeof( tag ),
	                                    &tag );
	if( NULL == bucket ) {

		// Create a new bucket
		bucket = ralloc( sc->R, sizeof(struct Bucket) );
		
		bucket->visuals  = new_Vector( ZONE_heap, sizeof(Visual), bucketSize );
		bucket->freelist = NULL;

		put_Map( sc->buckets, sizeof(tag), &tag, bucket );

	}

	// Stick it in the bucket
	Visual* vis = NULL;
	if( bucket->freelist ) {

		vis              = bucket->freelist;
		bucket->freelist = vis->next;

	} else 
		vis = (Visual*)push_back_Vector( bucket->visuals );

	vis->tag  = tag;
	vis->mask = mask;
	vis->draw = dr;
	vis->argv = argv;
	vis->next = NULL;

	return vis;

}
Ejemplo n.º 19
0
/* Symplectic Euler Scheme. Only to be used for Hamiltonian systems. Requires even dimension DIM */
void symplectic_euler (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) {
	if (DIM%2 != 0) printf("Warning: Tried to use symplectic Euler method for vector of odd dimension");
	else {	
		t[0] = t0;
		y[0] = y0;
		struct Vector* tmp;
		for (int j=1; j<steps; j++) {
			t[j] = t0+j*h;
			tmp = new_Vector(DIM);
			f(t[j-1],y[j-1],tmp);
			//print_Vector(tmp);
			copy_Vector(y[j-1],y[j]);
			for(int i=DIM/2; i<DIM; i++) {
				y[j]->values[i] = y[j-1]->values[i] + h*tmp->values[i];
			}
			f(t[j-1],y[j],tmp);
			for(int i=0; i<DIM/2; i++) {
				y[j]->values[i] = y[j-1]->values[i] + h*tmp->values[i];
			}
			delete_Vector(tmp);
		}
	}
}
Ejemplo n.º 20
0
float * FonctionsMath::resol_ConjGrad_SymPosDef(float ** A,float * b,int n)
{
    float * x,* r,* p,* Ap,alpha,beta,normRSqr;

    x=new_Vector(n);
    init_Vector_norm1(x,n,norm_Vector_2(b,n));
    r=minus_Vector(b,prod_MatVector_Sqr(A,x,n),n);
    p=affectValues_Vector(r,n);

    do
    {
        normRSqr=dot_Prod(r,r,n);
        Ap=prod_MatVector_Sqr(A,p,n);
        alpha=normRSqr/dot_Prod(p,Ap,n);
        x=plus_Vector(x,scalProd_Vector(alpha,p,n),n);
        r=minus_Vector(r,scalProd_Vector(alpha,Ap,n),n);
        beta=dot_Prod(r,r,n)/normRSqr;
        p=plus_Vector(r,scalProd_Vector(beta,p,n),n);
    }
    while(norm_Vector_inf(r,n)/norm_Vector_2(b,n) > PRECISION);

    return x;
}
Ejemplo n.º 21
0
/* Runge-Kutta Scheme of order 4 */
void rk4 (void (*f)(double,struct Vector*,struct Vector*), double t0, struct Vector* y0, double h, double* t, struct Vector** y, int steps) {
	t[0] = t0;
	y[0] = y0;
	struct Vector* k1;
	struct Vector* k2;
	struct Vector* k3;
	struct Vector* k4;
	struct Vector* tmp1;
	struct Vector* tmp2;
	for (int j=1; j<steps; j++) {
		k1 = new_Vector(DIM);
		k2 = new_Vector(DIM);
		k3 = new_Vector(DIM);
		k4 = new_Vector(DIM);
		tmp1 = new_Vector(DIM);
		tmp2 = new_Vector(DIM);

		f(t[j-1],y[j-1],k1);
		scale_Vector(h/2,k1,tmp1);
		add_Vectors(y[j-1],tmp1,tmp2);
		f(t[j-1]+h/2,tmp2,k2);
		scale_Vector(h/2,k2,tmp1);
		add_Vectors(y[j-1],tmp1,tmp2);
		f(t[j-1]+h/2,tmp2,k3);
		scale_Vector(h,k3,tmp1);
		add_Vectors(y[j-1],tmp1,tmp2);
		f(t[j-1]+h,tmp2,k4);
		
		add_Vectors(k2,k3,tmp1);
		scale_Vector(2,tmp1,tmp2);
		add_Vectors(k1,tmp2,tmp1);
		add_Vectors(tmp1,k4,tmp2);
		scale_Vector(h/6,tmp2,tmp1);
		add_Vectors(y[j-1],tmp1,y[j]);
		t[j] = t[j-1]+h;

		delete_Vector(tmp1);
		delete_Vector(tmp2);
		delete_Vector(k1);
		delete_Vector(k2);
		delete_Vector(k3);
	}
}
Ejemplo n.º 22
0
//Run Program
int main (int argc, char** argv) {
	
	//Read input argument
	int in = 0;
	double h = 0.5;
	double tol = 0.1;
	if (argc > 1) in = atoi(argv[1]);	
	if (argc > 2) h = atof(argv[2]);	
	if (argc > 3) tol = atof(argv[3]);	
	printf("Input arguments: %i %f %f \n", in, h, tol);
	
	//Check if SDL Initialization is successful
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		return -1;
	}

	//Create Window
	SDL_Window *win = SDL_CreateWindow("Adaptive Step Sizes",50,50,640,480,SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
	if (!win) {
		fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
	}
	
	//Initialize OpenGL
	SDL_GLContext context = SDL_GL_CreateContext(win);
	if (!context) {
		fprintf(stderr, "Could not create OpenGL context: %s\n", SDL_GetError());
	}
	glViewport(0,0,(GLsizei)640,(GLsizei)480);
	glClearColor(1.0f,1.0f,1.0f,1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
	SDL_GL_SwapWindow(win);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glDisable(GL_DEPTH_TEST);

	//Plot Functions
	double xpos = -0.9;
	double ypos = -0.9;
	double width = 1.8;
	double height = 1.8;
	glColor4f(0.0f,0.0f,0.0f,1.0f);
	glBegin(GL_LINE_LOOP);
		glVertex3f(xpos,ypos,0.0f);
		glVertex3f(xpos+width,ypos,0.0f);
		glVertex3f(xpos+width,ypos+height,0.0f);
		glVertex3f(xpos,ypos+height,0.0f);
	glEnd();
	glBegin(GL_LINES);
		for (int j=1; j<10; j++) {
		glVertex3f(xpos+j*width/10,ypos,0.0f);
		glVertex3f(xpos+j*width/10,ypos+0.02f,0.0f);
		glVertex3f(xpos+j*width/10,ypos+height,0.0f);
		glVertex3f(xpos+j*width/10,ypos+height-0.02f,0.0f);
		glVertex3f(xpos,ypos+j*height/10,0.0f);
		glVertex3f(xpos+0.02f,ypos+j*height/10,0.0f);
		glVertex3f(xpos+width,ypos+j*height/10,0.0f);
		glVertex3f(xpos+width-0.02f,ypos+j*height/10,0.0f);
		}
	glEnd();
	double xmin,xmax,ymin,ymax,t0;
	struct Vector* y0;
	int steps;
	void (*f)(double,struct Vector*,struct Vector*);
	switch(in) {
		case 0:
			xmin = 0.0;
			xmax = 20;
			ymin = 0.0;
			ymax = 1.2;
			t0 = 0;
			y0 = new_Vector(DIM);
			y0->values[0] = 1;
			steps = (int)floor((xmax-xmin)/h+1);
			f = f1;
		break;

		case 1:
			xmin = 0.0;
			xmax = 0.999;
			ymin = 0;
			ymax = 15;
			t0 = 0;
			y0 = new_Vector(DIM);
			y0->values[0] = 0;
			steps = (int)floor((xmax-xmin)/h+1);
			f = f2;
		break;
		
		default:
			printf("Invalid argument: %i\n",in);
		break;	
	}

	glColor4f(0.0f,0.0f,0.0f,1.0f);

	double* t = malloc(sizeof(double)*steps);
	double* values = malloc(sizeof(double)*steps);
	struct Vector** y = malloc(sizeof(struct Vector*)*steps);	
	for (int j=1; j < steps; j++) {
		y[j] = new_Vector(DIM);
	}

	/*	
	euler (f, t0, y0, h, t, y, steps);
	glColor4f(1.0f,0.0f,0.0f,1.0f);
	for (int j=0; j < steps; j++) {
		values[j] = y[j]->values[0];
	}
	plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height);
	*/
	
	/*
	modEuler (f, t0, y0, h, t, y, steps);
	glColor4f(0.0f,0.0f,1.0f,1.0f);
	for (int j=0; j < steps; j++) {
		values[j] = y[j]->values[0];
	}
	plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height);
	*/
			
	heun (f, t0, y0, h, t, y, steps);
	glColor4f(0.0f,1.0f,0.0f,1.0f);
	for (int j=0; j < steps; j++) {
		values[j] = y[j]->values[0];
	}
	plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height);
	
	adaptive_rk3 (f, t0, y0, tol, t, y, steps);
	glColor4f(1.0f,0.0f,0.0f,1.0f);
	for (int j=0; j < steps; j++) {
		values[j] = y[j]->values[0];
	}
	plotArray(t, values, steps, xmin, xmax, ymin, ymax, xpos, ypos, width, height);
	
	//Clean Up Memory					
	free(t);
	for (int j=1; j < steps; j++) {
		delete_Vector(y[j]);
	}
	free(y);
	free(values);
	delete_Vector(y0);

	SDL_GL_SwapWindow(win);

	//Save PLot as BMP
	/*
	unsigned char* pixels = malloc(640*480*4*sizeof(unsigned char));
	glReadPixels(0,0,640,480,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
	SDL_Surface* sur = SDL_CreateRGBSurfaceFrom(pixels,640,480,8*4,640*4,0x000000FF,0x0000FF00,0x00FF0000,0);
	SDL_SaveBMP(sur,"test.bmp");
	SDL_FreeSurface(sur);
	free(pixels);
	*/
	

	
	//Wait for Window Close Event
	SDL_Event event;
	while (SDL_WaitEvent(&event) >= 0) {
		if (event.type == SDL_QUIT) {
			SDL_GL_DeleteContext(context);
			SDL_DestroyWindow(win);
			SDL_Quit();
			break;
		}
	}
	return 0;
}
Ejemplo n.º 23
0
/* Run Program */
int main (int argc, char** argv) {
	
	//Read input argument
	int steps=1000;
	double h = 0.1;
	if (argc == 1){
		printf("USAGE: NumberOfSteps StepSize/Tolerance\nExited.\n");
		return 0;
	} 
	if (argc > 1) steps = atoi(argv[1]);	
	if (argc > 2) h = atof(argv[2]);	
	printf("Input arguments: %i %f \n", steps, h);
	
	//Check if SDL Initialization is successful
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		return -1;
	}

	//Create Window
	SDL_Window *win = SDL_CreateWindow("Exercise 5, Lorenz Equations",50,50,800,600,SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
	if (!win) {
		fprintf(stderr, "Could not create window: %s\n", SDL_GetError());
	}
	
	//Initialize OpenGL
	SDL_GLContext context = SDL_GL_CreateContext(win);
	if (!context) {
		fprintf(stderr, "Could not create OpenGL context: %s\n", SDL_GetError());
	}
	glViewport(0,0,(GLsizei)800,(GLsizei)600);
	glClearColor(1.0f,1.0f,1.0f,1.0f);
	glClear(GL_COLOR_BUFFER_BIT);
	SDL_GL_SwapWindow(win);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(GL_DEPTH_TEST);
	glFrustum(-100,100,-100,100,0.01,100);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1,1);
	glEnable(GL_LIGHTING);
	glShadeModel(GL_SMOOTH);
	GLfloat lightcol[] = {0.9,0.9,0.9,1.0};
	GLfloat lightamb[] = {0.5,0.5,0.5,1.0};
	GLfloat lightpos[] = {20.0,20.0,30.0,1.0};
	glLightfv(GL_LIGHT0,GL_AMBIENT,lightamb);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,lightcol);
	glEnable(GL_LIGHT0);
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_RESCALE_NORMAL);
	

	//Init all vectors
	double t0 = 0;
	double* t = malloc(sizeof(double)*steps);
	double* xValues = malloc(sizeof(double)*steps);
	double* yValues = malloc(sizeof(double)*steps);
	double* zValues = malloc(sizeof(double)*steps);
	double* xValues_it = malloc(sizeof(double)*steps);
	double* yValues_it = malloc(sizeof(double)*steps);
	double* zValues_it = malloc(sizeof(double)*steps);
	double xmin = -4;
	double xmax = 4;
	double ymin = -4;
	double ymax = 4;
	double xsteps = 21;
	double ysteps = 21;
	struct Matrix* X = new_Matrix(xsteps,ysteps);
	struct Matrix* Y = new_Matrix(xsteps,ysteps);
	struct Matrix* Z = new_Matrix(xsteps,ysteps);	
	meshgrid(xmin,xmax,ymin,ymax,xsteps,ysteps,X,Y);
	paraboloid(X,Y,Z);
	struct Vector* vec0 = new_Vector(DIM);
	vec0->values[0] = 1;
	vec0->values[1] = 1;
	vec0->values[2] = 2;
	vec0->values[3] = 1-0.25;
	vec0->values[4] = -1-0.25;
	vec0->values[5] = -1;
	struct Vector** vec = malloc(sizeof(struct Vector*)*steps);	
	for (int j=1; j < steps; j++) {
		vec[j] = new_Vector(DIM);
	}
	
	//find geodesic iteratively
	struct Vector** vec_it = malloc(sizeof(struct Vector*)*steps);
	vec_it[0] = vec0;	
	for (int j=1; j < steps; j++) {
		vec_it[j] = new_Vector(DIM);
		geodesic_step(vec_it[j-1],h,vec_it[j]);		
	}
	for (int j=0; j < steps; j++) {
		xValues_it[j] = vec_it[j]->values[0];
		yValues_it[j] = vec_it[j]->values[1];
		zValues_it[j] = vec_it[j]->values[2];
	}

	//solve ODE
	//adaptive_rk3(geodesic_rhs,t0,vec0,h,t,vec,steps);
	euler(geodesic_rhs,t0,vec0,h,t,vec,steps);

	for (int j=0; j < steps; j++) {
		xValues[j] = vec[j]->values[0];
		yValues[j] = vec[j]->values[1];
		zValues[j] = vec[j]->values[2];
	}
	
	SDL_GL_SwapWindow(win);

	/* Look Around Loop	*/
	bool loop = true;
	bool wireframe = false;
	bool overlay = true;
	double xMouse = 0;
	double yMouse = 0;
	double xpos = 0;
	double ypos = 0;
	double zpos = 0;
	bool mouseDown = false;
	double mouseZoom = 0.1;
	SDL_Event event;
	while (loop) {
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				loop = false;
			}
			if (event.type== SDL_MOUSEBUTTONDOWN) {
				mouseDown = true;
			}
			if (event.type == SDL_MOUSEBUTTONUP) {
				mouseDown = false;
			}
			if (event.type == SDL_MOUSEMOTION) {
				if(mouseDown){
					xMouse += 0.5*event.motion.xrel;
					yMouse += 0.5*event.motion.yrel;
				}
			}
			if (event.type== SDL_KEYDOWN) {
				if(event.key.keysym.scancode == SDL_SCANCODE_W)
					ypos += 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_S)
					ypos -= 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_A)
					xpos -= 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_D)
					xpos += 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_Q)
					zpos += 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_E)
					zpos -= 0.1;
				if(event.key.keysym.scancode == SDL_SCANCODE_TAB)
					wireframe = !wireframe;
				if(event.key.keysym.scancode == SDL_SCANCODE_O)
					overlay = !overlay;
			}
			if (event.type== SDL_MOUSEWHEEL) {
				if (event.wheel.y < 0)
					mouseZoom /= 1.2;
				else
					mouseZoom *= 1.2;
			}
		}
		
		//Draw current frame buffer
		SDL_GL_SwapWindow(win);	

		//Prepare next frame buffer
		glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
        glClear( GL_COLOR_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);
		glClear(GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
		
		glTranslated(xpos, ypos, zpos);
		glScaled(mouseZoom,mouseZoom,mouseZoom);
		glRotated(-90, 1.0, 0.0, 0.0);
		glRotated(-yMouse, 1.0, 0.0, 0.0);
		glRotated(-xMouse, 0.0, 0.0, 1.0);


		plotAxis3D(-10,10,-10,10,-5,30,0,0,0);
		glColor4f(0.2,0.4,0.5,1.0);
		glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
		if (wireframe) {
			glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
			surf(X,Y,Z);
		} else {
			glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
			surf(X,Y,Z);
			if (overlay) {
				glColor4f(0.2,0.2,0.2,1.0);
				glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
				surf(X,Y,Z);
			}
		}
		
		glColor4f(0.85,0.85,0.10,1.0);
		plotArray3D(xValues,yValues,zValues,steps);
		glColor4f(0.9,0.2,0.4,1.0);
		plotArray3D(xValues_it,yValues_it,zValues_it,steps);
		glColor4f(0.0,0.0,0.0,1.0);
	}


	//Clean Up Memory					
	free(t);
	for (int j=1; j < steps; j++) {
		delete_Vector(vec[j]);
	}
	free(vec);
	free(xValues);
	free(yValues);
	free(zValues);
	delete_Vector(vec0);
	delete_Matrix(X);
	delete_Matrix(Y);
	delete_Matrix(Z);

	SDL_GL_DeleteContext(context);
	SDL_DestroyWindow(win);
	SDL_Quit();
	return 0;
}