Formatting
[openscop.git] / source / matrix.c
blob05e7d6c8d098201dc39038fc8a0eb0548f2fc6c3
2 /*+-----------------------------------------------------------------**
3 ** OpenScop Library **
4 **-----------------------------------------------------------------**
5 ** matrix.c **
6 **-----------------------------------------------------------------**
7 ** First version: 30/04/2008 **
8 **-----------------------------------------------------------------**
11 *****************************************************************************
12 * OpenScop: Structures and formats for polyhedral tools to talk together *
13 *****************************************************************************
14 * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, *
15 * / / / // // // // / / / // // / / // / /|,_, *
16 * / / / // // // // / / / // // / / // / / / /\ *
17 * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ *
18 * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ *
19 * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ *
20 * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ *
21 * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ *
22 * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ *
23 * | I | | | | e | | | | | | | | | | | | | \ \ \ *
24 * | T | | | | | | | | | | | | | | | | | \ \ \ *
25 * | E | | | | | | | | | | | | | | | | | \ \ \ *
26 * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ *
27 * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / *
28 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
29 * *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
31 * *
32 * (3-clause BSD license) *
33 * Redistribution and use in source and binary forms, with or without *
34 * modification, are permitted provided that the following conditions *
35 * are met: *
36 * *
37 * 1. Redistributions of source code must retain the above copyright notice, *
38 * this list of conditions and the following disclaimer. *
39 * 2. Redistributions in binary form must reproduce the above copyright *
40 * notice, this list of conditions and the following disclaimer in the *
41 * documentation and/or other materials provided with the distribution. *
42 * 3. The name of the author may not be used to endorse or promote products *
43 * derived from this software without specific prior written permission. *
44 * *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
55 * *
56 * OpenScop Library, a library to manipulate OpenScop formats and data *
57 * structures. Written by: *
58 * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and *
59 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> *
60 * *
61 *****************************************************************************/
64 # include <stdlib.h>
65 # include <stdio.h>
66 # include <string.h>
67 # include <ctype.h>
68 # include <openscop/matrix.h>
71 /*+***************************************************************************
72 * Structure display function *
73 *****************************************************************************/
76 /**
77 * openscop_matrix_print_structure function:
78 * Displays a openscop_matrix_t structure (*matrix) into a file (file, possibly
79 * stdout) in a way that trends to be understandable without falling in a deep
80 * depression or, for the lucky ones, getting a headache... It includes an
81 * indentation level (level) in order to work with others print_structure
82 * functions.
83 * \param file File where informations are printed.
84 * \param matrix The matrix whose information have to be printed.
85 * \param level Number of spaces before printing, for each line.
87 void
88 openscop_matrix_print_structure(FILE * file, openscop_matrix_p matrix,
89 int level)
91 int i, j;
93 /* Go to the right level. */
94 for (j = 0; j < level; j++)
95 fprintf(file,"|\t");
97 if (matrix != NULL)
99 fprintf(file,"+-- openscop_matrix_t\n");
101 for(j = 0; j <= level; j++)
102 fprintf(file,"|\t");
103 fprintf(file,"%d %d\n",matrix->NbRows,matrix->NbColumns);
105 /* Display the matrix. */
106 for (i = 0; i < matrix->NbRows; i++)
108 for (j = 0; j <= level; j++)
109 fprintf(file,"|\t");
111 fprintf(file,"[ ");
113 for (j = 0; j < matrix->NbColumns; j++)
115 SCOPINT_print(file,OPENSCOP_FMT,matrix->p[i][j]);
116 fprintf(file," ");
119 fprintf(file,"]\n");
122 else
123 fprintf(file,"+-- NULL matrix\n");
125 /* The last line. */
126 for (j = 0; j <= level; j++)
127 fprintf(file,"|\t");
128 fprintf(file,"\n");
133 * openscop_matrix_print function:
134 * This function prints the content of a openscop_matrix_t structure
135 * (*matrix) into a file (file, possibly stdout).
136 * \param file File where informations are printed.
137 * \param matrix The matrix whose information have to be printed.
139 void
140 openscop_matrix_print(FILE * file, openscop_matrix_p matrix)
142 openscop_matrix_print_structure(file,matrix,0);
148 * openscop_matrix_expression_element function:
149 * This function returns a string containing the printing of a value (possibly
150 * an iterator or a parameter with its coefficient or a constant).
151 * \param val The coefficient or constant value.
152 * \param first Pointer to a boolean set to 1 if the current value is the first
153 * of an expresion, 0 otherwise (this function may update it).
154 * \param cst A boolean set to 1 if the value is a constant, 0 otherwise.
155 * \param name String containing the name of the iterator or of the parameter.
157 static
158 char *
159 openscop_matrix_expression_element(openscop_int_t val, int * first, int cst,
160 char * name)
162 char * sval, * body, * temp;
164 temp = (char *)malloc(OPENSCOP_MAX_STRING * sizeof(char));
165 body = (char *)malloc(OPENSCOP_MAX_STRING * sizeof(char));
166 sval = (char *)malloc(OPENSCOP_MAX_STRING * sizeof(char));
167 body[0] = '\0';
168 sval[0] = '\0';
170 /* statements for the 'normal' processing. */
171 if (SCOPINT_notzero_p(val) && (!cst))
173 if ((*first) || SCOPINT_neg_p(val))
175 if (SCOPINT_one_p(val)) /* case 1 */
176 sprintf(sval,"%s",name);
177 else
179 if (SCOPINT_mone_p(val)) /* case -1 */
180 sprintf(sval,"-%s",name);
181 else /* default case */
183 SCOPINT_sprint(sval,OPENSCOP_FMT_TXT,val);
184 sprintf(temp,"*%s",name);
185 strcat(sval,temp);
188 *first = 0;
190 else
192 if (SCOPINT_one_p(val))
193 sprintf(sval,"+%s",name);
194 else
196 sprintf(sval,"+");
197 SCOPINT_sprint(temp,OPENSCOP_FMT_TXT,val);
198 strcat(sval,temp);
199 sprintf(temp,"*%s",name);
200 strcat(sval,temp);
204 else
206 if (cst)
208 if ((SCOPINT_zero_p(val) && (*first)) || SCOPINT_neg_p(val))
209 SCOPINT_sprint(sval,OPENSCOP_FMT_TXT,val);
210 if (SCOPINT_pos_p(val))
212 if (!(*first))
214 SCOPINT_sprint(sval,"+"OPENSCOP_FMT_TXT,val); /* Block macro ! */
216 else
217 SCOPINT_sprint(sval,OPENSCOP_FMT_TXT,val);
221 free(temp);
222 free(body);
224 return(sval);
229 * openscop_matrix_expression function:
230 * This function returns a string corresponding to an affine expression
231 * stored at the "row"^th row of the matrix pointed by "matrix".
232 * \param matrix A set of linear expressions.
233 * \param row The row of the matrix corresponding to the expression.
234 * \param nb_iterators The number of iterators for the considered statement.
235 * \param iterators An array containing iterator names for the statement.
236 * \param nb_parameters The number of parameters in the SCoP.
237 * \param parameters An array containing all parameters names.
239 static
240 char *
241 openscop_matrix_expression(openscop_matrix_p matrix, int row,
242 int nb_iterators, char ** iterators,
243 int nb_parameters, char ** parameters)
245 int i, first = 1;
246 char * sline, * sval;
248 sline = (char *)malloc(OPENSCOP_MAX_STRING * sizeof(char)) ;
249 sline[0] = '\0' ;
251 /* First the iterator part. */
252 for (i = 1; i <= nb_iterators; i++)
254 sval = openscop_matrix_expression_element(matrix->p[row][i],&first,0,
255 iterators[i-1]);
256 strcat(sline,sval);
257 free(sval);
260 /* Next the parameter part. */
261 for (i = nb_iterators + 1; i <= nb_iterators + nb_parameters; i++)
263 sval = openscop_matrix_expression_element(matrix->p[row][i],&first,0,
264 parameters[i - nb_iterators - 1]);
265 strcat(sline,sval);
266 free(sval);
269 /* Finally the constant part (yes, I reused it). */
270 sval = openscop_matrix_expression_element(matrix->p[row][i],&first,1,NULL);
271 strcat(sline,sval);
272 free(sval);
274 return sline;
279 * openscop_matrix_print_dot_scop function:
280 * This function prints the content of a openscop_matrix_t structure
281 * (*matrix) into a file (file, possibly stdout) for the .scop format.
282 * \param file File where informations are printed.
283 * \param matrix The matrix whose information have to be printed.
284 * \param type Semantic about this matrix (domain, access...).
285 * \param nb_iterators The number of iterators for the considered statement.
286 * \param iterators An array containing iterator names for the statement.
287 * \param nb_parameters The number of parameters in the SCoP.
288 * \param parameters An array containing all parameters names.
289 * \param nb_arrays The number of arrays accessed in the SCoP.
290 * \param arrays An array containing all accessed array names.
292 void
293 openscop_matrix_print_dot_scop(FILE * file, openscop_matrix_p matrix, int type,
294 int nb_iterators, char ** iterators,
295 int nb_parameters, char ** parameters,
296 int nb_arrays, char ** arrays)
298 int i, j, k;
299 char * expression;
301 if (matrix == NULL)
303 fprintf(file,"0 %d\n",nb_iterators+nb_parameters+2);
304 return;
307 fprintf(file,"%d %d\n",matrix->NbRows,matrix->NbColumns);
309 for (i = 0; i < matrix->NbRows; i++)
311 for (j = 0; j < matrix->NbColumns; j++)
313 SCOPINT_print(file,OPENSCOP_FMT,matrix->p[i][j]);
314 fprintf(file," ");
317 if (type == OPENSCOP_TYPE_DOMAIN)
319 expression = openscop_matrix_expression(matrix,i,nb_iterators,iterators,
320 nb_parameters,parameters);
321 fprintf(file," ## %s",expression);
322 free(expression);
323 if (SCOPINT_zero_p(matrix->p[i][0]))
324 fprintf(file," == 0");
325 else
326 fprintf(file," >= 0");
329 if (type == OPENSCOP_TYPE_SCATTERING)
331 expression = openscop_matrix_expression(matrix,i,nb_iterators,iterators,
332 nb_parameters,parameters);
333 fprintf(file," ## %s",expression);
334 free(expression);
337 if (type == OPENSCOP_TYPE_ACCESS)
339 if (SCOPINT_notzero_p(matrix->p[i][0]))
341 if (strncmp(arrays[SCOPINT_get_si(matrix->p[i][0]) - 1],
342 OPENSCOP_FAKE_ARRAY, strlen(OPENSCOP_FAKE_ARRAY)))
343 fprintf(file," ## %s",arrays[SCOPINT_get_si(matrix->p[i][0]) - 1]);
344 k = i;
347 expression = openscop_matrix_expression(matrix,k,nb_iterators,
348 iterators,
349 nb_parameters,parameters);
350 fprintf(file,"[%s]",expression);
351 free(expression);
352 k++;
354 while ((k < matrix->NbRows) && SCOPINT_zero_p(matrix->p[k][0]));
356 else
357 fprintf(file," ##");
360 fprintf(file,"\n");
365 /*****************************************************************************
366 * Reading function *
367 *****************************************************************************/
371 * openscop_matrix_read function:
372 * Adaptation from the PolyLib. This function reads a matrix into a file (foo,
373 * posibly stdin) and returns a pointer this matrix.
375 openscop_matrix_p
376 openscop_matrix_read(FILE* foo)
378 unsigned NbRows, NbColumns;
379 int i, j, n;
380 char* c, s[OPENSCOP_MAX_STRING], str[OPENSCOP_MAX_STRING];
381 openscop_matrix_p matrix;
382 openscop_int_t* p;
384 while (fgets(s, OPENSCOP_MAX_STRING, foo) == 0)
386 while ((*s=='#' || *s=='\n') ||
387 (sscanf(s, " %u %u", &NbRows, &NbColumns) < 2))
388 fgets(s, OPENSCOP_MAX_STRING, foo);
390 matrix = openscop_matrix_malloc(NbRows, NbColumns);
392 p = matrix->p_Init;
393 for (i = 0; i < matrix->NbRows; i++)
397 c = fgets(s, OPENSCOP_MAX_STRING, foo);
398 while ((c != NULL) && isspace(*c) && (*c != '\n'))
399 c++;
401 while (c != NULL && (*c == '#' || *c == '\n'));
403 if (c == NULL)
405 fprintf(stderr, "[Scoplib] Error: not enough rows\n");
406 exit(1);
408 for (j = 0; j < matrix->NbColumns; j++)
410 if (c == NULL || *c == '#' || *c == '\n')
412 fprintf(stderr, "[Scoplib] Error: not enough columns\n");
413 exit(1);
415 if (sscanf(c, "%s%n", str, &n) == 0)
417 fprintf(stderr, "[Scoplib] Error: not enough rows\n");
418 exit(1);
420 #if defined(OPENSCOP_INT_T_IS_MP)
421 long long val;
422 sscanf(str, "%lld", &val);
423 mpz_set_si(*p++, val);
424 #else
425 sscanf(str, OPENSCOP_FMT_TXT, p++);
426 #endif
427 c += n;
431 return matrix;
436 * openscop_matrix_read_arrays function:
437 * This function reads a matrix into a file (foo, posibly stdin) and
438 * returns a pointer this matrix. In addition, it reads the arrays as
439 * comments at the end of the line.
441 openscop_matrix_p
442 openscop_matrix_read_arrays(FILE* foo, char*** arrays, int* nb_arr)
444 unsigned NbRows, NbColumns;
445 int i, j, n;
446 int count;
447 char* c, s[OPENSCOP_MAX_STRING], str[OPENSCOP_MAX_STRING],
448 buff[OPENSCOP_MAX_STRING];
449 openscop_matrix_p matrix;
450 openscop_int_t* p;
452 while (fgets(s, OPENSCOP_MAX_STRING, foo) == 0)
454 while ((*s=='#' || *s=='\n') ||
455 (sscanf(s, " %u %u", &NbRows, &NbColumns) < 2))
456 fgets(s, OPENSCOP_MAX_STRING, foo);
458 matrix = openscop_matrix_malloc(NbRows, NbColumns);
460 p = matrix->p_Init;
461 for (i = 0; i < matrix->NbRows; i++)
465 c = fgets(s, OPENSCOP_MAX_STRING, foo);
466 while ((c != NULL) && isspace(*c) && (*c != '\n'))
467 c++;
469 while (c != NULL && (*c == '#' || *c == '\n'));
471 if (c == NULL)
473 fprintf(stderr, "[Scoplib] Error: not enough rows\n");
474 exit(1);
477 for (j = 0; j < matrix->NbColumns; j++)
479 if (c == NULL || *c == '#' || *c == '\n')
481 fprintf(stderr, "[Scoplib] Error: not enough columns\n");
482 exit(1);
484 if (sscanf(c, "%s%n", str, &n) == 0)
486 fprintf(stderr, "[Scoplib] Error: not enough rows\n");
487 exit(1);
489 #if defined(OPENSCOP_INT_T_IS_MP)
490 long long val;
491 sscanf(str, "%lld", &val);
492 mpz_set_si(*p++, val);
493 #else
494 sscanf(str, OPENSCOP_FMT_TXT, p++);
495 #endif
496 c += n;
498 /* Read the array, passed as a comment at the end of the line. */
499 if (c)
501 while (c && (isspace(*c) || *c == '#'))
502 ++c;
503 for (count = 0; c && *c != '[' && *c != '\n'; ++count)
504 buff[count] = *(c++);
505 buff[count] = '\0';
506 if (count && SCOPINT_get_si(matrix->p[i][0]))
508 /* Increase the buffer size if we run out of space. */
509 if (SCOPINT_get_si(matrix->p[i][0]) - 1 > *nb_arr)
511 *nb_arr = SCOPINT_get_si(matrix->p[i][0]) - 1;
512 *arrays = (char**) realloc(*arrays,
513 sizeof(char*) * (*nb_arr + 1));
515 /* Backup the array name. */
516 (*arrays)[SCOPINT_get_si(matrix->p[i][0]) - 1] = strdup(buff);
521 return matrix;
525 /*+****************************************************************************
526 * Memory allocation/deallocation function *
527 ******************************************************************************/
530 * openscop_matrix_malloc function:
531 * This function allocates the memory space for a openscop_matrix_t structure and
532 * sets its fields with default values. Then it returns a pointer to the
533 * allocated space.
534 * \param NbRows The number of row of the matrix to allocate.
535 * \param NbColumns The number of columns of the matrix to allocate.
537 openscop_matrix_p
538 openscop_matrix_malloc(unsigned NbRows, unsigned NbColumns)
540 openscop_matrix_p matrix;
541 openscop_int_t ** p, * q;
542 int i, j;
544 matrix = (openscop_matrix_p)malloc(sizeof(openscop_matrix_t));
545 if (matrix == NULL)
547 fprintf(stderr, "[Scoplib] Memory Overflow.\n");
548 exit(1);
550 matrix->NbRows = NbRows;
551 matrix->NbColumns = NbColumns;
552 matrix->p_Init_size = NbRows * NbColumns;
553 if (matrix->p_Init_size == 0)
555 matrix->p = NULL;
556 matrix->p_Init = NULL;
558 else
560 p = (openscop_int_t **)malloc(NbRows*sizeof(openscop_int_t *));
561 if (p == NULL)
563 fprintf(stderr, "[Scoplib] Memory Overflow.\n");
564 exit(1);
566 q = (openscop_int_t *)malloc(NbRows * NbColumns * sizeof(openscop_int_t));
567 if (q == NULL)
569 fprintf(stderr, "[Scoplib] Memory Overflow.\n");
570 exit(1);
572 matrix->p = p;
573 matrix->p_Init = q;
574 for (i = 0; i < NbRows; i++)
576 *p++ = q;
577 for (j = 0; j < NbColumns; j++)
578 SCOPINT_init_set_si(*(q+j),0);
579 q += NbColumns;
582 return matrix;
587 * openscop_matrix_free_inside function:
588 * This function frees the allocated memory for the inside of a
589 * openscop_matrix_t structure, i.e. only p and p_Init.
590 * \param matrix The pointer to the matrix we want to free.
592 void
593 openscop_matrix_free_inside(openscop_matrix_p matrix)
595 int i;
596 openscop_int_t * p;
598 if (matrix == NULL)
599 return;
601 p = matrix->p_Init;
602 for (i = 0; i < matrix->p_Init_size; i++)
603 SCOPINT_clear(*p++);
605 if (matrix->p_Init != NULL)
606 free(matrix->p_Init);
608 if (matrix->p != NULL)
609 free(matrix->p);
614 * openscop_matrix_free function:
615 * This function frees the allocated memory for a openscop_matrix_t structure.
616 * \param matrix The pointer to the matrix we want to free.
618 void
619 openscop_matrix_free(openscop_matrix_p matrix)
621 if (matrix == NULL)
622 return;
624 openscop_matrix_free_inside(matrix);
625 free(matrix);
629 /*+****************************************************************************
630 * Processing functions *
631 ******************************************************************************/
635 * openscop_matrix_ncopy function:
636 * this functions builds and returns a "hard copy" (not a pointer copy) of a
637 * openscop_matrix_t data structure such that the copy is restricted to the "n"
638 * first rows of the matrix.
639 * \param matrix The pointer to the matrix we want to copy.
640 * \param n The number of row of the matrix we want to copy.
642 openscop_matrix_p
643 openscop_matrix_ncopy(openscop_matrix_p matrix, int n)
645 int i, j;
646 openscop_matrix_p copy;
648 if (matrix == NULL)
649 return NULL;
651 if (n > matrix->NbRows)
653 fprintf(stderr,"[Scoplib] Error: not enough rows in the matrix\n");
654 exit(1);
657 copy = openscop_matrix_malloc(n,matrix->NbColumns);
659 for (i = 0; i < n; i++)
660 for (j = 0; j < matrix->NbColumns; j++)
661 SCOPINT_assign(copy->p[i][j],matrix->p[i][j]);
663 return copy;
668 * openscop_matrix_copy function:
669 * this function builds and returns a "hard copy" (not a pointer copy) of a
670 * openscop_matrix_t data structure.
671 * \param matrix The pointer to the matrix we want to copy.
673 openscop_matrix_p
674 openscop_matrix_copy(openscop_matrix_p matrix)
676 if (matrix == NULL)
677 return NULL;
679 return openscop_matrix_ncopy(matrix,matrix->NbRows);
684 * openscop_matrix_replace_vector function:
685 * this function replaces the "row"^th row of a matrix "matrix" with the
686 * vector "vector". It directly updates "matrix".
687 * \param matrix The matrix we want to change a row.
688 * \param vector The vector that will replace a row of the matrix.
689 * \param row The row of the matrix to be replaced.
691 void
692 openscop_matrix_replace_vector(openscop_matrix_p matrix,
693 openscop_vector_p vector, int row)
695 int i;
697 if ((matrix == NULL) || (vector == NULL) ||
698 (matrix->NbColumns != vector->Size) ||
699 (row >= matrix->NbRows) || (row < 0))
701 fprintf(stderr,"[Scoplib] Error: vector cannot replace a matrix row\n");
702 exit(1);
705 for (i = 0; i < vector->Size; i++)
706 SCOPINT_assign(matrix->p[row][i],vector->p[i]);
711 * openscop_matrix_add_vector function:
712 * this function adds the "row"^th row of a matrix "matrix" with the
713 * vector "vector". It directly updates "matrix".
714 * \param matrix The matrix we want to change a row.
715 * \param vector The vector that will replace a row of the matrix.
716 * \param row The row of the matrix to be replaced.
718 void
719 openscop_matrix_add_vector(openscop_matrix_p matrix, openscop_vector_p vector,
720 int row)
722 int i;
724 if ((matrix == NULL) || (vector == NULL) ||
725 (matrix->NbColumns != vector->Size) ||
726 (row >= matrix->NbRows) || (row < 0))
728 fprintf(stderr,"[Scoplib] Error: vector cannot replace a matrix row\n");
729 exit(1);
732 if (SCOPINT_get_si(matrix->p[row][0]) == 0)
733 SCOPINT_assign(matrix->p[row][0],vector->p[0]);
734 for (i = 1; i < vector->Size; i++)
735 SCOPINT_addto(matrix->p[row][i],matrix->p[row][i],vector->p[i]);
740 * openscop_matrix_sub_vector function:
741 * this function substracts the vector "vector" to the "row"^th row of
742 * a matrix "matrix. It directly updates "matrix".
743 * \param matrix The matrix we want to change a row.
744 * \param vector The vector that will replace a row of the matrix.
745 * \param row The row of the matrix to be replaced.
747 void
748 openscop_matrix_sub_vector(openscop_matrix_p matrix, openscop_vector_p vector,
749 int row)
751 int i;
753 if ((matrix == NULL) || (vector == NULL) ||
754 (matrix->NbColumns != vector->Size) ||
755 (row >= matrix->NbRows) || (row < 0))
757 fprintf(stderr,"[Scoplib] Error: vector cannot replace a matrix row\n");
758 exit(1);
761 if (SCOPINT_get_si(matrix->p[row][0]) == 0)
762 SCOPINT_assign(matrix->p[row][0],vector->p[0]);
763 for (i = 1; i < vector->Size; i++)
764 SCOPINT_subtract(matrix->p[row][i],matrix->p[row][i],vector->p[i]);
769 * openscop_matrix_insert_vector function:
770 * this function adds a new row corresponding to the vector "vector" to
771 * the matrix "matrix" by inserting it at the "row"^th row. It directly
772 * updates "matrix". If "vector" (or "matrix") is NULL, the matrix is left
773 * unmodified.
774 * \param matrix The matrix we want to extend.
775 * \param vector The vector that will be added matrix.
776 * \param row The row where to insert the vector.
778 void
779 openscop_matrix_insert_vector(openscop_matrix_p matrix, openscop_vector_p vector,
780 int row)
782 int i, j;
783 openscop_matrix_p new;
785 if ((vector == NULL) || (matrix == NULL))
786 return;
788 if ((matrix->NbColumns != vector->Size) ||
789 (row > matrix->NbRows) || (row < 0))
791 fprintf(stderr,"[Scoplib] Error: vector cannot be inserted\n");
792 exit(1);
795 /* We use a temporary matrix just to reuse existing functions. Cleaner. */
796 new = openscop_matrix_malloc(matrix->NbRows+1,matrix->NbColumns);
798 for (i = 0; i < row; i++)
799 for (j = 0; j < matrix->NbColumns; j++)
800 SCOPINT_assign(new->p[i][j],matrix->p[i][j]);
802 openscop_matrix_replace_vector(new,vector,row);
804 for (i = row+1; i < matrix->NbRows; i++)
805 for (j = 0; j < matrix->NbColumns; j++)
806 SCOPINT_assign(new->p[i][j],matrix->p[i-1][j]);
808 openscop_matrix_free_inside(matrix);
810 /* Replace the inside of matrix */
811 matrix->NbRows = new->NbRows;
812 matrix->NbColumns = new->NbColumns;
813 matrix->p = new->p;
814 matrix->p_Init = new->p_Init;
815 /* Free the new "shell" */
816 free(new);
821 * openscop_matrix_from_vector function:
822 * this function converts a vector "vector" to a matrix with a single row
823 * and returns a pointer to that matrix.
824 * \param vector The vector to convert to a matrix.
826 openscop_matrix_p
827 openscop_matrix_from_vector(openscop_vector_p vector)
829 openscop_matrix_p matrix;
831 if (vector == NULL)
832 return NULL;
834 matrix = openscop_matrix_malloc(1,vector->Size);
835 openscop_matrix_replace_vector(matrix,vector,0);
836 return matrix;
841 * openscop_matrix_replace_matrix function:
842 * this function replaces some rows of a matrix "m1" with the rows of
843 * the matrix "m2". It begins at the "row"^th row of "m1". It directly
844 * updates "m1".
845 * \param m1 The matrix we want to change some row1.
846 * \param m2 The matrix containing the new rows.
847 * \param row The first row of the matrix m1 to be replaced.
849 void
850 openscop_matrix_replace_matrix(openscop_matrix_p m1, openscop_matrix_p m2, int row)
852 int i, j;
854 if ((m1 == NULL) || (m2 == NULL) ||
855 (m1->NbColumns != m1->NbColumns) ||
856 ((row + m2->NbRows) > m1->NbRows) || (row < 0))
858 fprintf(stderr,"[Scoplib] Error: vector cannot replace a matrix row\n");
859 exit(1);
862 for (i = 0; i < m2->NbRows; i++)
863 for (j = 0; j < m2->NbColumns; j++)
864 SCOPINT_assign(m1->p[i+row][j],m2->p[i][j]);
869 * openscop_matrix_insert_matrix function:
870 * this function adds new rows corresponding to the matrix "m1" to
871 * the matrix "m2" by inserting it at the "row"^th row. It directly
872 * updates "m1". If "m2" (or "m1") is NULL, the matrix is left
873 * unmodified.
874 * \param m1 The matrix we want to extend.
875 * \param m2 The matrix to be inserted.
876 * \param row The row where to insert the matrix
878 void
879 openscop_matrix_insert_matrix(openscop_matrix_p m1, openscop_matrix_p m2, int row)
881 int i, j;
882 openscop_matrix_p new;
884 if ((m1 == NULL) || (m2 == NULL))
885 return;
887 if ((m1->NbColumns != m2->NbColumns) ||
888 (row > m1->NbRows) || (row < 0))
890 fprintf(stderr,"[Scoplib] Error: matrix cannot be inserted\n");
891 exit(1);
894 /* We use a temporary matrix just to reuse existing functions. Cleaner. */
895 new = openscop_matrix_malloc(m1->NbRows+m2->NbRows,m1->NbColumns);
897 for (i = 0; i < row; i++)
898 for (j = 0; j < m1->NbColumns; j++)
899 SCOPINT_assign(new->p[i][j],m1->p[i][j]);
901 openscop_matrix_replace_matrix(new,m2,row);
903 for (i = row + m2->NbRows; i < m1->NbRows; i++)
904 for (j = 0; j < m1->NbColumns; j++)
905 SCOPINT_assign(new->p[i][j],m1->p[i-m2->NbRows][j]);
907 openscop_matrix_free_inside(m1);
909 /* Replace the inside of matrix */
910 m1->NbRows = new->NbRows;
911 m1->NbColumns = new->NbColumns;
912 m1->p = new->p;
913 m1->p_Init = new->p_Init;
915 /* Free the new "container" */
916 free(new);
921 * openscop_matrix_concat function:
922 * this function builds a new matrix as the concatenation of the rows of
923 * two other matrices sent as parameters.
924 * \param m1 The first matrix.
925 * \param m2 The second matrix.
927 openscop_matrix_p
928 openscop_matrix_concat(openscop_matrix_p m1, openscop_matrix_p m2)
930 openscop_matrix_p new;
932 if (m1 == NULL)
933 return openscop_matrix_copy(m2);
935 if (m2 == NULL)
936 return openscop_matrix_copy(m1);
938 if (m1->NbColumns != m2->NbColumns)
940 fprintf(stderr,"[Scoplib] Error: matrices cannot be concatenated\n");
941 exit(1);
944 new = openscop_matrix_malloc(m1->NbRows+m2->NbRows,m1->NbColumns);
945 openscop_matrix_replace_matrix(new,m1,0);
946 openscop_matrix_replace_matrix(new,m2,m1->NbRows);
948 return new;
953 * openscop_matrix_equal function:
954 * this function returns true if the two matrices are the same, false
955 * otherwise.
956 * \param m1 The first matrix.
957 * \param m2 The second matrix.
958 * \return 1 if m1 and m2 are the same (content-wise), 0 otherwise.
961 openscop_matrix_equal(openscop_matrix_p m1, openscop_matrix_p m2)
963 if (m1 == m2)
964 return 1;
965 if (m1 == NULL || m2 == NULL)
966 return 0;
967 if (m1->NbRows != m2->NbRows || m1->NbColumns != m2->NbColumns)
968 return 0;
969 int i, j;
970 for (i = 0; i < m1->NbRows; ++i)
971 for (j = 0; j < m1->NbColumns; ++j)
972 if (SCOPINT_ne(m1->p[i][j], m2->p[i][j]))
973 return 0;
974 return 1;