Beispiel #1
0
double accuracy(matrix_list_t* theta, matrix_t* X, matrix_t* y)
{
	assert(theta->num == 2);
	matrix_t* theta_transpose, *temp, *temp2;

	theta_transpose = matrix_transpose(theta->matrix_list[0]);
	temp = matrix_prepend_col(X, 1.0);
	temp2 = matrix_multiply(temp, theta_transpose);
	matrix_t* h1 = matrix_sigmoid(temp2);

	free_matrix(theta_transpose);
	free_matrix(temp);
	free_matrix(temp2);

	theta_transpose = matrix_transpose(theta->matrix_list[1]);
	temp = matrix_prepend_col(h1, 1.0);
	temp2 = matrix_multiply(temp, theta_transpose);
	matrix_t* h2 = matrix_sigmoid(temp2);

	free_matrix(theta_transpose);
	free_matrix(temp);
	free_matrix(temp2);

	assert(h2->rows == 5000 && h2->cols == 10);
	matrix_t* p = matrix_constructor(1, 5000);
	int i, j;

	for(i = 0; i<h2->rows; i++)
	{
		double max = 0.0;
		unsigned char first = 1;
		for(j=0; j<h2->cols; j++)
		{
			if(matrix_get(h2, i, j) > max || first == 1)
			{
				vector_set(p, i, j);
				max = matrix_get(h2, i, j);
				first = 0;
			}
		}
	}
	double count = 0;
	for(i=0; i<5000; i++)
	{
		if(vector_get(y, i) == vector_get(p, i))
			count = count + 1;
	}

	free_matrix(p);
	free_matrix(h1);
	free_matrix(h2);
	
	return count/5000;
}
Beispiel #2
0
matrix_list_t* random_init_weights(unsigned int num_layers, unsigned int layer_sizes[])
{
	srand(time(NULL));

	matrix_list_t* theta = matrix_list_constructor(num_layers-1);
	unsigned int i, j, k;
	for(i = 0; i<num_layers-1; i++)
	{
		theta->matrix_list[i] = matrix_constructor(layer_sizes[i+1], layer_sizes[i]+1);
		for(j=0; j<theta->matrix_list[i]->rows; j++)
		{
			for(k = 0; k<theta->matrix_list[i]->cols; k++)
			{
				double random_double = ((double)(rand() % 1000)) / (double)1000;
				matrix_set(theta->matrix_list[i], j, k, random_double * 2 * .12 - .12);
			}
		}
	}
	return theta;
}
Beispiel #3
0
double NN_cost_function(int num_threads, matrix_t** gradient, matrix_t* rolled_theta, unsigned int layer_sizes[], unsigned int num_layers,
		unsigned int num_labels, matrix_t* X, matrix_t* y, double lamda)
{
	unsigned int theta_sizes[][2] = {{25, 401}, {10, 26}};

	matrix_list_t* theta = unroll_matrix_list(rolled_theta, num_layers-1, theta_sizes);

	unsigned int m = X->rows;
	//unsigned int n = X->cols;

	matrix_list_t* theta_gradient_total = matrix_list_constructor(theta->num);
	unsigned int i, j;
	for(i=0; i<theta_gradient_total->num; i++)
	{
		theta_gradient_total->matrix_list[i] = matrix_constructor(theta->matrix_list[i]->rows, theta->matrix_list[i]->cols);
	}
	
	omp_set_num_threads(num_threads);
	int nthreads, tid;
	#pragma omp parallel private(nthreads, tid)
	{
		int indexes[2];
		tid = omp_get_thread_num();
		nthreads = omp_get_num_threads();
		get_indexes(m, nthreads, tid, indexes);
		unsigned int i, j;

		matrix_t* temp;
		matrix_t* temp2;
		matrix_t* temp3;

		matrix_list_t* theta_gradient = matrix_list_constructor(theta->num);
		for(i=0; i<theta_gradient->num; i++)
		{
			theta_gradient->matrix_list[i] = matrix_constructor(theta->matrix_list[i]->rows, theta->matrix_list[i]->cols);
		}

		for(i=indexes[0]; i<indexes[1]; i++)
		{
			matrix_list_t* A = matrix_list_constructor(num_layers);
			matrix_list_t* Z = matrix_list_constructor(num_layers-1);
			matrix_list_t* delta = matrix_list_constructor(num_layers-1);

			A->matrix_list[0] = row_to_vector(X, i);
			temp = matrix_prepend_col(A->matrix_list[0], 1.0);
			free_matrix(A->matrix_list[0]);

			A->matrix_list[0] = matrix_transpose(temp);
			free_matrix(temp);

			for(j=0; j<num_layers-1; j++)
			{
				Z->matrix_list[j] = matrix_multiply(theta->matrix_list[j], A->matrix_list[j]);

				temp = matrix_sigmoid(Z->matrix_list[j]);
				A->matrix_list[j+1] = matrix_prepend_row(temp, 1.0);
				free_matrix(temp);
			}

			temp = matrix_remove_row(A->matrix_list[num_layers-1]);
			free_matrix(A->matrix_list[num_layers-1]);
			A->matrix_list[num_layers-1] = temp;

			matrix_t* result_matrix = matrix_constructor(1, num_labels);
			for(j = 0; j < num_labels; j++)
			{
				if(vector_get(y, i) == j)
				{
					vector_set(result_matrix, j, 1.0);
				}
			}
			temp = matrix_transpose(result_matrix);
			free_matrix(result_matrix);
			result_matrix= temp;

			delta->matrix_list[1] = matrix_subtract(A->matrix_list[num_layers-1], result_matrix);
			free_matrix(result_matrix);

			matrix_t* theta_transpose = matrix_transpose(theta->matrix_list[1]);
			temp = matrix_multiply(theta_transpose, delta->matrix_list[1]);

			matrix_t* sig_gradient = matrix_sigmoid_gradient(Z->matrix_list[0]);
			temp2 = matrix_prepend_row(sig_gradient, 1.0);

			temp3 = matrix_cell_multiply(temp, temp2);
			delta->matrix_list[0] = matrix_remove_row(temp3);

			free_matrix(temp);
			free_matrix(temp2);
			free_matrix(temp3);
			free_matrix(sig_gradient);
			free_matrix(theta_transpose);

			for(j=0; j<num_layers-1; j++)
			{
				matrix_t* A_transpose = matrix_transpose(A->matrix_list[j]);
				temp = matrix_multiply(delta->matrix_list[j], A_transpose);
				temp2 = matrix_add(theta_gradient->matrix_list[j], temp);
				free_matrix(theta_gradient->matrix_list[j]);
				theta_gradient->matrix_list[j] = temp2;


				free_matrix(A_transpose);
				free_matrix(temp);
			}
			free_matrix_list(A);
			free_matrix_list(Z);
			free_matrix_list(delta);
		}
		#pragma omp critical
		{
			matrix_list_t* temp_list;
			temp_list = matrix_list_add(theta_gradient_total, theta_gradient);

			free_matrix_list(theta_gradient_total);
			free_matrix_list(theta_gradient);
			theta_gradient_total = temp_list;
		}
	}

	for(i=0; i<num_layers-1; i++)
	{
		matrix_t* temp;
		matrix_t* temp2;
		matrix_t* temp3;

		temp = matrix_scalar_multiply(theta_gradient_total->matrix_list[i], 1.0/m);
		temp2 = copy_matrix(theta->matrix_list[i]);
		for(j=0; j<theta->matrix_list[i]->rows; j++)
		{
			matrix_set(temp2, j, 0, 0.0);
		}
		free_matrix(theta_gradient_total->matrix_list[i]);
		temp3 = matrix_scalar_multiply(temp2, lamda/m);
		theta_gradient_total->matrix_list[i] = matrix_add(temp, temp3);
		free_matrix(temp);
		free_matrix(temp2);
		free_matrix(temp3);
	}

	*gradient = roll_matrix_list(theta_gradient_total);

	free_matrix_list(theta);
	free_matrix_list(theta_gradient_total);

	return 0.0;
}
Beispiel #4
0
int main()
{
    char filename[255] = {}; // filename of the test image

    // We need to load the data structures that were created by the
    // CreateDatabase step
    if (MatrixRead_Binary() != 0) { //Load structures
        printf("Error!!!\n");
        exit(-1);
    }
    printf("Database Files Loaded From Disk...\n");
    PPMImage *TestImage; // pointer to the structure of our loaded test image

    int pass = 0, fail = 0, iterations; // Let's keep a few stats
    int i, j, k, x; // loop variables

    for (iterations = 1; iterations <= 30; iterations++) {
        /* 994 is the number of test images that we have sequentially numbered */
        // concat our filename together
        sprintf(filename, "../LDAIMAGES/Test2/%d.ppm", iterations);
        TestImage = ppm_image_constructor(filename);
        printf("Test Image Loaded From Disk and converted to grayscale...\n");

        // First let's allocate our difference array
        Difference = matrix_constructor(m_database.rows, 1);
        //Difference.rows = m_database.rows;
        //Difference.cols = 1;
        //Difference.data = (double**) malloc(Difference.rows * sizeof (double*));
        //for (i = 0; i < Difference.rows; i++) {
        //    Difference.data[i] = (double*) malloc(Difference.cols
        //            * sizeof (double));
        //}

        for (i = 0; i < m_database.rows; i++) {
            Difference.data[i][0] = TestImage->pixels[i].r
                    - m_database.data[i][0]; // mean database is a 1d vector
            // (using red channel for gray)
        }
        // Now let's multiply in the last matrix to calculate our ProjectedTestImage
        //v_fisherT_x_v_pcaT * Difference
        // Why is this commented out?

        ProjectedTestImage = matrix_constructor(rows, cols);
//        ProjectedTestImage.rows = v_fisherT_x_v_pcaT.rows;
//        ProjectedTestImage.cols = Difference.cols;
//        ProjectedTestImage.data = (double**) malloc(ProjectedTestImage.rows
//                * sizeof (double*));
        // allocate memory for our new array
//        for (i = 0; i < ProjectedTestImage.rows; i++) {
//            ProjectedTestImage.data[i] = (double*) malloc(ProjectedTestImage.cols
//                    * sizeof (double));
//            if (ProjectedTestImage.data[i] == 0) {
//                printf("Dynamic Allocation Failed!!!\n");
//                return -1;
//            }
//        }

        // clbas_dgemm();
        for (i = 0; i < v_fisherT_x_v_pcaT.rows; i++) { // perform matrix mult.
            // computation
            for (j = 0; j < Difference.cols; j++) { // This loop executes once
                ProjectedTestImage.data[i][j] = 0.0;
                for (k = 0; k < v_fisherT_x_v_pcaT.cols; k++) {
                    ProjectedTestImage.data[i][j] +=
                            v_fisherT_x_v_pcaT.data[i][k] * Difference.data[k][j];
                }
            }
        }

        unsigned long int Train_Number = 0;
        Train_Number = ProjectedImages_Fisher.cols; // Satisfies line 27
        double * q = 0; // Holds a column vector
        q = (double *) malloc(ProjectedImages_Fisher.rows * sizeof (double));

        double * Euc_dist = (double *)
                malloc(sizeof (double) * ProjectedImages_Fisher.cols);
        double temp = 0;

        for (i = 0; i < Train_Number; i++) { // line 44 Recognition.m
            for (j = 0; j < ProjectedImages_Fisher.rows; j++) { // create q
                q[j] = ProjectedImages_Fisher.data[j][i];
            } //q has been populated

            // At this point, ProjectedTestImage is 99x1 and q is 99x1
                    // (Based on testing database)
            for (x = 0; x < ProjectedImages_Fisher.rows; x++) {
                temp += ((ProjectedTestImage.data[x][0] - q[x]) *
                        (ProjectedTestImage.data[x][0] - q[x])); //line 46
            }
            Euc_dist[i] = temp;
            temp = 0; //reset our running count
        }
        // at this point, Euc_dist should be populated

        // we need to find the min euc_dist and its index
        //int Euc_dist_len = sizeof(*Euc_dist) / sizeof(double);
        int Euc_dist_len = ProjectedImages_Fisher.cols; // the length of euc_dist
        double min = Euc_dist[0];

        int Recognized_index = 0;
        for (i = 0; i < Euc_dist_len; i++) {
            if (Euc_dist[i] < min) { // reassign min
                min = Euc_dist[i];
                Recognized_index = i;
            }
        }
        int filename_index = Recognized_index + 1; // because our files are
        // named starting at 1 and not 0. Arrays start at 0 in C

        printf("Test %d : %d.ppm == %d.ppm\n", iterations, iterations,
                filename_index);
        printf("-----------------------------------\n");

        ////////////// for statistic tracking
        if (iterations == ((Recognized_index - 1) / 4 + 1)) {
            pass++;
        } else {
            fail++;
        }
        //////////////
        ppm_image_destructor(TestImage, 0); // Free the loaded image
        // Need to free the memory that was allocated...

        // free Difference matrix
        matrix_destructor(Difference);
//        for (i = 0; i < Difference.rows; i++) {
//            free(Difference.data[i]);
//        }
//        free(Difference.data);

        // Free ProjectedTestImage matrix...
        matrix_destructor(ProjectedTestImage);
//        for (i = 0; i < ProjectedTestImage.rows; i++) {
//            free(ProjectedTestImage.data[i]);
//        }
//        free(ProjectedTestImage.data);

        // Free q vector
        free(q); // wha? why exactly did i use malloc?

        // Free Euc_dist
        free(Euc_dist); // huh?
        ///////////Allocated Memory Freed//////////////////////
    }
    printf("%d Correct %d Wrong\n", pass, fail);
    return 0;
}
Beispiel #5
0
/*MatrixRead_Binary() returns 0 on error and 1 on success*/
int MatrixRead_Binary() //Reads in all required matrices
{
    int rows, cols;
    int i, j;
    FILE *fin = 0;
    /**********************Read In The m.mat*************************/
    fin = fopen("m.mat", "rb");
    if (fin == NULL) {
        printf("Unable to Open m.mat!!!\n");
        return (0);
    }
    fread(&rows, sizeof (int), 1, fin);
    fread(&cols, sizeof (int), 1, fin);
    printf("m.mat [%d %d]\n", rows, cols);
    m_database = matrix_constructor(rows, cols);
    //m_database.data = (double**) malloc(rows * sizeof (double*));
    //for (i = 0; i < rows; i++) {
    //    m_database.data[i] = (double*) malloc(cols * sizeof (double));
    //}
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            fread(&(m_database.data[i][j]), sizeof (double), 1, fin);
            /*printf("data verify (%lf)\n", m_database.data[i][j]);
            while(1) {
                if(getchar() == 'n') break;
            }*/
        }
    }
    printf("read m.mat!!!\n");
    //m_database.rows = rows;
    //m_database.cols = cols;
    fclose(fin);
    fin = 0;
    /**************************************************************/

    /**************Read In The Inverse_V_Fisher.mat****************/
    fin = fopen("Inverse_V_Fisher.mat", "rb");
    if (fin == NULL) {
        printf("Unable to Open Inverse_V_Fisher.mat!!!\n");
        return (0);
    }
    fread(&rows, sizeof (int), 1, fin);
    fread(&cols, sizeof (int), 1, fin);
    printf("Inverse_V_Fisher.mat [%d %d]\n", rows, cols);
    Inverse_V_Fisher = matrix_constructor(rows, cols);
    //Inverse_V_Fisher.data = (double**) malloc(rows * sizeof (double*));
    //for (i = 0; i < rows; i++) {
    //    Inverse_V_Fisher.data[i] = (double*) malloc(cols * sizeof (double));
    //}
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            fread(&(Inverse_V_Fisher.data[i][j]), sizeof (double), 1, fin);
            /*printf("data verify (%.20lf)\n", Inverse_V_Fisher.data[i][j]);
            while(1)
            {
                if(getchar() == 'n') break;
            }*/
        }
    }
    printf("read Inverse_V_Fisher.mat!!!\n");
    //Inverse_V_Fisher.rows = rows;
    //Inverse_V_Fisher.cols = cols;
    fclose(fin);
    fin = 0;
    /**************************************************************/


    /**************Read In The Inverse_V_PCA.mat****************/
    fin = fopen("Inverse_V_PCA.mat", "rb");
    if (fin == NULL) {
        printf("Unable to Open Inverse_V_PCA!!!\n");
        return (0);
    }
    fread(&rows, sizeof (int), 1, fin);
    fread(&cols, sizeof (int), 1, fin);
    printf("Inverse_V_PCA.mat [%d %d]\n", rows, cols);
    Inverse_V_PCA = matrix_constructor(rows, cols);
    //Inverse_V_PCA.data = (double**) malloc(rows * sizeof (double*));
    //for (i = 0; i < rows; i++) {
        Inverse_V_PCA.data[i] = (double*) malloc(cols * sizeof (double));
    //}
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            fread(&(Inverse_V_PCA.data[i][j]), sizeof (double), 1, fin);
            /*printf("data verify (%.20lf) total read - %d\n",
                    Inverse_V_PCA.data[i][j], ((i*cols)+j+1));
            while (1) {
                if(getchar() == '\n') break;
            }*/
        }
    }
    printf("read Inverse_V_PCA.mat!!!\n");
    //Inverse_V_PCA.rows = rows;
    //Inverse_V_PCA.cols = cols;
    fclose(fin);
    fin = 0;
    /**************************************************************/

    /**************Read In The ProjectedImages_Fisher.mat****************/
    fin = fopen("ProjectedImages_Fisher.mat", "rb");
    if (fin == NULL) {
        printf("Unable to Open ProjectedImages_Fisher.mat!!!\n");
        return (0);
    }
    fread(&rows, sizeof (int), 1, fin);
    fread(&cols, sizeof (int), 1, fin);
    printf("ProjectedImages_Fisher.mat [%d %d]\n", rows, cols);
    ProjectedImages_Fisher = matrix_constructor(rows, cols);
    //ProjectedImages_Fisher.data = (double**) malloc(rows * sizeof (double*));
    //for (i = 0; i < rows; i++) {
    //    ProjectedImages_Fisher.data[i] = (double*) malloc(cols * sizeof (double));
    //}
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            fread(&(ProjectedImages_Fisher.data[i][j]), sizeof (double), 1, fin);
        }
    }
    printf("read ProjectedImages_Fisher.mat!!!\n");
    fflush(stdout);
    //ProjectedImages_Fisher.rows = rows;
    //ProjectedImages_Fisher.cols = cols;
    fclose(fin);

    /**************************************************************/

    /**************Read In The v_fisherT_x_v_pcaT.mat****************/
    fin = fopen("v_fisherT_x_v_pcaT.mat", "rb");
    if (fin == NULL) {
        printf("Unable to Open v_fisherT_x_v_pcaT.mat!!!\n");
        return (0);
    }
    fread(&rows, sizeof (int), 1, fin);
    fread(&cols, sizeof (int), 1, fin);
    printf("v_fisherT_x_v_pcaT.mat [%d %d]\n", rows, cols);
    v_fisherT_x_v_pcaT = matrix_constructor(rows, cols);
    //v_fisherT_x_v_pcaT.data = (double**) malloc(rows * sizeof (double*));
    //for (i = 0; i < rows; i++) {
    //    v_fisherT_x_v_pcaT.data[i] = (double*) malloc(cols * sizeof (double));
    //}
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            fread(&(v_fisherT_x_v_pcaT.data[i][j]), sizeof (double), 1, fin);

        }
    }
    printf("read v_fisherT_x_v_pcaT.mat!!!\n");
    fflush(stdout);
    //v_fisherT_x_v_pcaT.rows = rows;
    //v_fisherT_x_v_pcaT.cols = cols;
    fclose(fin);
    /**************************************************************/

    //Now make sure everything is opened properly
    if (m_database.data == NULL || Inverse_V_Fisher.data == NULL
            || Inverse_V_PCA.data == NULL || ProjectedImages_Fisher.data == NULL
            || v_fisherT_x_v_pcaT.data == NULL) {
        return 1; //Memory not allocated properly somewhere
    } else {
        return 0;
    }
}
void operator_matrix() {
    matrix result;
    char in[USHRT_MAX];
    int m;
    int n;
    while (1) {
        printf("Entre com o número de linhas da 1ª matriz: ");
        scanf("%s", in);
        m = atoi(in);
        printf("\n");
        if (m == 0)
            printf("Valor inválido!\n\n");
        else
            break;
    }
    while (1) {
        printf("Entre com o número de colunas da 1ª matriz: ");
        scanf("%s", in);
        n = atoi(in);
        printf("\n");
        if (n == 0)
            printf("Valor inválido!\n\n");
        else
            break;
    }
    result = matrix_constructor(m, n);
    printf("Entre com os elementos da 1ª matriz, separando-os por espaços e/ou quebras de linha:\n");
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++) {
            scanf("%s", in);
            result.table[i][j] = atof(in);
        }
    printf("\n");
    int keep_going = 1;
    while (keep_going) {
        matrix next;
        switch (menu_matrix()) {
            case 1:
                // Add
                while (1) {
                    while (1) {
                        printf("Entre com o número de linhas da proxima matriz: ");
                        scanf("%s", in);
                        m = atoi(in);
                        printf("\n");
                        if (m == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    while (1) {
                        printf("Entre com o número de colunas da proxima matriz: ");
                        scanf("%s", in);
                        n = atoi(in);
                        printf("\n");
                        if (n == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    next = matrix_constructor(m, n);
                    if (!matrix_can_add(result, next))
                        printf("Não é possivel fazer a operação desejada com as matrizes de ordens previamente informadas!\n\n");
                    else
                        break;
                }
                printf("Entre com os elementos da proxima matriz, separando-os por espaços e/ou quebras de linha:\n");
                for (int i = 0; i < m; i++)
                    for (int j = 0; j < n; j++) {
                        scanf("%s", in);
                        next.table[i][j] = atof(in);
                    }
                printf("\n");
                matrix_add(&result, next);
                break;
            case 2:
                // Subtract
                while (1) {
                    while (1) {
                        printf("Entre com o número de linhas da proxima matriz: ");
                        scanf("%s", in);
                        m = atoi(in);
                        printf("\n");
                        if (m == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    while (1) {
                        printf("Entre com o número de colunas da proxima matriz: ");
                        scanf("%s", in);
                        n = atoi(in);
                        printf("\n");
                        if (n == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    next = matrix_constructor(m, n);
                    if (!matrix_can_subtract(result, next))
                        printf("Não é possivel fazer a operação desejada com as matrizes de ordens previamente informadas!\n\n");
                    else
                        break;
                }
                printf("Entre com os elementos da proxima matriz, separando-os por espaços e/ou quebras de linha:\n");
                for (int i = 0; i < m; i++)
                    for (int j = 0; j < n; j++) {
                        scanf("%s", in);
                        next.table[i][j] = atof(in);
                    }
                printf("\n");
                matrix_subtract(&result, next);
                break;
            case 3:
                // Multiply
                while (1) {
                    while (1) {
                        printf("Entre com o número de linhas da proxima matriz: ");
                        scanf("%s", in);
                        m = atoi(in);
                        printf("\n");
                        if (m == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    while (1) {
                        printf("Entre com o número de colunas da proxima matriz: ");
                        scanf("%s", in);
                        n = atoi(in);
                        printf("\n");
                        if (n == 0)
                            printf("Valor inválido!\n\n");
                        else
                            break;
                    }
                    next = matrix_constructor(m, n);
                    if (!matrix_can_multiply(result, next))
                        printf("Não é possivel fazer a operação desejada com as matrizes de ordens previamente informadas!\n\n");
                    else
                        break;
                }
                printf("Entre com os elementos da proxima matriz, separando-os por espaços e/ou quebras de linha:\n");
                for (int i = 0; i < m; i++)
                    for (int j = 0; j < n; j++) {
                        scanf("%s", in);
                        next.table[i][j] = atof(in);
                    }
                printf("\n");
                matrix_multiply(&result, next);
                break;
            case 4:
                // Power
                if (matrix_can_power(result)) {
                    while (1) {
                        printf("Entre com o próximo valor: ");
                        scanf("%s", in);
                        printf("\n");
                        if (atoll(in) >= 0) {
                            matrix_power(&result, (unsigned long long int) atoll(in));
                            break;
                        } else
                            printf("Valor inválido!\n\n");
                    }
                } else
                    printf("Não é possivel realizar a operação desejada com a matrix atual!\n\n");
                break;
            default:
                keep_going = 0;
                break;
        }
        matrix_destructor(&next);
        printf("Resultado:\n\n");
        matrix_print(result);
        printf("\n");
        if (!keep_going)
            matrix_destructor(&result);
    }
}