2 /*+-----------------------------------------------------------------**
4 **-----------------------------------------------------------------**
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 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
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 *
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. *
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. *
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> *
61 *****************************************************************************/
68 # include <openscop/matrix.h>
71 /*+***************************************************************************
72 * Structure display function *
73 *****************************************************************************/
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
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.
88 openscop_matrix_print_structure(FILE * file
, openscop_matrix_p matrix
,
93 /* Go to the right level. */
94 for (j
= 0; j
< level
; j
++)
99 fprintf(file
,"+-- openscop_matrix_t\n");
101 for(j
= 0; j
<= level
; j
++)
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
++)
113 for (j
= 0; j
< matrix
->NbColumns
; j
++)
115 SCOPINT_print(file
,OPENSCOP_FMT
,matrix
->p
[i
][j
]);
123 fprintf(file
,"+-- NULL matrix\n");
126 for (j
= 0; j
<= level
; j
++)
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.
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.
159 openscop_matrix_expression_element(openscop_int_t val
, int * first
, int cst
,
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));
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
);
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
);
192 if (SCOPINT_one_p(val
))
193 sprintf(sval
,"+%s",name
);
197 SCOPINT_sprint(temp
,OPENSCOP_FMT_TXT
,val
);
199 sprintf(temp
,"*%s",name
);
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
))
214 SCOPINT_sprint(sval
,"+"OPENSCOP_FMT_TXT
,val
); /* Block macro ! */
217 SCOPINT_sprint(sval
,OPENSCOP_FMT_TXT
,val
);
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.
241 openscop_matrix_expression(openscop_matrix_p matrix
, int row
,
242 int nb_iterators
, char ** iterators
,
243 int nb_parameters
, char ** parameters
)
246 char * sline
, * sval
;
248 sline
= (char *)malloc(OPENSCOP_MAX_STRING
* sizeof(char)) ;
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,
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]);
269 /* Finally the constant part (yes, I reused it). */
270 sval
= openscop_matrix_expression_element(matrix
->p
[row
][i
],&first
,1,NULL
);
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.
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
)
303 fprintf(file
,"0 %d\n",nb_iterators
+nb_parameters
+2);
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
]);
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
);
323 if (SCOPINT_zero_p(matrix
->p
[i
][0]))
324 fprintf(file
," == 0");
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
);
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]);
347 expression
= openscop_matrix_expression(matrix
,k
,nb_iterators
,
349 nb_parameters
,parameters
);
350 fprintf(file
,"[%s]",expression
);
354 while ((k
< matrix
->NbRows
) && SCOPINT_zero_p(matrix
->p
[k
][0]));
365 /*****************************************************************************
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.
376 openscop_matrix_read(FILE* foo
)
378 unsigned NbRows
, NbColumns
;
380 char* c
, s
[OPENSCOP_MAX_STRING
], str
[OPENSCOP_MAX_STRING
];
381 openscop_matrix_p matrix
;
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
);
393 for (i
= 0; i
< matrix
->NbRows
; i
++)
397 c
= fgets(s
, OPENSCOP_MAX_STRING
, foo
);
398 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
401 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
405 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
408 for (j
= 0; j
< matrix
->NbColumns
; j
++)
410 if (c
== NULL
|| *c
== '#' || *c
== '\n')
412 fprintf(stderr
, "[Scoplib] Error: not enough columns\n");
415 if (sscanf(c
, "%s%n", str
, &n
) == 0)
417 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
420 #if defined(OPENSCOP_INT_T_IS_MP)
422 sscanf(str
, "%lld", &val
);
423 mpz_set_si(*p
++, val
);
425 sscanf(str
, OPENSCOP_FMT_TXT
, p
++);
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.
442 openscop_matrix_read_arrays(FILE* foo
, char*** arrays
, int* nb_arr
)
444 unsigned NbRows
, NbColumns
;
447 char* c
, s
[OPENSCOP_MAX_STRING
], str
[OPENSCOP_MAX_STRING
],
448 buff
[OPENSCOP_MAX_STRING
];
449 openscop_matrix_p matrix
;
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
);
461 for (i
= 0; i
< matrix
->NbRows
; i
++)
465 c
= fgets(s
, OPENSCOP_MAX_STRING
, foo
);
466 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
469 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
473 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
477 for (j
= 0; j
< matrix
->NbColumns
; j
++)
479 if (c
== NULL
|| *c
== '#' || *c
== '\n')
481 fprintf(stderr
, "[Scoplib] Error: not enough columns\n");
484 if (sscanf(c
, "%s%n", str
, &n
) == 0)
486 fprintf(stderr
, "[Scoplib] Error: not enough rows\n");
489 #if defined(OPENSCOP_INT_T_IS_MP)
491 sscanf(str
, "%lld", &val
);
492 mpz_set_si(*p
++, val
);
494 sscanf(str
, OPENSCOP_FMT_TXT
, p
++);
498 /* Read the array, passed as a comment at the end of the line. */
501 while (c
&& (isspace(*c
) || *c
== '#'))
503 for (count
= 0; c
&& *c
!= '[' && *c
!= '\n'; ++count
)
504 buff
[count
] = *(c
++);
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
);
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
534 * \param NbRows The number of row of the matrix to allocate.
535 * \param NbColumns The number of columns of the matrix to allocate.
538 openscop_matrix_malloc(unsigned NbRows
, unsigned NbColumns
)
540 openscop_matrix_p matrix
;
541 openscop_int_t
** p
, * q
;
544 matrix
= (openscop_matrix_p
)malloc(sizeof(openscop_matrix_t
));
547 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
550 matrix
->NbRows
= NbRows
;
551 matrix
->NbColumns
= NbColumns
;
552 matrix
->p_Init_size
= NbRows
* NbColumns
;
553 if (matrix
->p_Init_size
== 0)
556 matrix
->p_Init
= NULL
;
560 p
= (openscop_int_t
**)malloc(NbRows
*sizeof(openscop_int_t
*));
563 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
566 q
= (openscop_int_t
*)malloc(NbRows
* NbColumns
* sizeof(openscop_int_t
));
569 fprintf(stderr
, "[Scoplib] Memory Overflow.\n");
574 for (i
= 0; i
< NbRows
; i
++)
577 for (j
= 0; j
< NbColumns
; j
++)
578 SCOPINT_init_set_si(*(q
+j
),0);
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.
593 openscop_matrix_free_inside(openscop_matrix_p matrix
)
602 for (i
= 0; i
< matrix
->p_Init_size
; i
++)
605 if (matrix
->p_Init
!= NULL
)
606 free(matrix
->p_Init
);
608 if (matrix
->p
!= NULL
)
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.
619 openscop_matrix_free(openscop_matrix_p matrix
)
624 openscop_matrix_free_inside(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.
643 openscop_matrix_ncopy(openscop_matrix_p matrix
, int n
)
646 openscop_matrix_p copy
;
651 if (n
> matrix
->NbRows
)
653 fprintf(stderr
,"[Scoplib] Error: not enough rows in the matrix\n");
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
]);
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.
674 openscop_matrix_copy(openscop_matrix_p matrix
)
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.
692 openscop_matrix_replace_vector(openscop_matrix_p matrix
,
693 openscop_vector_p vector
, int row
)
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");
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.
719 openscop_matrix_add_vector(openscop_matrix_p matrix
, openscop_vector_p vector
,
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");
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.
748 openscop_matrix_sub_vector(openscop_matrix_p matrix
, openscop_vector_p vector
,
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");
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
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.
779 openscop_matrix_insert_vector(openscop_matrix_p matrix
, openscop_vector_p vector
,
783 openscop_matrix_p
new;
785 if ((vector
== NULL
) || (matrix
== NULL
))
788 if ((matrix
->NbColumns
!= vector
->Size
) ||
789 (row
> matrix
->NbRows
) || (row
< 0))
791 fprintf(stderr
,"[Scoplib] Error: vector cannot be inserted\n");
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
;
814 matrix
->p_Init
= new->p_Init
;
815 /* Free the new "shell" */
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.
827 openscop_matrix_from_vector(openscop_vector_p vector
)
829 openscop_matrix_p matrix
;
834 matrix
= openscop_matrix_malloc(1,vector
->Size
);
835 openscop_matrix_replace_vector(matrix
,vector
,0);
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
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.
850 openscop_matrix_replace_matrix(openscop_matrix_p m1
, openscop_matrix_p m2
, int row
)
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");
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
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
879 openscop_matrix_insert_matrix(openscop_matrix_p m1
, openscop_matrix_p m2
, int row
)
882 openscop_matrix_p
new;
884 if ((m1
== NULL
) || (m2
== NULL
))
887 if ((m1
->NbColumns
!= m2
->NbColumns
) ||
888 (row
> m1
->NbRows
) || (row
< 0))
890 fprintf(stderr
,"[Scoplib] Error: matrix cannot be inserted\n");
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
;
913 m1
->p_Init
= new->p_Init
;
915 /* Free the new "container" */
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.
928 openscop_matrix_concat(openscop_matrix_p m1
, openscop_matrix_p m2
)
930 openscop_matrix_p
new;
933 return openscop_matrix_copy(m2
);
936 return openscop_matrix_copy(m1
);
938 if (m1
->NbColumns
!= m2
->NbColumns
)
940 fprintf(stderr
,"[Scoplib] Error: matrices cannot be concatenated\n");
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
);
953 * openscop_matrix_equal function:
954 * this function returns true if the two matrices are the same, false
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
)
965 if (m1
== NULL
|| m2
== NULL
)
967 if (m1
->NbRows
!= m2
->NbRows
|| m1
->NbColumns
!= m2
->NbColumns
)
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
]))