changed curly bracket code style
This commit is contained in:
@@ -1,4 +1,2 @@
|
|||||||
# Lina
|
# Lina, the nice-to-read linear algebra toolkit!
|
||||||
Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations.
|
Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations with the aim to be nice to read!
|
||||||
|
|
||||||
Note that this is still a work in progress.
|
|
||||||
+252
-292
@@ -29,36 +29,28 @@
|
|||||||
** - This function can never fail.
|
** - This function can never fail.
|
||||||
*/
|
*/
|
||||||
void lina_dot(double *A, double *B, double *C, int m, int n, int l)
|
void lina_dot(double *A, double *B, double *C, int m, int n, int l)
|
||||||
{
|
|
||||||
lina_dot2(A, B, C, 0, 0, 0, m, n, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lina_dot2(double *A, double *B, double *C,
|
|
||||||
int As, int Bs, int Cs,
|
|
||||||
int m, int n, int l)
|
|
||||||
{
|
{
|
||||||
assert(m > 0 && n > 0 && l > 0);
|
assert(m > 0 && n > 0 && l > 0);
|
||||||
assert(As >= 0 && Bs >= 0 && Cs >= 0);
|
|
||||||
assert(A != NULL && B != NULL && C != NULL);
|
assert(A != NULL && B != NULL && C != NULL);
|
||||||
assert(A != C && B != C);
|
assert(A != C && B != C);
|
||||||
|
|
||||||
// Iteration over A's rows
|
// Iteration over A's rows
|
||||||
for(int i = 0; i < m; i++)
|
for(int i = 0; i < m; i++) {
|
||||||
{
|
|
||||||
// Iteration over B's columns
|
|
||||||
for(int k = 0; k < l; k++)
|
|
||||||
{
|
|
||||||
double pos = 0;
|
|
||||||
|
|
||||||
// Iteration over the single B column
|
// Iteration over B's columns
|
||||||
// for executing the product of sum
|
for(int k = 0; k < l; k++) {
|
||||||
|
|
||||||
for(int j=0; j < n; j++)
|
double sum = 0;
|
||||||
pos += A[i*(n + As) + j] * B[j*(l + Bs) + k];
|
|
||||||
|
|
||||||
C[i*(l + Cs) + k] = pos;
|
// Iteration over the single B column
|
||||||
}
|
// for executing the product of sum
|
||||||
|
|
||||||
|
for(int j=0; j < n; j++)
|
||||||
|
sum += A[i * n + j] * B[j * l + k];
|
||||||
|
|
||||||
|
C[i * l + k] = sum;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: lina_add
|
/* Function: lina_add
|
||||||
@@ -130,68 +122,64 @@ void lina_transpose(double *A, double *B, int m, int n)
|
|||||||
assert(m > 0 && n > 0);
|
assert(m > 0 && n > 0);
|
||||||
assert(A != NULL && B != NULL);
|
assert(A != NULL && B != NULL);
|
||||||
|
|
||||||
if(m == 1 || n == 1)
|
if(m == 1 || n == 1) {
|
||||||
{
|
// For a matrix with height or width of 1
|
||||||
// For a matrix with height or width of 1
|
// row-major and column-major order coincide,
|
||||||
// row-major and column-major order coincide,
|
// so the stransposition doesn't change the
|
||||||
// so the stransposition doesn't change the
|
// the memory representation. A simple copy
|
||||||
// the memory representation. A simple copy
|
// does the job.
|
||||||
// does the job.
|
|
||||||
|
|
||||||
if(A != B) // Does the copy or the branch cost more?
|
if(A != B) // Does the copy or the branch cost more?
|
||||||
memcpy(B, A, sizeof(A[0]) * m * n);
|
memcpy(B, A, sizeof(A[0]) * m * n);
|
||||||
|
|
||||||
|
} else if(m == n) {
|
||||||
|
|
||||||
|
// Iterate over the upper triangular portion of
|
||||||
|
// the matrix and switch each element with the
|
||||||
|
// corresponding one in the lower triangular portion.
|
||||||
|
// NOTE: We're assuming A,B might be the same matrix.
|
||||||
|
// If A,B are the same matrix, then the diagonal
|
||||||
|
// is copied onto itself. By removing the +1 in
|
||||||
|
// the inner loop, the copying of the diagonal
|
||||||
|
// is avoided.
|
||||||
|
|
||||||
|
for(int i = 0; i < n; i += 1)
|
||||||
|
for(int j = 0; j < i+1; j += 1) {
|
||||||
|
double temp = A[i*n + j];
|
||||||
|
B[i*n + j] = A[j*n + i];
|
||||||
|
B[j*n + i] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Not only the matrix needs to be transposed
|
||||||
|
// assuming the destination matrix is the same
|
||||||
|
// as the source matrix, but the memory representation
|
||||||
|
// of the matrix needs to switch from row-major
|
||||||
|
// to col-major, so it's not as simple as switching
|
||||||
|
// value's positions.
|
||||||
|
// This algorithm starts from the A[0][1] value and
|
||||||
|
// moves it where it needs to go, then gets the value
|
||||||
|
// that was at that position and puts that in it's
|
||||||
|
// new position. This process is iterated until the
|
||||||
|
// starting point A[0][1] is overwritten with the
|
||||||
|
// new value. In this process the first and last
|
||||||
|
// value of the matrix never move.
|
||||||
|
|
||||||
|
B[0] = A[0];
|
||||||
|
B[m*n - 1] = A[m*n - 1];
|
||||||
|
|
||||||
|
double item = A[1];
|
||||||
|
int next = m;
|
||||||
|
|
||||||
|
while(next != 1) {
|
||||||
|
double temp = A[next];
|
||||||
|
B[next] = item;
|
||||||
|
item = temp;
|
||||||
|
next = (next % n) * m + (next / n);
|
||||||
}
|
}
|
||||||
else if(m == n)
|
|
||||||
{
|
|
||||||
// Iterate over the upper triangular portion of
|
|
||||||
// the matrix and switch each element with the
|
|
||||||
// corresponding one in the lower triangular portion.
|
|
||||||
// NOTE: We're assuming A,B might be the same matrix.
|
|
||||||
// If A,B are the same matrix, then the diagonal
|
|
||||||
// is copied onto itself. By removing the +1 in
|
|
||||||
// the inner loop, the copying of the diagonal
|
|
||||||
// is avoided.
|
|
||||||
|
|
||||||
for(int i = 0; i < n; i += 1)
|
B[1] = item;
|
||||||
for(int j = 0; j < i+1; j += 1)
|
}
|
||||||
{
|
|
||||||
double temp = A[i*n + j];
|
|
||||||
B[i*n + j] = A[j*n + i];
|
|
||||||
B[j*n + i] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Not only the matrix needs to be transposed
|
|
||||||
// assuming the destination matrix is the same
|
|
||||||
// as the source matrix, but the memory representation
|
|
||||||
// of the matrix needs to switch from row-major
|
|
||||||
// to col-major, so it's not as simple as switching
|
|
||||||
// value's positions.
|
|
||||||
// This algorithm starts from the A[0][1] value and
|
|
||||||
// moves it where it needs to go, then gets the value
|
|
||||||
// that was at that position and puts that in it's
|
|
||||||
// new position. This process is iterated until the
|
|
||||||
// starting point A[0][1] is overwritten with the
|
|
||||||
// new value. In this process the first and last
|
|
||||||
// value of the matrix never move.
|
|
||||||
|
|
||||||
B[0] = A[0];
|
|
||||||
B[m*n - 1] = A[m*n - 1];
|
|
||||||
|
|
||||||
double item = A[1];
|
|
||||||
int next = m;
|
|
||||||
|
|
||||||
while(next != 1)
|
|
||||||
{
|
|
||||||
double temp = A[next];
|
|
||||||
B[next] = item;
|
|
||||||
item = temp;
|
|
||||||
next = (next % n) * m + (next / n);
|
|
||||||
}
|
|
||||||
|
|
||||||
B[1] = item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: scanValue
|
/* Function: scanValue
|
||||||
@@ -241,22 +229,19 @@ static int scanValue(FILE *fp, char *buffer, int max_length, char first, char *f
|
|||||||
// Scan the integer portion of
|
// Scan the integer portion of
|
||||||
// the numeric value and copy it
|
// the numeric value and copy it
|
||||||
// into the buffer.
|
// into the buffer.
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
if(n == max_length)
|
|
||||||
{
|
|
||||||
// ERROR: Internal buffer is too small to hold
|
|
||||||
// the representation of this item.
|
|
||||||
*error = "Internal buffer is too small to hold "
|
|
||||||
"the representation of a numeric value";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[n++] = c;
|
if(n == max_length) {
|
||||||
|
*error = "Internal buffer is too small to hold "
|
||||||
c = getc(fp);
|
"the representation of a numeric value";
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
while(c != EOF && isdigit(c));
|
|
||||||
|
buffer[n++] = c;
|
||||||
|
|
||||||
|
c = getc(fp);
|
||||||
|
|
||||||
|
} while(c != EOF && isdigit(c));
|
||||||
|
|
||||||
// Did the integer part end with
|
// Did the integer part end with
|
||||||
// a dot?
|
// a dot?
|
||||||
@@ -265,48 +250,42 @@ static int scanValue(FILE *fp, char *buffer, int max_length, char first, char *f
|
|||||||
// Now scan and copy the decimal
|
// Now scan and copy the decimal
|
||||||
// part of the numeric value if
|
// part of the numeric value if
|
||||||
// a dot was found.
|
// a dot was found.
|
||||||
if(dot)
|
if(dot) {
|
||||||
{
|
if(n == max_length) {
|
||||||
if(n == max_length)
|
// ERROR: Internal buffer is too small to hold
|
||||||
{
|
// the representation of this item.
|
||||||
// ERROR: Internal buffer is too small to hold
|
// (The dot doesn't fit.)
|
||||||
// the representation of this item.
|
*error = "Internal buffer is too small to hold "
|
||||||
// (The dot doesn't fit.)
|
"the representation of a numeric value";
|
||||||
*error = "Internal buffer is too small to hold "
|
return 0;
|
||||||
"the representation of a numeric value";
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[n++] = '.';
|
buffer[n++] = '.';
|
||||||
|
|
||||||
|
c = getc(fp);
|
||||||
|
|
||||||
|
if(!isdigit(c)) {
|
||||||
|
// ERROR: Got something other than a
|
||||||
|
// digit after the dot.
|
||||||
|
*error = "Got something other than a digit after the dot.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if(n == max_length) {
|
||||||
|
// ERROR: Internal buffer is too small
|
||||||
|
// to hold the representation of
|
||||||
|
// this item.
|
||||||
|
*error = "Internal buffer is too small to hold "
|
||||||
|
"the representation of a numeric value";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[n++] = c;
|
||||||
|
|
||||||
c = getc(fp);
|
c = getc(fp);
|
||||||
|
} while(c != EOF && isdigit(c));
|
||||||
if(!isdigit(c))
|
}
|
||||||
{
|
|
||||||
// ERROR: Got something other than a
|
|
||||||
// digit after the dot.
|
|
||||||
*error = "Got something other than a digit after the dot.";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(n == max_length)
|
|
||||||
{
|
|
||||||
// ERROR: Internal buffer is too small
|
|
||||||
// to hold the representation of
|
|
||||||
// this item.
|
|
||||||
*error = "Internal buffer is too small to hold "
|
|
||||||
"the representation of a numeric value";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[n++] = c;
|
|
||||||
|
|
||||||
c = getc(fp);
|
|
||||||
}
|
|
||||||
while(c != EOF && isdigit(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer[n] = '\0';
|
buffer[n] = '\0';
|
||||||
|
|
||||||
@@ -377,23 +356,21 @@ double *lina_loadMatrixFromStream(FILE *fp, int *width, int *height, char **erro
|
|||||||
while(c != EOF && isspace(c))
|
while(c != EOF && isspace(c))
|
||||||
c = getc(fp);
|
c = getc(fp);
|
||||||
|
|
||||||
if(c == EOF)
|
if(c == EOF) {
|
||||||
{
|
// ERROR: Stream ended before a matrix was
|
||||||
// ERROR: Stream ended before a matrix was
|
// found.
|
||||||
// found.
|
*error = "Stream ended before a matrix was found";
|
||||||
*error = "Stream ended before a matrix was found";
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(c != '[')
|
if(c != '[') {
|
||||||
{
|
// ERROR: Was expected a '[' as the first
|
||||||
// ERROR: Was expected a '[' as the first
|
// character of a matrix, but got
|
||||||
// character of a matrix, but got
|
// something else instead.
|
||||||
// something else instead.
|
*error = "Got something other than a matrix "
|
||||||
*error = "Got something other than a matrix "
|
"where one was expected";
|
||||||
"where one was expected";
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
c = getc(fp);
|
c = getc(fp);
|
||||||
|
|
||||||
@@ -401,173 +378,161 @@ double *lina_loadMatrixFromStream(FILE *fp, int *width, int *height, char **erro
|
|||||||
while(c != EOF && isspace(c))
|
while(c != EOF && isspace(c))
|
||||||
c = getc(fp);
|
c = getc(fp);
|
||||||
|
|
||||||
if(c == EOF)
|
if(c == EOF) {
|
||||||
{
|
// ERROR: Stream ended where a numeric value
|
||||||
// ERROR: Stream ended where a numeric value
|
// was expected.
|
||||||
// was expected.
|
*error = "Stream ended where a numeric value "
|
||||||
*error = "Stream ended where a numeric value "
|
"was expected";
|
||||||
"was expected";
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
double *matrix = malloc(sizeof(matrix[0]) * 64);
|
double *matrix = malloc(sizeof(matrix[0]) * 64);
|
||||||
|
|
||||||
if(matrix == NULL)
|
if(matrix == NULL) {
|
||||||
{
|
// ERROR: Insufficient memory.
|
||||||
// ERROR: Insufficient memory.
|
*error = "Insufficient memory";
|
||||||
*error = "Insufficient memory";
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int capacity = 64, size = 0,
|
int capacity = 64, size = 0,
|
||||||
w = -1, i = 0, j = 0;
|
w = -1, i = 0, j = 0;
|
||||||
|
|
||||||
if(c != ']')
|
if(c != ']')
|
||||||
while(1)
|
while(1) {
|
||||||
{
|
if(!isdigit(c)) {
|
||||||
if(!isdigit(c))
|
// ERROR: Got something other than a digit
|
||||||
{
|
// where a numeric value was expected.
|
||||||
// ERROR: Got something other than a digit
|
*error = "Got something other than a numeric "
|
||||||
// where a numeric value was expected.
|
"value where one was expected";
|
||||||
*error = "Got something other than a numeric "
|
return NULL;
|
||||||
"value where one was expected";
|
}
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numeric values can't be represented
|
// Numeric values can't be represented
|
||||||
// in strings bigger than this buffer
|
// in strings bigger than this buffer
|
||||||
// since they need to be copied in it
|
// since they need to be copied in it
|
||||||
// to be converted to actual numeric
|
// to be converted to actual numeric
|
||||||
// variables.
|
// variables.
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
|
||||||
int res = scanValue(fp, buffer, sizeof(buffer), c, &c, error);
|
int res = scanValue(fp, buffer, sizeof(buffer), c, &c, error);
|
||||||
|
|
||||||
if(res == 0)
|
if(res == 0)
|
||||||
// Failed to scan the value, abort.
|
// Failed to scan the value, abort.
|
||||||
// NOTE: The error was already reported.
|
// NOTE: The error was already reported.
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
assert(res == 1 || res == -1);
|
||||||
|
|
||||||
|
// Make sure the matrix has enough space.
|
||||||
|
if(size == capacity) {
|
||||||
|
int new_capacity = capacity * 2;
|
||||||
|
|
||||||
|
double *temp = realloc(matrix, sizeof(double) * new_capacity);
|
||||||
|
|
||||||
|
if(temp == NULL) {
|
||||||
|
// ERROR: Insufficient memory.
|
||||||
|
*error = "Insufficient memory";
|
||||||
|
free(matrix);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
assert(res == 1 || res == -1);
|
matrix = temp;
|
||||||
|
capacity = new_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the matrix has enough space.
|
errno = 0;
|
||||||
if(size == capacity)
|
|
||||||
{
|
|
||||||
int new_capacity = capacity * 2;
|
|
||||||
|
|
||||||
double *temp = realloc(matrix, sizeof(double) * new_capacity);
|
double casted;
|
||||||
|
|
||||||
if(temp == NULL)
|
if(res == 1)
|
||||||
{
|
casted = (double) strtoll(buffer, NULL, 10);
|
||||||
// ERROR: Insufficient memory.
|
else
|
||||||
*error = "Insufficient memory";
|
casted = strtod(buffer, NULL);
|
||||||
free(matrix);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix = temp;
|
if(errno) {
|
||||||
capacity = new_capacity;
|
// ERROR: Failed to convert a numeric value
|
||||||
}
|
// from it's string form to a numeric
|
||||||
|
// variable.
|
||||||
|
*error = "Failed to convert string to number";
|
||||||
|
free(matrix);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
matrix[size++] = casted;
|
||||||
|
|
||||||
double casted;
|
i += 1;
|
||||||
|
|
||||||
if(res == 1)
|
while(c != EOF && isspace(c))
|
||||||
casted = (double) strtoll(buffer, NULL, 10);
|
c = getc(fp);
|
||||||
else
|
|
||||||
casted = strtod(buffer, NULL);
|
|
||||||
|
|
||||||
if(errno)
|
if(c == ']' || c == ',') {
|
||||||
{
|
// The matrix's row just ended.
|
||||||
// ERROR: Failed to convert a numeric value
|
|
||||||
// from it's string form to a numeric
|
if(w == -1)
|
||||||
// variable.
|
// This was the first row.
|
||||||
*error = "Failed to convert string to number";
|
w = i;
|
||||||
free(matrix);
|
else {
|
||||||
|
// This wasn't the first row,
|
||||||
|
// so it's possible that it's
|
||||||
|
// length is different from the
|
||||||
|
// previous ones.
|
||||||
|
assert(w > -1);
|
||||||
|
|
||||||
|
if(i != w) {
|
||||||
|
// ERROR: The j-th row has the wrong
|
||||||
|
// number of elements.
|
||||||
|
if(i < w)
|
||||||
|
*error = "Matrix row is too short";
|
||||||
|
else
|
||||||
|
*error = "Matrix row is too long";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
matrix[size++] = casted;
|
i = 0;
|
||||||
|
j += 1;
|
||||||
|
|
||||||
i += 1;
|
if(c == ']')
|
||||||
|
// The whole matrix ended!
|
||||||
|
break;
|
||||||
|
|
||||||
|
c = getc(fp);
|
||||||
|
|
||||||
while(c != EOF && isspace(c))
|
while(c != EOF && isspace(c))
|
||||||
c = getc(fp);
|
c = getc(fp);
|
||||||
|
|
||||||
if(c == ']' || c == ',')
|
|
||||||
{
|
|
||||||
// The matrix's row just ended.
|
|
||||||
|
|
||||||
if(w == -1)
|
|
||||||
// This was the first row.
|
|
||||||
w = i;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This wasn't the first row,
|
|
||||||
// so it's possible that it's
|
|
||||||
// length is different from the
|
|
||||||
// previous ones.
|
|
||||||
assert(w > -1);
|
|
||||||
|
|
||||||
if(i != w)
|
|
||||||
{
|
|
||||||
// ERROR: The j-th row has the wrong
|
|
||||||
// number of elements.
|
|
||||||
if(i < w)
|
|
||||||
*error = "Matrix row is too short";
|
|
||||||
else
|
|
||||||
*error = "Matrix row is too long";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
j += 1;
|
|
||||||
|
|
||||||
if(c == ']')
|
|
||||||
// The whole matrix ended!
|
|
||||||
break;
|
|
||||||
|
|
||||||
c = getc(fp);
|
|
||||||
|
|
||||||
while(c != EOF && isspace(c))
|
|
||||||
c = getc(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(c == EOF)
|
|
||||||
{
|
|
||||||
// ERROR: Stream ended inside a matrix, where
|
|
||||||
// either ',', ']' or a numeric value was
|
|
||||||
// expected.
|
|
||||||
*error = "Stream ended inside a matrix, where either "
|
|
||||||
"',', ']' or a numeric value was expected";
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(size == 0)
|
if(c == EOF) {
|
||||||
{
|
// ERROR: Stream ended inside a matrix, where
|
||||||
free(matrix);
|
// either ',', ']' or a numeric value was
|
||||||
*error = "Empty matrix";
|
// expected.
|
||||||
return NULL;
|
*error = "Stream ended inside a matrix, where either "
|
||||||
|
"',', ']' or a numeric value was expected";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(size == 0) {
|
||||||
|
free(matrix);
|
||||||
|
*error = "Empty matrix";
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// If the internal fragmentation is too much,
|
// If the internal fragmentation is too much,
|
||||||
// return a dynamic memory region with the
|
// return a dynamic memory region with the
|
||||||
// exact size instead of the buffer used to
|
// exact size instead of the buffer used to
|
||||||
// build the matrix.
|
// build the matrix.
|
||||||
int fragm_threshold = 30; // (It's a percentage)
|
int fragm_threshold = 30; // (It's a percentage)
|
||||||
|
|
||||||
if(100.0 * size/capacity < fragm_threshold)
|
if(100.0 * size/capacity < fragm_threshold) {
|
||||||
{
|
|
||||||
int new_capacity = (size == 0) ? 1 : size;
|
|
||||||
|
|
||||||
double *temp = realloc(matrix, new_capacity * sizeof(double));
|
int new_capacity = (size == 0) ? 1 : size;
|
||||||
|
|
||||||
if(temp != NULL)
|
double *temp = realloc(matrix, new_capacity * sizeof(double));
|
||||||
matrix = temp;
|
|
||||||
}
|
if(temp != NULL)
|
||||||
|
matrix = temp;
|
||||||
|
}
|
||||||
|
|
||||||
*width = w;
|
*width = w;
|
||||||
*height = j;
|
*height = j;
|
||||||
@@ -613,14 +578,12 @@ int lina_saveMatrixToStream(FILE *fp, double *A, int width, int height, char **e
|
|||||||
else
|
else
|
||||||
*error = NULL;
|
*error = NULL;
|
||||||
|
|
||||||
if (width < 1)
|
if (width < 1) {
|
||||||
{
|
|
||||||
*error = "The provided width is less than one";
|
*error = "The provided width is less than one";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (height < 1)
|
if (height < 1) {
|
||||||
{
|
|
||||||
*error = "The provided height is less than one";
|
*error = "The provided height is less than one";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -630,19 +593,17 @@ int lina_saveMatrixToStream(FILE *fp, double *A, int width, int height, char **e
|
|||||||
|
|
||||||
putc('[',fp);
|
putc('[',fp);
|
||||||
|
|
||||||
for (int i = 0; i < height-1; i++)
|
for (int i = 0; i < height-1; i++) {
|
||||||
{
|
|
||||||
for (int j = 0; j < width-1; j++)
|
for (int j = 0; j < width-1; j++)
|
||||||
fprintf(fp, "%f ", A[i*width + j]);
|
fprintf(fp, "%f ", A[i*width + j]);
|
||||||
|
|
||||||
fprintf(fp, "%f, ", A[i*width + width-1]);
|
fprintf(fp, "%f, ", A[i*width + width-1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < width-1; j++)
|
for (int j = 0; j < width-1; j++)
|
||||||
fprintf(fp, "%f ", A[(height-1)*width + j]);
|
fprintf(fp, "%f ", A[(height-1)*width + j]);
|
||||||
|
|
||||||
fprintf(fp, "%f", A[(height-1)*width + width-1]);
|
fprintf(fp, "%f", A[(height-1)*width + width-1]);
|
||||||
|
|
||||||
putc(']',fp);
|
putc(']',fp);
|
||||||
|
|
||||||
@@ -666,17 +627,16 @@ void lina_conv(double *A, double *B, double *C,
|
|||||||
|
|
||||||
// Iterate over each pixel of the result matrix..
|
// Iterate over each pixel of the result matrix..
|
||||||
for(int j = 0; j < Ch; j += 1)
|
for(int j = 0; j < Ch; j += 1)
|
||||||
for(int i = 0; i < Cw; i += 1)
|
for(int i = 0; i < Cw; i += 1) {
|
||||||
{
|
// ..and calculate it's value as
|
||||||
// ..and calculate it's value as
|
// the scalar product between the
|
||||||
// the scalar product between the
|
// mask B and a portion of A.
|
||||||
// mask B and a portion of A.
|
|
||||||
|
|
||||||
C[j * Cw + i] = 0;
|
C[j * Cw + i] = 0;
|
||||||
for(int v = 0; v < Bh; v += 1)
|
for(int v = 0; v < Bh; v += 1)
|
||||||
for(int u = 0; u < Bw; u += 1)
|
for(int u = 0; u < Bw; u += 1)
|
||||||
C[j * Cw + i] += A[(i - Bw/2 + u) * Aw + (i - Bh/2 + v)] * B[v * Bw + u];
|
C[j * Cw + i] += A[(i - Bw/2 + u) * Aw + (i - Bh/2 + v)] * B[v * Bw + u];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lina_reallyP(int *P, double *P2, int n)
|
void lina_reallyP(int *P, double *P2, int n)
|
||||||
|
|||||||
Reference in New Issue
Block a user