This commit is contained in:
rdgarce
2023-08-13 16:00:34 +02:00
parent fa1af3ade8
commit 4b3127d84d
21 changed files with 87 additions and 896 deletions
-4
View File
@@ -1,6 +1,2 @@
.swp .swp
test
test2
test_loader
time
.vscode .vscode
+3 -1
View File
@@ -1,2 +1,4 @@
# Lina, the nice-to-read linear algebra toolkit! # Lina, the nice-to-read linear algebra toolkit!
Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations with the aim to be nice to read! Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations with the aim to be nice to read!
The performance branch focuses only on the core functionalities of lina and aims to produce faster and reliable routines.
+84
View File
@@ -0,0 +1,84 @@
#include <time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../src/lina.h"
#define A_ROWS 1000llu
#define A_COLS 146llu
#define B_ROWS 146llu
#define B_COLS 1024llu
uint64_t nanos();
int main()
{
uint64_t ops = A_ROWS*B_COLS*2*A_COLS;
uint64_t start,stop,lina_dot_time, lina_dot_mod1_time, lina_dot_mod1_1_time, lina_dot_mod2_time;
double *A = (double *)malloc(sizeof(double)*A_ROWS*A_COLS);
double *B = (double *)malloc(sizeof(double)*B_ROWS*B_COLS);
double *C1 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS);
double *C2 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS);
double *C3 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS);
double *C4 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS);
for (int i = 0; i < A_ROWS*A_COLS; i++)
A[i] = (double)(rand()%10);
for (int i = 0; i < B_ROWS*B_COLS; i++)
B[i] = (double)(rand()%10);
for (int i = 0; i < A_ROWS*B_COLS; i++)
{
C1[i] = (double)(rand()%10);
C2[i] = (double)(rand()%10);
C3[i] = (double)(rand()%10);
C4[i] = (double)(rand()%10);
}
start = nanos();
lina_dot(A,B,C1,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot_time = stop-start;
start = nanos();
lina_dot_mod1(A,B,C2,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot_mod1_time = stop-start;
start = nanos();
lina_dot_mod2(A,B,C3,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot_mod2_time = stop-start;
start = nanos();
lina_dot_mod2_old(A,B,C4,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot_mod1_1_time = stop-start;
if(!memcmp(C1,C2,sizeof(double)*A_ROWS*B_COLS) && !memcmp(C2,C3,sizeof(double)*A_ROWS*B_COLS) && !memcmp(C3,C4,sizeof(double)*A_ROWS*B_COLS))
{
printf( "lina_dot : %f GFLOPS\n"
"lina_dot_mod1: %f GFLOPS\n"
"lina_dot_mod2: %f GFLOPS\n"
"lina_dot_mod2_old: %f GFLOPS\n", (double)ops/lina_dot_time,
(double)ops/lina_dot_mod1_time,
(double)ops/lina_dot_mod2_time,
(double)ops/lina_dot_mod1_1_time);
}
else
printf("ERRORE: i prodotti matriciali sono diversi!\n");
free(A);
free(B);
free(C1);
free(C2);
free(C3);
free(C4);
}
-87
View File
@@ -1,87 +0,0 @@
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "lina.h"
/* This program compares the lina_transpose
** implementation against the naive implementation.
** Build it with:
** $ gcc time.c lina.c -o time -Wall -Wextra -O3
*/
#define check assert
static void naive_transpose(double *A, double *B, int m, int n)
{
assert(m > 0 && n > 0);
assert(A != NULL && B != NULL);
double *support;
if(A == B)
{
support = malloc(sizeof(*support) * m * n);
check(support != NULL);
memcpy(support, A, sizeof(*support) * m * n);
}
else
{
support = A;
}
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
B[j*n + i] = support[i*m + j];
if(support != A)
free(support);
}
// Wrap transposing functions and return their
// execution time.
static double time_transposition(void (*callback)(double*, double*, int, int), double *A, double *B, int m, int n)
{
clock_t begin = clock();
callback(A, B, m, n);
clock_t end = clock();
return (double) (end - begin) / CLOCKS_PER_SEC;
}
int main()
{
int m = 1000;
int n = 100000;
double *big = malloc(sizeof(double) * m * n);
check(big != NULL);
memset(big, 0, sizeof(double) * m * n);
printf("lina_transpose took %gms (in-place)\n",
1000 * time_transposition(lina_transpose, big, big, m, n));
printf("naive_transpose took %gms (in-place)\n",
1000 * time_transposition(naive_transpose, big, big, m, n));
double *big2 = malloc(sizeof(double) * m * n);
check(big2 != NULL);
printf("lina_transpose took %gms\n",
1000 * time_transposition(lina_transpose, big, big2, m, n));
printf("naive_transpose took %gms\n",
1000 * time_transposition(naive_transpose, big, big2, m, n));
free(big);
free(big2);
return 0;
}
-2
View File
@@ -1,2 +0,0 @@
gcc tests/test.c src/lina.c src/qr.c -o test -Wall -Wextra -g -Isrc/ -lm
gcc tests/test_loader.c src/lina.c src/qr.c -o test_loader -Wall -Wextra -g -Isrc/ -lm
-135
View File
@@ -1,135 +0,0 @@
#include <stdio.h>
#include "src/lina.h"
void print_square_matrix(double *M, int n, FILE *stream)
{
for (int i = 0; i < n; i++)
{
fprintf(stream, "| ");
for (int j = 0; j < n; j++)
{
fprintf(stderr, "%2.2f ", M[i * n + j]);
}
fprintf(stream, "|\n");
}
fprintf(stream, "\n");
}
void print_vector(double complex *V, int n, FILE *stream)
{
fprintf(stream, "[ ");
for (int i = 0; i < n; i++)
fprintf(stderr, "(%2.2f + i%2.2f) ", creal(V[i]), cimag(V[i]));
fprintf(stream, "]\n");
}
int main(void)
{
double M[25] = {
1, 2, 3, 4, 5,
5, 1, 2, 3, 4,
4, 5, 1, 2, 3,
3, 4, 5, 1, 2,
2, 3, 4, 5, 1,
};
fprintf(stderr, "# --- M --- #\n");
print_square_matrix(M, 5, stderr);
/*
double L[25];
double U[25];
int P[5];
double P2[25];
lina_decompLUP(M, L, U, P, 5);
lina_reallyP(P, P2, 5);
fprintf(stderr, "# --- L --- #\n");
print_square_matrix(L, 5, stderr);
fprintf(stderr, "# --- U --- #\n");
print_square_matrix(U, 5, stderr);
fprintf(stderr, "# --- P2 --- #\n");
print_square_matrix(P2, 5, stderr);
double PA[25];
lina_dot(P2, M, PA, 5, 5, 5);
fprintf(stderr, "# --- PA --- #\n");
print_square_matrix(PA, 5, stderr);
double LU[25];
lina_dot(L, U, LU, 5, 5, 5);
fprintf(stderr, "# --- LU --- #\n");
print_square_matrix(LU, 5, stderr);
double det;
lina_det(M, 5, &det);
fprintf(stderr, "det=%2.2f\n", det);
fprintf(stderr, "# --- eig(M) --- #\n");
double complex E[5];
lina_eig(M, E, 5);
print_vector(E, 5, stderr);
*/
double invM[25];
lina_inverse(M, invM, 5);
double expI[25];
lina_dot(M, invM, expI, 5, 5, 5);
fprintf(stderr, "# --- inv(M) --- #\n");
print_square_matrix(invM, 5, stderr);
fprintf(stderr, "# --- I? --- #\n");
print_square_matrix(expI, 5, stderr);
/*
double M[16] = {
1, 5, 4, 2,
2, 1, 5, 3,
4, 3, 2, 5,
5, 4, 3, 1,
};
fprintf(stderr, "# --- M --- #\n");
print_square_matrix(M, 4, stderr);
double L[16];
double U[16];
int P[4];
lina_decompLUP(M, L, U, P, 4);
fprintf(stderr, "# --- L,U,P --- #\n");
print_square_matrix(L, 4, stderr);
print_square_matrix(U, 4, stderr);
fprintf(stderr, "[ ");
for(int i = 0; i < 4; i++)
fprintf(stderr, "%d ", P[i]);
fprintf(stderr, "]\n");
double RP[16];
double PM[16];
lina_reallyP(P, RP, 4);
lina_dot(RP, M, PM, 4, 4, 4);
double LU[16];
lina_dot(L, U, LU, 4, 4, 4);
fprintf(stderr, "# --- P,PM,LU --- #\n");
print_square_matrix(RP, 4, stderr);
print_square_matrix(PM, 4, stderr);
print_square_matrix(LU, 4, stderr);
double det;
lina_det(M, 4, &det);
fprintf(stderr, "det(M) = %2.2f\n", det);
*/
return 0;
}
-16
View File
@@ -1,16 +0,0 @@
## Description
Here is developed the testing unit for all the lina functions that need numerical testing.
## Usage
For each function in the lina library named in the form of _lina_something()_, here is defined a folder named _something_. In each folder there are many tests, each one identified by a ti.txt file, for i=1,...,n.
Each test file is defined as follows: The first matrix/matrices are the inputs of the function (depending on the function, for example: lina_add() has two inputs A,B and one output C=A+B. A and B have to be the first two matrices in the test file), the last matrix/matrices are the output of the function and after there are input scalar values (ordered in the same order of the function under test) of the function represented as a 1x1 matrix.
For example, a scale test file, that is a test for the lina_scale() function is defined as follows:
[1 1 1,1 1 1,1 1 1]
[2 2 2,2 2 2,2 2 2]
[2]
Where the first matrix is the input, the second the output and the last is the scalar value.
By default, executing the test file will generate all the testing and provide the results on the stdout.
-11
View File
@@ -1,11 +0,0 @@
[1 0 0,
0 1 0,
0 0 1]
[1 0 0,
0 1 0,
0 0 1]
[1 0 0,
0 1 0,
0 0 1]
-9
View File
@@ -1,9 +0,0 @@
[1 1 1,
1 1 1,
1 1 1]
[2 2 2,
2 2 2,
2 2 2]
[2]
-553
View File
@@ -1,553 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <dirent.h>
#include <sys/types.h>
#include <errno.h>
#include "lina.h"
#define check assert
//Print the matrix A with size m by n
static void pmatrix(FILE *fp, double *A, int m, int n);
typedef struct dot_test{
double *A;
double *B;
double *C;
int m;
int n;
int l;
}dot_test;
typedef struct add_test{
double *A;
double *B;
double *C;
int m;
int n;
}add_test;
typedef struct scale_test{
double *A;
double *B;
double s;
int m;
int n;
}scale_test;
typedef struct transpose_test{
double *A;
double *B;
int m;
int n;
}transpose_test;
#define PATH "./tests/"
int main()
{
//Defining pointers to the test structures
add_test *add_tests;
dot_test *dot_tests;
scale_test *scale_tests;
transpose_test *transpose_tests;
//Number of tests for each lina functions
int n_dot_tests, n_add_tests, n_scale_tests, n_transpose_tests;
//Opening dir stream
DIR *dir = opendir(PATH);
struct dirent *ep;
check(dir != NULL);
//Loading all the tests from files
while (ep = readdir(dir))
{
if(ep->d_type != DT_DIR || !strcmp(ep->d_name, ".") || !strcmp(ep->d_name, ".."))
continue;
if(!strcmp(ep->d_name,"add"))
{
//Implement loading lina_add test matrices
char sub_path[256] = PATH;
strcat(sub_path,ep->d_name);
strcat(sub_path,"/");
DIR *sub_dir = opendir(sub_path);
check(sub_dir != NULL);
struct dirent *sub_ep;
unsigned int count = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
count += 1;
}
closedir(sub_dir);
sub_dir = opendir(sub_path);
check(sub_dir != NULL);
add_tests = malloc(sizeof(add_test)*count);
n_add_tests = count;
int i = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
char file_pos[256];
strcat(file_pos,sub_path);
strcat(file_pos,sub_ep->d_name);
FILE *fp;
fp = fopen(file_pos,"r");
check(fp != NULL);
int m,n;
char *error;
add_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(add_tests[i].A != NULL);
add_tests[i].B = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(add_tests[i].B != NULL);
add_tests[i].C = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(add_tests[i].C != NULL);
add_tests[i].m = m;
add_tests[i].n = n;
i += 1;
fclose(fp);
}
closedir(sub_dir);
}
else if (!strcmp(ep->d_name,"dot"))
{
//Implement loading lina_dot test matrices
char sub_path[256] = PATH;
strcat(sub_path,ep->d_name);
strcat(sub_path,"/");
DIR *sub_dir = opendir(sub_path);
check(sub_dir != NULL);
struct dirent *sub_ep;
unsigned int count = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
count += 1;
}
closedir(sub_dir);
sub_dir = opendir(sub_path);
check(sub_dir != NULL);
dot_tests = malloc(sizeof(dot_test)*count);
n_dot_tests = count;
int i = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
char file_pos[256];
strcpy(file_pos,sub_path);
strcat(file_pos,sub_ep->d_name);
FILE *fp;
fp = fopen(file_pos,"r");
check(fp != NULL);
int m,n,l;
char *error;
dot_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(dot_tests[i].A != NULL);
dot_tests[i].B = lina_loadMatrixFromStream(fp,&l,&n,&error);
check(dot_tests[i].B != NULL);
dot_tests[i].C = lina_loadMatrixFromStream(fp,&l,&m,&error);
check(dot_tests[i].C != NULL);
dot_tests[i].m = m;
dot_tests[i].n = n;
dot_tests[i].l = l;
i += 1;
fclose(fp);
}
closedir(sub_dir);
}
else if (!strcmp(ep->d_name,"scale"))
{
//Implement loading lina_scale test matrices
char sub_path[256] = PATH;
strcat(sub_path,ep->d_name);
strcat(sub_path,"/");
DIR *sub_dir = opendir(sub_path);
check(sub_dir != NULL);
struct dirent *sub_ep;
unsigned int count = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
count += 1;
}
closedir(sub_dir);
sub_dir = opendir(sub_path);
check(sub_dir != NULL);
scale_tests = malloc(sizeof(scale_test)*count);
n_scale_tests = count;
int i = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
char file_pos[256];
strcpy(file_pos,sub_path);
strcat(file_pos,sub_ep->d_name);
FILE *fp;
fp = fopen(file_pos,"r");
check(fp != NULL);
int m,n;
int useless1,useless2;
double *scale;
char *error;
scale_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(scale_tests[i].A != NULL);
scale_tests[i].B = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(scale_tests[i].B != NULL);
scale = lina_loadMatrixFromStream(fp,&useless1,&useless2,&error);
check(scale != NULL);
scale_tests[i].m = m;
scale_tests[i].n = n;
scale_tests[i].s = scale[0];
free(scale);
i += 1;
fclose(fp);
}
closedir(sub_dir);
}
else if (!strcmp(ep->d_name,"transpose"))
{
//Implement loading lina_transpose test matrices
char sub_path[256] = PATH;
strcat(sub_path,ep->d_name);
strcat(sub_path,"/");
DIR *sub_dir = opendir(sub_path);
check(sub_dir != NULL);
struct dirent *sub_ep;
unsigned int count = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
count += 1;
}
closedir(sub_dir);
sub_dir = opendir(sub_path);
check(sub_dir != NULL);
transpose_tests = malloc(sizeof(transpose_test)*count);
n_transpose_tests = count;
int i = 0;
while (sub_ep = readdir(sub_dir))
{
if(sub_ep->d_type == DT_DIR)
continue;
char file_pos[256];
strcpy(file_pos,sub_path);
strcat(file_pos,sub_ep->d_name);
FILE *fp;
fp = fopen(file_pos,"r");
check(fp != NULL);
int m,n;
char *error;
transpose_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error);
check(transpose_tests[i].A != NULL);
transpose_tests[i].B = lina_loadMatrixFromStream(fp,&m,&n,&error);
check(transpose_tests[i].B != NULL);
transpose_tests[i].m = m;
transpose_tests[i].n = n;
i += 1;
fclose(fp);
}
closedir(sub_dir);
}
}
closedir(dir);
//Starting the lina_add tests
{
int passed_tests = 0;
fprintf(stdout,"Starting tests on lina_add():\n");
for(int i=0;i<n_add_tests;i++){
double *C = (double*) malloc(sizeof(*C)*add_tests[i].m * add_tests[i].n);
check(C != NULL);
lina_add(add_tests[i].A, add_tests[i].B, C,add_tests[i].m,add_tests[i].n);
if( !memcmp(add_tests[i].C, C, sizeof(*C)*add_tests[i].m * add_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_add() failed on the following matrices:\n");
pmatrix(stderr,add_tests[i].A, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"+\n");
pmatrix(stderr,add_tests[i].B, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"lina_add() gives following output:\n");
pmatrix(stderr,C, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,add_tests[i].C, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_add_tests != 0)
fprintf(stdout, "Test on lina_add() finished: %d out of %d tests were succesfull\n",passed_tests,n_add_tests);
else
fprintf(stdout, "There are no tests for lina_add() function.\n");
}
//Starting the lina_dot tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_dot():\n");
for(int i=0;i<n_dot_tests;i++){
double *C = (double*) malloc(sizeof(*C)*dot_tests[i].m * dot_tests[i].l);
check(C != NULL);
lina_dot(dot_tests[i].A, dot_tests[i].B, C, dot_tests[i].m, dot_tests[i].n, dot_tests[i].l);
if( !memcmp(dot_tests[i].C, C, sizeof(*C)*dot_tests[i].m * dot_tests[i].l) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_dot() failed on the following matrices:\n");
pmatrix(stderr,dot_tests[i].A, dot_tests[i].m, dot_tests[i].n);
fprintf(stderr,"*\n");
pmatrix(stderr,dot_tests[i].B, dot_tests[i].n, dot_tests[i].l);
fprintf(stderr,"lina_dot() gives following output:\n");
pmatrix(stderr,C, dot_tests[i].m, dot_tests[i].l);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,dot_tests[i].C, dot_tests[i].m, dot_tests[i].l);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_dot_tests != 0)
fprintf(stdout, "Test on lina_dot() finished: %d out of %d tests were succesfull\n",passed_tests,n_dot_tests);
else
fprintf(stdout, "There are no tests for lina_dot() function.\n");
}
//Starting the lina_transpose tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_transpose():\n");
for(int i=0;i<n_transpose_tests;i++){
double *C = (double*) malloc(sizeof(*C)*transpose_tests[i].m * transpose_tests[i].n);
check(C != NULL);
lina_transpose(transpose_tests[i].A, C, transpose_tests[i].m, transpose_tests[i].n);
if( !memcmp(transpose_tests[i].B, C, sizeof(*C)*transpose_tests[i].m * transpose_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_transpose() failed on the following matrices:\n");
pmatrix(stderr,transpose_tests[i].A, transpose_tests[i].m, transpose_tests[i].n);
fprintf(stderr,"lina_transpose() gives following output:\n");
pmatrix(stderr,C, transpose_tests[i].n, transpose_tests[i].m);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,transpose_tests[i].B, transpose_tests[i].n, transpose_tests[i].m);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_transpose_tests != 0)
fprintf(stdout, "Test on lina_transpose() finished: %d out of %d tests were succesfull\n",passed_tests,n_transpose_tests);
else
fprintf(stdout, "There are no tests for lina_transpose() function.\n");
}
//Starting the lina_scale tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_scale():\n");
for(int i=0;i<n_scale_tests;i++){
double *C = (double*) malloc(sizeof(*C)*scale_tests[i].m * scale_tests[i].n);
check(C != NULL);
lina_scale(scale_tests[i].A, C, scale_tests[i].s, scale_tests[i].m, scale_tests[i].n);
if( !memcmp(scale_tests[i].B, C, sizeof(*C)*scale_tests[i].m * scale_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_scale() failed on the following matrices:\n");
pmatrix(stderr,scale_tests[i].A, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"lina_scale() gives following output:\n");
pmatrix(stderr, C, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,scale_tests[i].B, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_scale_tests != 0)
fprintf(stdout, "Test on lina_scale() finished: %d out of %d tests were succesfull\n",passed_tests,n_scale_tests);
else
fprintf(stdout, "There are no tests for lina_scale() function.\n");
}
//Freeing the memory of all the heap variables
{
//Freeing add_tests memory
for(int i=0;i< n_add_tests;i++)
{
free(add_tests[i].A);
free(add_tests[i].B);
free(add_tests[i].C);
}
//Freeing dot_tests memory
for(int i=0;i< n_dot_tests;i++)
{
free(dot_tests[i].A);
free(dot_tests[i].B);
free(dot_tests[i].C);
}
//Freeing scale_tests memory
for(int i=0;i< n_scale_tests;i++)
{
free(scale_tests[i].A);
free(scale_tests[i].B);
}
//Freeing transpose_tests memory
for(int i=0;i< n_transpose_tests;i++)
{
free(transpose_tests[i].A);
free(transpose_tests[i].B);
}
}
return 0;
}
static void pmatrix(FILE *fp, double *A,int m,int n){
for(int i = 0; i<m; i++){
fprintf(fp, " | ");
for(int j = 0; j< n; j++)
fprintf(fp, "%g ",A[i*n + j]);
fprintf(fp, "|\n");
}
fprintf(fp, "\n");
}
-9
View File
@@ -1,9 +0,0 @@
[1 0 0 0,
0 2 0 0,
0 0 3 0,
0 0 0 4]
[1 0 0 0,
0 2 0 0,
0 0 3 0,
0 0 0 4]
-6
View File
@@ -1,6 +0,0 @@
[1 2,
3 4,
5 6]
[1 3 5,
2 4 6]
-9
View File
@@ -1,9 +0,0 @@
[1 2 3 4,
0 0 0 0,
0 0 0 0,
0 0 0 0]
[1 0 0 0,
2 0 0 0,
3 0 0 0,
4 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 1 0 0,
0 2 0 0,
0 3 0 0,
0 4 0 0]
[0 0 0 0,
1 2 3 4,
0 0 0 0,
0 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 0 1 0,
0 0 2 0,
0 0 3 0,
0 0 4 0]
[0 0 0 0,
0 0 0 0,
1 2 3 4,
0 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 0 0 0,
0 0 0 0,
0 0 0 0,
1 2 3 4]
[0 0 0 1,
0 0 0 2,
0 0 0 3,
0 0 0 4]
-7
View File
@@ -1,7 +0,0 @@
[1 0 0,
0 2 0,
0 0 3]
[1 0 0,
0 2 0,
0 0 3]
-7
View File
@@ -1,7 +0,0 @@
[1 2 3,
0 0 0,
0 0 0]
[1 0 0,
2 0 0,
3 0 0]
-7
View File
@@ -1,7 +0,0 @@
[0 0 1,
0 0 2,
0 0 3]
[0 0 0,
0 0 0,
1 2 3]
-6
View File
@@ -1,6 +0,0 @@
[1 2 3,
4 5 6]
[1 4,
2 5,
3 6]