2 /*+------- <| --------------------------------------------------------**
4 **--- /.\ -----------------------------------------------------**
5 ** <| [""M# matrix.c **
6 **- A | # -----------------------------------------------------**
7 ** /.\ [""M# First version: 30/04/2008 **
8 **- [""M# | # U"U#U -----------------------------------------------**
11 ****** | "--' .-" ******************************************************
12 * |"-"-"-"-"-#-#-## Clan : the Chunky Loop Analyzer (experimental) *
13 **** | # ## ###### *****************************************************
15 * \ ::::'/ Copyright (C) 2008 Cedric Bastoul *
17 * ::88a ### This is free software; you can redistribute it *
18 * ::::888a 8a ##::. and/or modify it under the terms of the GNU Lesser *
19 * ::::::::888a88a[]::: General Public License as published by the Free *
20 *::8:::::::::SUNDOGa8a::. Software Foundation, either version 2.1 of the *
21 *::::::::8::::888:Y8888:: License, or (at your option) any later version. *
22 *::::':::88::::888::Y88a::::::::::::... *
23 *::'::.. . ..... .. ... . *
24 * This software is distributed in the hope that it will be useful, but *
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
29 * You should have received a copy of the GNU Lesser General Public License *
30 * along with software; if not, write to the Free Software Foundation, Inc., *
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
33 * Clan, the Chunky Loop Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
36 ******************************************************************************/
43 # include <scoplib/matrix.h>
46 /*+****************************************************************************
47 * Structure display function *
48 ******************************************************************************/
52 * scoplib_matrix_print_structure function:
53 * Displays a scoplib_matrix_t structure (*matrix) into a file (file, possibly
54 * stdout) in a way that trends to be understandable without falling in a deep
55 * depression or, for the lucky ones, getting a headache... It includes an
56 * indentation level (level) in order to work with others print_structure
58 * \param file File where informations are printed.
59 * \param matrix The matrix whose information have to be printed.
60 * \param level Number of spaces before printing, for each line.
62 * - 30/04/2008: first version (from CLooG 0.14.0).
65 scoplib_matrix_print_structure(FILE * file
, scoplib_matrix_p matrix
, int level
)
69 /* Go to the right level. */
70 for (j
= 0; j
< level
; j
++)
75 fprintf(file
,"+-- scoplib_matrix_t\n");
77 for(j
= 0; j
<= level
; j
++)
79 fprintf(file
,"%d %d\n",matrix
->NbRows
,matrix
->NbColumns
);
81 /* Display the matrix. */
82 for (i
= 0; i
< matrix
->NbRows
; i
++)
84 for (j
= 0; j
<= level
; j
++)
89 for (j
= 0; j
< matrix
->NbColumns
; j
++)
91 SCOPVAL_print(file
,SCOPLIB_FMT
,matrix
->p
[i
][j
]);
99 fprintf(file
,"+-- NULL matrix\n");
102 for (j
= 0; j
<= level
; j
++)
109 * scoplib_matrix_print function:
110 * This function prints the content of a scoplib_matrix_t structure
111 * (*matrix) into a file (file, possibly stdout).
112 * \param file File where informations are printed.
113 * \param matrix The matrix whose information have to be printed.
115 * - 30/04/2008: first version (from CLooG 0.14.0).
118 scoplib_matrix_print(FILE * file
, scoplib_matrix_p matrix
)
120 scoplib_matrix_print_structure(file
,matrix
,0);
126 * scoplib_matrix_expression_element function:
127 * This function returns a string containing the printing of a value (possibly
128 * an iterator or a parameter with its coefficient or a constant).
129 * \param val The coefficient or constant value.
130 * \param first Pointer to a boolean set to 1 if the current value is the first
131 * of an expresion, 0 otherwise (this function may update it).
132 * \param cst A boolean set to 1 if the value is a constant, 0 otherwise.
133 * \param name String containing the name of the iterator or of the parameter.
135 * - 03/05/2008: first version (from CLooG 0.14.0, glorious pprint_val).
139 scoplib_matrix_expression_element(scoplib_int_t val
, int * first
, int cst
,
142 char * sval
, * body
, * temp
;
144 temp
= (char *)malloc(SCOPLIB_MAX_STRING
* sizeof(char));
145 body
= (char *)malloc(SCOPLIB_MAX_STRING
* sizeof(char));
146 sval
= (char *)malloc(SCOPLIB_MAX_STRING
* sizeof(char));
150 /* statements for the 'normal' processing. */
151 if (SCOPVAL_notzero_p(val
) && (!cst
))
153 if ((*first
) || SCOPVAL_neg_p(val
))
155 if (SCOPVAL_one_p(val
)) /* case 1 */
156 sprintf(sval
,"%s",name
);
159 if (SCOPVAL_mone_p(val
)) /* case -1 */
160 sprintf(sval
,"-%s",name
);
161 else /* default case */
163 SCOPVAL_sprint(sval
,SCOPLIB_FMT_TXT
,val
);
164 sprintf(temp
,"*%s",name
);
172 if (SCOPVAL_one_p(val
))
173 sprintf(sval
,"+%s",name
);
177 SCOPVAL_sprint(temp
,SCOPLIB_FMT_TXT
,val
);
179 sprintf(temp
,"*%s",name
);
188 if ((SCOPVAL_zero_p(val
) && (*first
)) || SCOPVAL_neg_p(val
))
189 SCOPVAL_sprint(sval
,SCOPLIB_FMT_TXT
,val
);
190 if (SCOPVAL_pos_p(val
))
194 SCOPVAL_sprint(sval
,"+"SCOPLIB_FMT_TXT
,val
); /* Block macro ! */
197 SCOPVAL_sprint(sval
,SCOPLIB_FMT_TXT
,val
);
209 * scoplib_matrix_expression function:
210 * This function returns a string corresponding to an affine expression
211 * stored at the "row"^th row of the matrix pointed by "matrix".
212 * \param matrix A set of linear expressions.
213 * \param row The row of the matrix corresponding to the expression.
214 * \param nb_iterators The number of iterators for the considered statement.
215 * \param iterators An array containing iterator names for the statement.
216 * \param nb_parameters The number of parameters in the SCoP.
217 * \param parameters An array containing all parameters names.
219 * - 03/05/2008: first version (from CLooG 0.14.0, glorious pprint_val).
223 scoplib_matrix_expression(scoplib_matrix_p matrix
, int row
,
224 int nb_iterators
, char ** iterators
,
225 int nb_parameters
, char ** parameters
)
228 char * sline
, * sval
;
230 sline
= (char *)malloc(SCOPLIB_MAX_STRING
* sizeof(char)) ;
233 /* First the iterator part. */
234 for (i
= 1; i
<= nb_iterators
; i
++)
236 sval
= scoplib_matrix_expression_element(matrix
->p
[row
][i
],&first
,0,
242 /* Next the parameter part. */
243 for (i
= nb_iterators
+ 1; i
<= nb_iterators
+ nb_parameters
; i
++)
245 sval
= scoplib_matrix_expression_element(matrix
->p
[row
][i
],&first
,0,
246 parameters
[i
- nb_iterators
- 1]);
251 /* Finally the constant part (yes, I reused it). */
252 sval
= scoplib_matrix_expression_element(matrix
->p
[row
][i
],&first
,1,NULL
);
261 * scoplib_matrix_print_dot_scop function:
262 * This function prints the content of a scoplib_matrix_t structure
263 * (*matrix) into a file (file, possibly stdout) for the .scop format.
264 * \param file File where informations are printed.
265 * \param matrix The matrix whose information have to be printed.
266 * \param type A bit of semantic about this matrix (domain, access...).
267 * \param nb_iterators The number of iterators for the considered statement.
268 * \param iterators An array containing iterator names for the statement.
269 * \param nb_parameters The number of parameters in the SCoP.
270 * \param parameters An array containing all parameters names.
271 * \param nb_arrays The number of arrays accessed in the SCoP.
272 * \param arrays An array containing all accessed array names.
274 * - 02/05/2008: first version.
277 scoplib_matrix_print_dot_scop(FILE * file
, scoplib_matrix_p matrix
, int type
,
278 int nb_iterators
, char ** iterators
,
279 int nb_parameters
, char ** parameters
,
280 int nb_arrays
, char ** arrays
)
287 fprintf(file
,"0 %d\n",nb_iterators
+nb_parameters
+2);
291 fprintf(file
,"%d %d\n",matrix
->NbRows
,matrix
->NbColumns
);
293 for (i
= 0; i
< matrix
->NbRows
; i
++)
295 for (j
= 0; j
< matrix
->NbColumns
; j
++)
297 SCOPVAL_print(file
,SCOPLIB_FMT
,matrix
->p
[i
][j
]);
301 if (type
== SCOPLIB_TYPE_DOMAIN
)
303 expression
= scoplib_matrix_expression(matrix
,i
,nb_iterators
,iterators
,
304 nb_parameters
,parameters
);
305 fprintf(file
," ## %s",expression
);
307 if (SCOPVAL_zero_p(matrix
->p
[i
][0]))
308 fprintf(file
," == 0");
310 fprintf(file
," >= 0");
313 if (type
== SCOPLIB_TYPE_SCATTERING
)
315 expression
= scoplib_matrix_expression(matrix
,i
,nb_iterators
,iterators
,
316 nb_parameters
,parameters
);
317 fprintf(file
," ## %s",expression
);
321 if (type
== SCOPLIB_TYPE_ACCESS
)
323 if (SCOPVAL_notzero_p(matrix
->p
[i
][0]))
325 if (strncmp(arrays
[SCOPVAL_get_si(matrix
->p
[i
][0]) - 1],
326 SCOPLIB_FAKE_ARRAY
, strlen(SCOPLIB_FAKE_ARRAY
)))
327 fprintf(file
," ## %s",arrays
[SCOPVAL_get_si(matrix
->p
[i
][0]) - 1]);
331 expression
= scoplib_matrix_expression(matrix
,k
,nb_iterators
,
333 nb_parameters
,parameters
);
334 fprintf(file
,"[%s]",expression
);
338 while ((k
< matrix
->NbRows
) && SCOPVAL_zero_p(matrix
->p
[k
][0]));
350 * scoplib_matrix_list_print_structure function:
351 * Displays a scoplib_matrix_list_t structure (a list of matrices) into a
352 * file (file, possibly stdout). See scoplib_matrix_print_structure for
354 * \param file File where informations are printed.
355 * \param l The list of matrices whose information have to be printed.
356 * \param level Number of spaces before printing, for each line.
359 scoplib_matrix_list_print_structure(FILE * file
, scoplib_matrix_list_p l
,
364 /* Go to the right level. */
365 for (j
= 0; j
< level
; j
++)
369 fprintf(file
,"+-- scoplib_matrix_list_t\n");
371 fprintf(file
,"+-- NULL matrix list\n");
377 /* Go to the right level. */
378 for (j
= 0; j
< level
; j
++)
380 fprintf(file
,"| scoplib_matrix_list_t\n");
386 for (j
= 0; j
<= level
+1; j
++)
390 /* Print a matrix. */
391 scoplib_matrix_print_structure(file
,l
->elt
,level
+1);
398 for (j
= 0; j
<= level
; j
++)
405 for (j
= 0; j
<= level
; j
++)
412 * scoplib_matrix_list_print function:
413 * This function prints the content of a scoplib_matrix_list_t into
414 * a file (file, possibly stdout).
415 * \param file File where informations are printed.
416 * \param list The matrix whose information have to be printed.
418 * - 30/04/2008: first version (from CLooG 0.14.0).
421 scoplib_matrix_list_print(FILE * file
, scoplib_matrix_list_p list
)
423 scoplib_matrix_list_print_structure(file
, list
, 0);
428 * scoplib_matrix_list_print_dot_scop function:
429 * This function prints the content of a scoplib_matrix_list_t structure into
430 * a file (file, possibly stdout) for the .scop format.
431 * \param file File where informations are printed.
432 * \param list The matrix list whose information have to be printed.
433 * \param type A bit of semantic about this matrix (domain, access...).
434 * \param nb_iterators The number of iterators for the considered statement.
435 * \param iterators An array containing iterator names for the statement.
436 * \param nb_parameters The number of parameters in the SCoP.
437 * \param parameters An array containing all parameters names.
438 * \param nb_arrays The number of arrays accessed in the SCoP.
439 * \param arrays An array containing all accessed array names.
442 scoplib_matrix_list_print_dot_scop(FILE * file
, scoplib_matrix_list_p list
,
444 int nb_iterators
, char ** iterators
,
445 int nb_parameters
, char ** parameters
,
446 int nb_arrays
, char ** arrays
)
449 scoplib_matrix_list_p head
= list
;
451 /* Count the number of elements in the list. */
452 for (i
= 0; list
; list
= list
->next
, i
++)
455 fprintf(file
,"%d\n", i
);
456 /* Print each element of the matrix list. */
459 scoplib_matrix_print_dot_scop(file
, head
->elt
, type
,
460 nb_iterators
, iterators
,
461 nb_parameters
, parameters
,
468 /******************************************************************************
470 ******************************************************************************/
474 * scoplib_matrix_read function:
475 * Adaptation from the PolyLib. This function reads a matrix into a file (foo,
476 * posibly stdin) and returns a pointer this matrix.
477 * October 18th 2001: first version.
478 * - April 17th 2005: this function moved from domain.c to here.
479 * - June 21rd 2005: Adaptation for GMP (based on S. Verdoolaege's version of
481 * - July 9th 2008: Grabbed from CLooG and adapted for Scoplib.
484 scoplib_matrix_read(FILE* foo
)
486 unsigned NbRows
, NbColumns
;
488 char* c
, s
[SCOPLIB_MAX_STRING
], str
[SCOPLIB_MAX_STRING
];
489 scoplib_matrix_p matrix
;
492 while (fgets(s
, SCOPLIB_MAX_STRING
, foo
) == 0)
494 while ((*s
=='#' || *s
=='\n') ||
495 (sscanf(s
, " %u %u", &NbRows
, &NbColumns
) < 2))
496 fgets(s
, SCOPLIB_MAX_STRING
, foo
);
498 matrix
= scoplib_matrix_malloc(NbRows
, NbColumns
);
501 for (i
= 0; i
< matrix
->NbRows
; i
++)
505 c
= fgets(s
, SCOPLIB_MAX_STRING
, foo
);
506 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
509 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
513 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
516 for (j
= 0; j
< matrix
->NbColumns
; j
++)
518 if (c
== NULL
|| *c
== '#' || *c
== '\n')
520 fprintf(stderr
, "[Scoplib] Error: not enough columns\n");
523 if (sscanf(c
, "%s%n", str
, &n
) == 0)
525 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
528 #if defined(SCOPLIB_INT_T_IS_MP)
530 sscanf(str
, "%lld", &val
);
531 mpz_set_si(*p
++, val
);
533 sscanf(str
, SCOPLIB_FMT_TXT
, p
++);
544 * scoplib_matrix_list_read function:
545 * This function reads a list of matrices into a file (foo,
546 * posibly stdin) and returns a pointer this matrix list.
547 * \param file File where informations are stored.
549 scoplib_matrix_list_p
550 scoplib_matrix_list_read(FILE* file
)
552 char s
[SCOPLIB_MAX_STRING
];
554 scoplib_matrix_list_p list
;
555 scoplib_matrix_list_p res
;
558 /* Skip blank/commented lines. */
559 while (fgets(s
, SCOPLIB_MAX_STRING
, file
) == 0 || s
[0] == '#' ||
562 /* Read the number of matrices to read. */
563 sscanf(s
, "%d", &nb_mat
);
565 /* Allocate the header of the list. */
566 res
= list
= scoplib_matrix_list_malloc();
567 for (i
= 0; i
< nb_mat
; ++i
)
569 list
->elt
= scoplib_matrix_read(file
);
571 list
->next
= scoplib_matrix_list_malloc();
580 * scoplib_matrix_read_arrays function:
581 * This function reads a matrix into a file (foo, posibly stdin) and
582 * returns a pointer this matrix. In addition, it reads the arrays as
583 * comments at the end of the line.
586 scoplib_matrix_read_arrays(FILE* foo
, char*** arrays
, int* nb_arr
)
588 unsigned NbRows
, NbColumns
;
591 char* c
, s
[SCOPLIB_MAX_STRING
], str
[SCOPLIB_MAX_STRING
],
592 buff
[SCOPLIB_MAX_STRING
];
593 scoplib_matrix_p matrix
;
596 while (fgets(s
, SCOPLIB_MAX_STRING
, foo
) == 0)
598 while ((*s
=='#' || *s
=='\n') ||
599 (sscanf(s
, " %u %u", &NbRows
, &NbColumns
) < 2))
600 fgets(s
, SCOPLIB_MAX_STRING
, foo
);
602 matrix
= scoplib_matrix_malloc(NbRows
, NbColumns
);
605 for (i
= 0; i
< matrix
->NbRows
; i
++)
609 c
= fgets(s
, SCOPLIB_MAX_STRING
, foo
);
610 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
613 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
617 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
621 for (j
= 0; j
< matrix
->NbColumns
; j
++)
623 if (c
== NULL
|| *c
== '#' || *c
== '\n')
625 fprintf(stderr
, "[Scoplib] Error: not enough columns\n");
628 if (sscanf(c
, "%s%n", str
, &n
) == 0)
630 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
633 #if defined(SCOPLIB_INT_T_IS_MP)
635 sscanf(str
, "%lld", &val
);
636 mpz_set_si(*p
++, val
);
638 sscanf(str
, SCOPLIB_FMT_TXT
, p
++);
642 /* Read the array, passed as a comment at the end of the line. */
645 while (c
&& (isspace(*c
) || *c
== '#'))
647 for (count
= 0; c
&& *c
!= '[' && *c
!= '\n'; ++count
)
648 buff
[count
] = *(c
++);
650 if (count
&& SCOPVAL_get_si(matrix
->p
[i
][0]))
652 /* Increase the buffer size if we run out of space. */
653 if (SCOPVAL_get_si(matrix
->p
[i
][0]) - 1 > *nb_arr
)
655 *nb_arr
= SCOPVAL_get_si(matrix
->p
[i
][0]) - 1;
656 *arrays
= (char**) realloc(*arrays
,
657 sizeof(char*) * (*nb_arr
+ 1));
659 /* Backup the array name. */
660 (*arrays
)[SCOPVAL_get_si(matrix
->p
[i
][0]) - 1] = strdup(buff
);
669 /*+****************************************************************************
670 * Memory allocation/deallocation function *
671 ******************************************************************************/
674 * scoplib_matrix_malloc function:
675 * This function allocates the memory space for a scoplib_matrix_t structure and
676 * sets its fields with default values. Then it returns a pointer to the
678 * \param NbRows The number of row of the matrix to allocate.
679 * \param NbColumns The number of columns of the matrix to allocate.
681 * - 30/04/2008: first version (from PipLib 1.4.0).
684 scoplib_matrix_malloc(unsigned NbRows
, unsigned NbColumns
)
686 scoplib_matrix_p matrix
;
687 scoplib_int_t
** p
, * q
;
690 matrix
= (scoplib_matrix_p
)malloc(sizeof(scoplib_matrix_t
));
693 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
696 matrix
->NbRows
= NbRows
;
697 matrix
->NbColumns
= NbColumns
;
698 matrix
->p_Init_size
= NbRows
* NbColumns
;
699 if (matrix
->p_Init_size
== 0)
702 matrix
->p_Init
= NULL
;
706 p
= (scoplib_int_t
**)malloc(NbRows
*sizeof(scoplib_int_t
*));
709 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
712 q
= (scoplib_int_t
*)malloc(NbRows
* NbColumns
* sizeof(scoplib_int_t
));
715 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
720 for (i
= 0; i
< NbRows
; i
++)
723 for (j
= 0; j
< NbColumns
; j
++)
724 SCOPVAL_init_set_si(*(q
+j
),0);
733 * scoplib_matrix_free_inside function:
734 * This function frees the allocated memory for the inside of a
735 * scoplib_matrix_t structure, i.e. only p and p_Init.
736 * \param matrix The pointer to the matrix we want to free.
738 * - 02/05/2008: first version.
741 scoplib_matrix_free_inside(scoplib_matrix_p matrix
)
750 for (i
= 0; i
< matrix
->p_Init_size
; i
++)
753 if (matrix
->p_Init
!= NULL
)
754 free(matrix
->p_Init
);
756 if (matrix
->p
!= NULL
)
762 * scoplib_matrix_free function:
763 * This function frees the allocated memory for a scoplib_matrix_t structure.
764 * \param matrix The pointer to the matrix we want to free.
766 * - 30/04/2008: first version.
767 * - 02/05/2008: now uses scoplib_matrix_free_inside.
770 scoplib_matrix_free(scoplib_matrix_p matrix
)
775 scoplib_matrix_free_inside(matrix
);
781 * scoplib_matrix_list_malloc function:
782 * This function allocates the memory space for a scoplib_matrix_list_t
783 * structure and sets its fields with default values. Then it returns
784 * a pointer to the allocated space.
786 scoplib_matrix_list_p
787 scoplib_matrix_list_malloc()
789 scoplib_matrix_list_p res
=
790 (scoplib_matrix_list_p
) malloc(sizeof(scoplib_matrix_list_t
));
794 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
807 * scoplib_matrix_list_free function:
808 * This function frees the allocated memory for a scoplib_matrix_list_t
809 * structure, and all the matrices stored in the list.
810 * \param list The pointer to the matrix list we want to free.
813 scoplib_matrix_list_free(scoplib_matrix_list_p list
)
815 scoplib_matrix_list_p tmp
;
823 scoplib_matrix_free(list
->elt
);
831 /*+****************************************************************************
832 * Processing functions *
833 ******************************************************************************/
837 * scoplib_matrix_ncopy function:
838 * this functions builds and returns a "hard copy" (not a pointer copy) of a
839 * scoplib_matrix_t data structure such that the copy is restricted to the "n"
840 * first rows of the matrix.
841 * \param matrix The pointer to the matrix we want to copy.
842 * \param n The number of row of the matrix we want to copy.
844 * - 02/05/2008: first version.
847 scoplib_matrix_ncopy(scoplib_matrix_p matrix
, int n
)
850 scoplib_matrix_p copy
;
855 if (n
> matrix
->NbRows
)
857 fprintf(stderr
,"[Scoplib] Error: not enough rows in the matrix\n");
861 copy
= scoplib_matrix_malloc(n
,matrix
->NbColumns
);
863 for (i
= 0; i
< n
; i
++)
864 for (j
= 0; j
< matrix
->NbColumns
; j
++)
865 SCOPVAL_assign(copy
->p
[i
][j
],matrix
->p
[i
][j
]);
872 * scoplib_matrix_copy function:
873 * this functions builds and returns a "hard copy" (not a pointer copy) of a
874 * scoplib_matrix_t data structure.
875 * \param matrix The pointer to the matrix we want to copy.
877 * - 30/04/2008: first version (from CLooG 0.14.0).
878 * - 02/05/2008: no uses scoplib_matrix_ncopy.
881 scoplib_matrix_copy(scoplib_matrix_p matrix
)
886 return scoplib_matrix_ncopy(matrix
,matrix
->NbRows
);
891 * scoplib_matrix_replace_vector function:
892 * this function replaces the "row"^th row of a matrix "matrix" with the
893 * vector "vector". It directly updates "matrix".
894 * \param matrix The matrix we want to change a row.
895 * \param vector The vector that will replace a row of the matrix.
896 * \param row The row of the matrix to be replaced.
898 * - 02/05/2008: first version.
901 scoplib_matrix_replace_vector(scoplib_matrix_p matrix
, scoplib_vector_p vector
,
906 if ((matrix
== NULL
) || (vector
== NULL
) ||
907 (matrix
->NbColumns
!= vector
->Size
) ||
908 (row
>= matrix
->NbRows
) || (row
< 0))
910 fprintf(stderr
,"[Scoplib] Error: vector cannot replace a matrix row\n");
914 for (i
= 0; i
< vector
->Size
; i
++)
915 SCOPVAL_assign(matrix
->p
[row
][i
],vector
->p
[i
]);
920 * scoplib_matrix_add_vector function:
921 * this function adds the "row"^th row of a matrix "matrix" with the
922 * vector "vector". It directly updates "matrix".
923 * \param matrix The matrix we want to change a row.
924 * \param vector The vector that will replace a row of the matrix.
925 * \param row The row of the matrix to be replaced.
927 * - 08/28/2008: first version.
930 scoplib_matrix_add_vector(scoplib_matrix_p matrix
, scoplib_vector_p vector
,
935 if ((matrix
== NULL
) || (vector
== NULL
) ||
936 (matrix
->NbColumns
!= vector
->Size
) ||
937 (row
>= matrix
->NbRows
) || (row
< 0))
939 fprintf(stderr
,"[Scoplib] Error: vector cannot replace a matrix row\n");
943 if (SCOPVAL_get_si(matrix
->p
[row
][0]) == 0)
944 SCOPVAL_assign(matrix
->p
[row
][0],vector
->p
[0]);
945 for (i
= 1; i
< vector
->Size
; i
++)
946 SCOPVAL_addto(matrix
->p
[row
][i
],matrix
->p
[row
][i
],vector
->p
[i
]);
951 * scoplib_matrix_sub_vector function:
952 * this function substracts the vector "vector" to the "row"^th row of
953 * a matrix "matrix. It directly updates "matrix".
954 * \param matrix The matrix we want to change a row.
955 * \param vector The vector that will replace a row of the matrix.
956 * \param row The row of the matrix to be replaced.
958 * - 08/28/2008: first version.
961 scoplib_matrix_sub_vector(scoplib_matrix_p matrix
, scoplib_vector_p vector
,
966 if ((matrix
== NULL
) || (vector
== NULL
) ||
967 (matrix
->NbColumns
!= vector
->Size
) ||
968 (row
>= matrix
->NbRows
) || (row
< 0))
970 fprintf(stderr
,"[Scoplib] Error: vector cannot replace a matrix row\n");
974 if (SCOPVAL_get_si(matrix
->p
[row
][0]) == 0)
975 SCOPVAL_assign(matrix
->p
[row
][0],vector
->p
[0]);
976 for (i
= 1; i
< vector
->Size
; i
++)
977 SCOPVAL_subtract(matrix
->p
[row
][i
],matrix
->p
[row
][i
],vector
->p
[i
]);
982 * scoplib_matrix_insert_vector function:
983 * this function adds a new row corresponding to the vector "vector" to
984 * the matrix "matrix" by inserting it at the "row"^th row. It directly
985 * updates "matrix". If "vector" (or "matrix") is NULL, the matrix is left
987 * \param matrix The matrix we want to extend.
988 * \param vector The vector that will be added matrix.
989 * \param row The row where to insert the vector.
991 * - 02/05/2008: first version.
994 scoplib_matrix_insert_vector(scoplib_matrix_p matrix
, scoplib_vector_p vector
,
998 scoplib_matrix_p
new;
1000 if ((vector
== NULL
) || (matrix
== NULL
))
1003 if ((matrix
->NbColumns
!= vector
->Size
) ||
1004 (row
> matrix
->NbRows
) || (row
< 0))
1006 fprintf(stderr
,"[Scoplib] Error: vector cannot be inserted\n");
1010 /* We use a temporary matrix just to reuse existing functions. Cleaner. */
1011 new = scoplib_matrix_malloc(matrix
->NbRows
+1,matrix
->NbColumns
);
1013 for (i
= 0; i
< row
; i
++)
1014 for (j
= 0; j
< matrix
->NbColumns
; j
++)
1015 SCOPVAL_assign(new->p
[i
][j
],matrix
->p
[i
][j
]);
1017 scoplib_matrix_replace_vector(new,vector
,row
);
1019 for (i
= row
+1; i
< matrix
->NbRows
; i
++)
1020 for (j
= 0; j
< matrix
->NbColumns
; j
++)
1021 SCOPVAL_assign(new->p
[i
][j
],matrix
->p
[i
-1][j
]);
1023 scoplib_matrix_free_inside(matrix
);
1025 /* Replace the inside of matrix */
1026 matrix
->NbRows
= new->NbRows
;
1027 matrix
->NbColumns
= new->NbColumns
;
1029 matrix
->p_Init
= new->p_Init
;
1030 /* Free the new "shell" */
1036 * scoplib_matrix_from_vector function:
1037 * this function converts a vector "vector" to a matrix with a single row
1038 * and returns a pointer to that matrix.
1039 * \param vector The vector to convert to a matrix.
1041 * - 02/05/2008: first version.
1044 scoplib_matrix_from_vector(scoplib_vector_p vector
)
1046 scoplib_matrix_p matrix
;
1051 matrix
= scoplib_matrix_malloc(1,vector
->Size
);
1052 scoplib_matrix_replace_vector(matrix
,vector
,0);
1058 * scoplib_matrix_replace_matrix function:
1059 * this function replaces some rows of a matrix "m1" with the rows of
1060 * the matrix "m2". It begins at the "row"^th row of "m1". It directly
1062 * \param m1 The matrix we want to change some row1.
1063 * \param m2 The matrix containing the new rows.
1064 * \param row The first row of the matrix m1 to be replaced.
1066 * - 02/05/2008: first version.
1069 scoplib_matrix_replace_matrix(scoplib_matrix_p m1
, scoplib_matrix_p m2
, int row
)
1073 if ((m1
== NULL
) || (m2
== NULL
) ||
1074 (m1
->NbColumns
!= m1
->NbColumns
) ||
1075 ((row
+ m2
->NbRows
) > m1
->NbRows
) || (row
< 0))
1077 fprintf(stderr
,"[Scoplib] Error: vector cannot replace a matrix row\n");
1081 for (i
= 0; i
< m2
->NbRows
; i
++)
1082 for (j
= 0; j
< m2
->NbColumns
; j
++)
1083 SCOPVAL_assign(m1
->p
[i
+row
][j
],m2
->p
[i
][j
]);
1088 * scoplib_matrix_insert_matrix function:
1089 * this function adds new rows corresponding to the matrix "m1" to
1090 * the matrix "m2" by inserting it at the "row"^th row. It directly
1091 * updates "m1". If "m2" (or "m1") is NULL, the matrix is left
1093 * \param m1 The matrix we want to extend.
1094 * \param m2 The matrix to be inserted.
1095 * \param row The row where to insert the matrix
1097 * - 02/05/2008: first version.
1100 scoplib_matrix_insert_matrix(scoplib_matrix_p m1
, scoplib_matrix_p m2
, int row
)
1103 scoplib_matrix_p
new;
1105 if ((m1
== NULL
) || (m2
== NULL
))
1108 if ((m1
->NbColumns
!= m2
->NbColumns
) ||
1109 (row
> m1
->NbRows
) || (row
< 0))
1111 fprintf(stderr
,"[Scoplib] Error: matrix cannot be inserted\n");
1115 /* We use a temporary matrix just to reuse existing functions. Cleaner. */
1116 new = scoplib_matrix_malloc(m1
->NbRows
+m2
->NbRows
,m1
->NbColumns
);
1118 for (i
= 0; i
< row
; i
++)
1119 for (j
= 0; j
< m1
->NbColumns
; j
++)
1120 SCOPVAL_assign(new->p
[i
][j
],m1
->p
[i
][j
]);
1122 scoplib_matrix_replace_matrix(new,m2
,row
);
1124 for (i
= row
+ m2
->NbRows
; i
< m1
->NbRows
; i
++)
1125 for (j
= 0; j
< m1
->NbColumns
; j
++)
1126 SCOPVAL_assign(new->p
[i
][j
],m1
->p
[i
-m2
->NbRows
][j
]);
1128 scoplib_matrix_free_inside(m1
);
1130 /* Replace the inside of matrix */
1131 m1
->NbRows
= new->NbRows
;
1132 m1
->NbColumns
= new->NbColumns
;
1134 m1
->p_Init
= new->p_Init
;
1136 /* Free the new "container" */
1142 * scoplib_matrix_concat function:
1143 * this function builds a new matrix as the concatenation of the rows of
1144 * two other matrices sent as parameters.
1145 * \param m1 The first matrix.
1146 * \param m2 The second matrix.
1148 * - 02/05/2008: first version.
1151 scoplib_matrix_concat(scoplib_matrix_p m1
, scoplib_matrix_p m2
)
1153 scoplib_matrix_p
new;
1156 return scoplib_matrix_copy(m2
);
1159 return scoplib_matrix_copy(m1
);
1161 if (m1
->NbColumns
!= m2
->NbColumns
)
1163 fprintf(stderr
,"[Scoplib] Error: matrices cannot be concatenated\n");
1167 new = scoplib_matrix_malloc(m1
->NbRows
+m2
->NbRows
,m1
->NbColumns
);
1168 scoplib_matrix_replace_matrix(new,m1
,0);
1169 scoplib_matrix_replace_matrix(new,m2
,m1
->NbRows
);
1176 * scoplib_matrix_equal function:
1177 * this function returns true if the two matrices are the same, false
1179 * \param m1 The first matrix.
1180 * \param m2 The second matrix.
1184 scoplib_matrix_equal(scoplib_matrix_p m1
, scoplib_matrix_p m2
)
1188 if (m1
== NULL
|| m2
== NULL
)
1190 if (m1
->NbRows
!= m2
->NbRows
|| m1
->NbColumns
!= m2
->NbColumns
)
1193 for (i
= 0; i
< m1
->NbRows
; ++i
)
1194 for (j
= 0; j
< m1
->NbColumns
; ++j
)
1195 if (SCOPVAL_ne(m1
->p
[i
][j
], m2
->p
[i
][j
]))