begin process at 2010 02 10 11:33:16
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Maths & Algorithmes

 > OPÉRATION SUR MATRICE

OPÉRATION SUR MATRICE


 Information sur la source

Note :
10 / 10 - par 2 personnes
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Maths & Algorithmes Niveau :Débutant Date de création :07/06/2004 Date de mise à jour :07/06/2004 12:39:09 Vu :11 412

Auteur : bonac

Ecrire un message privé
Site perso
Commentaire sur cette source (11)
Ajouter un commentaire et/ou une note

 Description

quelques fonctions et une structure simple permettant de calculer des opérations courantes sur les matrices: transposée, multiplication, addition, déterminant, inversion, comatrice, moindre carré...

Source

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <math.h>
  • typedef struct{
  • int n, m; /*n->lignes, m->colonnes*/
  • double **P;/*Matrice*/
  • } *Matrice, structMatrice;
  • Matrice allouerMatrice(int l,int c){/*allouer une matrice de l lignes et c colonnes*/
  • Matrice A;
  • int i;
  • A=(Matrice)malloc(sizeof(structMatrice));
  • A->n=l;A->m=c;
  • A->P=(double**)malloc(l*sizeof(double*));
  • for(i=0;i<l;i++) {
  • A->P[i]=(double *)malloc(c*sizeof(double ));
  • }
  • return A;
  • }
  • void libererMatrice(Matrice A){/*libÃ&#168;re l'espace mémoire occupé par la matrice*/
  • int i;
  • for(i=0;i<A->n;i++)free(A->P[i]);
  • }
  • int deMemeDim(Matrice A, Matrice B){/*teste si les matrices A et B sont de même dimension*/
  • if(A->n == B->n && A->m == B->m)return 1;
  • return 0;
  • }
  • Matrice Mat_add(Matrice A, Matrice B){/*renvoie la matrice issue de l'addition de A et de B*/
  • int i,j;
  • Matrice C;
  • if(!deMemeDim(A,B))return NULL;
  • C=allouerMatrice(A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • C->P[i][j]=A->P[i][j]+B->P[i][j];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_Id(int n){/*renvoie la matrice identité de dimension n x n */
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(n,n);
  • for(i=0;i<n;i++){
  • for(j=0;j<n;j++){
  • if(i!=j)C->P[i][j]=0;
  • else C->P[i][j]=1;
  • }
  • }
  • return C;
  • }
  • Matrice Mat_nulle(int n){/*renvoie une matrice nulle*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(n,n);
  • for(i=0;i<n;i++){
  • for(j=0;j<n;j++){
  • C->P[i][j]=0;
  • }
  • }
  • return C;
  • }
  • Matrice Mat_mul(Matrice A, double c){/*renvoie le produit de A par le scalaire c*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • C->P[i][j]=c*A->P[i][j];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_dot(Matrice A, Matrice B){/*renvoie le produit de A et B,
  • renvoie NULL si l'opération n'est pas possible*/
  • int i,j,k;
  • Matrice C;
  • if(A->m!=B->n)return NULL;
  • C=allouerMatrice(A->n,B->m);
  • for(i=0;i<C->n;i++){
  • for(j=0;j<C->m;j++){
  • for(k=0;k<A->m;k++){
  • C->P[i][j]+= A->P[i][k]*B->P[k][j];
  • }
  • }
  • }
  • return C;
  • }
  • Matrice Mat_transpose(Matrice A){/*renvoie la transposée de la matrice A*/
  • int i,j;
  • Matrice C;
  • C=allouerMatrice(A->m,A->n);
  • for(i=0;i<C->n;i++){
  • for(j=0;j<C->m;j++){
  • C->P[i][j]=A->P[j][i];
  • }
  • }
  • return C;
  • }
  • Matrice Mat_sousMat(Matrice A,int ib,int jb){/*renvoie la matrice A à laquelle à été supprimé
  • la ib°ligne et la jb° colonne*/
  • int i,j;
  • int is=0,js=0;
  • Matrice B;
  • B=allouerMatrice(A->n-1,A->m-1);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • if(i!=ib && j!=jb){
  • B->P[is][js]=A->P[i][j];
  • if(js<B->n-1)js++;
  • else{js=0;is++;}
  • }
  • }
  • }
  • return B;
  • }
  • double Mat_determinant(Matrice A){/*renvoie le déterminant de la matrice A*/
  • int i,j;
  • double det=0;
  • Matrice B;
  • //condition d'arret
  • if(A->n==1)return A->P[0][0];
  • if(A->n==2)return A->P[0][0]*A->P[1][1]-A->P[0][1]*A->P[1][0];
  • //condition de descente dans la récurrence
  • else{
  • for(j=0;j<A->m;j++){
  • B=Mat_sousMat(A,0,j);
  • if(j%2==0){det+=A->P[0][j]*Mat_determinant(B);}
  • else{det+=(-1)*A->P[0][j]*Mat_determinant(B);}
  • libererMatrice(B);
  • }
  • }
  • return det;
  • }
  • void Mat_afficherMat(Matrice A){/*affiche la matrice A*/
  • int i,j;
  • printf("\n Matrice %dx%d :\n",A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • printf("%f\t",A->P[i][j]);
  • }
  • printf("\n");
  • }
  • }
  • void Mat_remplirMatrice(Matrice A){/*remplie la matrice A par saisie au clavier*/
  • int i,j;
  • printf("\nRemplissage de matrice %dx%d\n",A->n,A->m);
  • for(i=0;i<A->n;i++){
  • for(j=0;j<A->m;j++){
  • printf("element (%d,%d)?",i,j);
  • scanf("%lf",&(A->P[i][j]));
  • }
  • }
  • }
  • Matrice Mat_coMat(Matrice A){/*renvoie la comatrice de A*/
  • int i,j;
  • Matrice B;
  • Matrice S;
  • B=allouerMatrice(A->n,A->m);
  • //S=allouerMatrice(A->n-1,A->m-1);
  • for(i=0;i<B->n;i++){
  • for(j=0;j<B->m;j++){
  • S=Mat_sousMat(A,i,j);
  • if((i+j)%2==0){B->P[i][j]=Mat_determinant(S);}
  • else{B->P[i][j]=-1*Mat_determinant(S);}
  • libererMatrice(S);
  • }
  • }
  • return B;
  • }
  • Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
  • double det;
  • Matrice coA,t_coA,inv_A;
  • det=Mat_determinant(A);
  • if(det==0)return NULL;
  • coA=Mat_coMat(A);
  • t_coA=Mat_transpose(coA);
  • inv_A=Mat_mul(t_coA,1/det);
  • libererMatrice(coA);
  • libererMatrice(t_coA);
  • libererMatrice(inv_A);
  • return inv_A;
  • }
  • int Mat_moindreCarre(Matrice A,Matrice *U,Matrice B){/*résout A.U=B par la méthode de moindre carré
  • renvoie 1 si le calcul est possible, 0 sinon*/
  • Matrice At,AtA,AtA_inv,AtA_inv_At;
  • At=Mat_transpose(A);
  • AtA=Mat_dot(At,A);
  • AtA_inv=Mat_invMat(AtA);
  • if(AtA_inv==NULL)return 0;
  • AtA_inv_At=Mat_dot(AtA_inv,At);
  • *U=Mat_dot(AtA_inv_At,B);
  • libererMatrice(At);
  • libererMatrice(AtA);
  • libererMatrice(AtA_inv);
  • libererMatrice(AtA_inv_At);
  • return 1;
  • }
  • int main(){
  • Matrice A,B,C,D,U;
  • double det;
  • int i,j;
  • /*A=allouerMatrice(3,3);
  • Mat_remplirMatrice(A);
  • Mat_afficherMat(A);
  • getchar();
  • B=Mat_mul(A,3.2);
  • Mat_afficherMat(B);
  • getchar();
  • libererMatrice(B);
  • B=Mat_Id(3);
  • C=Mat_dot(A,B);
  • Mat_afficherMat(C);
  • getchar();
  • det=Mat_determinant(A);
  • printf("det(A)=%lf\n",det);
  • getchar();
  • A=Mat_mul(A,2);
  • Mat_afficherMat(A);
  • getchar();
  • D=allouerMatrice(2,2);
  • Mat_remplirMatrice(D);
  • Mat_afficherMat(D);
  • det=Mat_determinant(D);
  • printf("det=%lf\n",det);
  • D=Mat_invMat(D);
  • D=Mat_mul(D,det);
  • Mat_afficherMat(D);*/
  • //Test Méthode de moindre carré
  • A=allouerMatrice(10,4);
  • B=allouerMatrice(10,1);
  • for(i=0;i<A->n;i++){
  • B->P[i][0]=(double)rand()*10/RAND_MAX;
  • for(j=0;j<A->m;j++){
  • A->P[i][j]=(double)rand()*10/RAND_MAX;
  • }
  • }
  • Mat_afficherMat(A);
  • Mat_afficherMat(B);
  • Mat_moindreCarre(A,&U,B);
  • Mat_afficherMat(U);
  • libererMatrice(A);
  • libererMatrice(B);
  • libererMatrice(U);
  • }
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


typedef struct{
	int n, m; /*n->lignes, m->colonnes*/
  	double **P;/*Matrice*/
} *Matrice, structMatrice;


Matrice allouerMatrice(int l,int c){/*allouer une matrice de l lignes et c colonnes*/
	Matrice A;
	int i;
	A=(Matrice)malloc(sizeof(structMatrice));
	A->n=l;A->m=c;
	A->P=(double**)malloc(l*sizeof(double*));
	for(i=0;i<l;i++) {
		A->P[i]=(double *)malloc(c*sizeof(double ));
	}
	return A;
}

void libererMatrice(Matrice A){/*libÃ&#168;re l'espace mémoire occupé par la matrice*/
	int i;
	for(i=0;i<A->n;i++)free(A->P[i]);
}
int deMemeDim(Matrice A, Matrice B){/*teste si les matrices A et B sont de même dimension*/
	if(A->n == B->n && A->m == B->m)return 1;
	return 0;
}

Matrice Mat_add(Matrice A, Matrice B){/*renvoie la matrice issue de l'addition de A et de B*/
	int i,j;
	Matrice C;
	if(!deMemeDim(A,B))return NULL;
	C=allouerMatrice(A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			C->P[i][j]=A->P[i][j]+B->P[i][j];
		}
	}
	return C;
}

Matrice Mat_Id(int n){/*renvoie la matrice identité de dimension n x n */
	int i,j;
	Matrice C;
	C=allouerMatrice(n,n);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			if(i!=j)C->P[i][j]=0;
			else C->P[i][j]=1;
		}
	}
	return C;
}

Matrice Mat_nulle(int n){/*renvoie une matrice nulle*/
	int i,j;
	Matrice C;
	C=allouerMatrice(n,n);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++){
			C->P[i][j]=0;
		}
	}
	return C;
}
Matrice Mat_mul(Matrice A, double c){/*renvoie le produit de A par le scalaire c*/
	int i,j;
	Matrice C;
	C=allouerMatrice(A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			C->P[i][j]=c*A->P[i][j];
		}
	}
	return C;
}



Matrice Mat_dot(Matrice A, Matrice B){/*renvoie le produit de A et B,
	renvoie NULL si l'opération n'est pas possible*/
	int i,j,k;
	Matrice C;
	if(A->m!=B->n)return NULL;
	C=allouerMatrice(A->n,B->m);
	for(i=0;i<C->n;i++){
		for(j=0;j<C->m;j++){
			for(k=0;k<A->m;k++){
			C->P[i][j]+= A->P[i][k]*B->P[k][j];
			}
		}
	}
	
	return C;
}

Matrice Mat_transpose(Matrice A){/*renvoie la transposée de la matrice A*/
	int i,j;
	Matrice C;
	C=allouerMatrice(A->m,A->n);
	for(i=0;i<C->n;i++){
		for(j=0;j<C->m;j++){
			C->P[i][j]=A->P[j][i];
		}
	}
	return C;
}



Matrice Mat_sousMat(Matrice A,int ib,int jb){/*renvoie la matrice A à laquelle à été supprimé
	la ib°ligne et la jb° colonne*/
	int i,j;
	int is=0,js=0;
	Matrice B;
	B=allouerMatrice(A->n-1,A->m-1);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			if(i!=ib && j!=jb){
			B->P[is][js]=A->P[i][j];
			if(js<B->n-1)js++;
			else{js=0;is++;}	
			}
		}
	}
	return B;
}
double Mat_determinant(Matrice A){/*renvoie le déterminant de la matrice A*/
	int i,j;
	double det=0;
	Matrice B;
	//condition d'arret
	if(A->n==1)return A->P[0][0];
	if(A->n==2)return A->P[0][0]*A->P[1][1]-A->P[0][1]*A->P[1][0];
	//condition de descente dans la récurrence
	else{
		for(j=0;j<A->m;j++){
		B=Mat_sousMat(A,0,j);
		if(j%2==0){det+=A->P[0][j]*Mat_determinant(B);}
		else{det+=(-1)*A->P[0][j]*Mat_determinant(B);}
		libererMatrice(B);
		}
	}
	return det;
}
void Mat_afficherMat(Matrice A){/*affiche la matrice A*/
	int i,j;
	printf("\n Matrice %dx%d :\n",A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			printf("%f\t",A->P[i][j]);
		}
		printf("\n");
	}
}
void Mat_remplirMatrice(Matrice A){/*remplie la matrice A par saisie au clavier*/
	int i,j;
	printf("\nRemplissage de matrice %dx%d\n",A->n,A->m);
	for(i=0;i<A->n;i++){
		for(j=0;j<A->m;j++){
			printf("element (%d,%d)?",i,j);
			scanf("%lf",&(A->P[i][j]));
		}
	}
}

Matrice Mat_coMat(Matrice A){/*renvoie la comatrice de A*/
	int i,j;
	Matrice B;
	Matrice S;
	B=allouerMatrice(A->n,A->m);
	//S=allouerMatrice(A->n-1,A->m-1);
	for(i=0;i<B->n;i++){
		for(j=0;j<B->m;j++){
			S=Mat_sousMat(A,i,j);
			if((i+j)%2==0){B->P[i][j]=Mat_determinant(S);}
			else{B->P[i][j]=-1*Mat_determinant(S);}
			libererMatrice(S);
		}
	}
	return B;
}
Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
	double det;
	Matrice coA,t_coA,inv_A;
	det=Mat_determinant(A);
	if(det==0)return NULL;
	coA=Mat_coMat(A);
	t_coA=Mat_transpose(coA);
	inv_A=Mat_mul(t_coA,1/det);
	libererMatrice(coA);
	libererMatrice(t_coA);
	libererMatrice(inv_A);
	return inv_A;
}

int Mat_moindreCarre(Matrice A,Matrice *U,Matrice B){/*résout A.U=B par la méthode de moindre carré
	renvoie 1 si le calcul est possible, 0 sinon*/
	Matrice At,AtA,AtA_inv,AtA_inv_At;
	At=Mat_transpose(A);
	AtA=Mat_dot(At,A);
	AtA_inv=Mat_invMat(AtA);
	if(AtA_inv==NULL)return 0;
	AtA_inv_At=Mat_dot(AtA_inv,At);
	*U=Mat_dot(AtA_inv_At,B);
	libererMatrice(At);
	libererMatrice(AtA);
	libererMatrice(AtA_inv);
	libererMatrice(AtA_inv_At);
	return 1;
}
int main(){
	Matrice A,B,C,D,U;
	double det;
	int i,j;
	/*A=allouerMatrice(3,3);
	Mat_remplirMatrice(A);
	Mat_afficherMat(A);
	getchar();
	B=Mat_mul(A,3.2);
	Mat_afficherMat(B);
	getchar();
	libererMatrice(B);
	B=Mat_Id(3);
	C=Mat_dot(A,B);
	Mat_afficherMat(C);
	getchar();
	det=Mat_determinant(A);
	printf("det(A)=%lf\n",det);
	getchar();
	A=Mat_mul(A,2);
	Mat_afficherMat(A);
	getchar();	
	D=allouerMatrice(2,2);
	Mat_remplirMatrice(D);
	Mat_afficherMat(D);
	det=Mat_determinant(D);
	printf("det=%lf\n",det);
	D=Mat_invMat(D);
	D=Mat_mul(D,det);
	Mat_afficherMat(D);*/
	//Test Méthode de moindre carré
	A=allouerMatrice(10,4);
	B=allouerMatrice(10,1);
	for(i=0;i<A->n;i++){
		B->P[i][0]=(double)rand()*10/RAND_MAX;
		for(j=0;j<A->m;j++){
			A->P[i][j]=(double)rand()*10/RAND_MAX;
		}
	}
	
	Mat_afficherMat(A);
	Mat_afficherMat(B);
	Mat_moindreCarre(A,&U,B);
	Mat_afficherMat(U);
	libererMatrice(A);
	libererMatrice(B);
	libererMatrice(U);
}



 Sources du même auteur

RÉSOLUTION DE SYSTÈMES D'ÉQUATIONS

 Sources de la même categorie

Source avec Zip OPERATION SUR LES MATRICES CARREES AVEC CLASSE GENERIQUE par chouhad
Source avec une capture OPÉRATIONS SUR MATRICES C++ par Minilogus
[DEV-C++] CALCUL DE LA RACINE CARRÉE D'UN RÉEL par Jhep
PROGRAMME QUI CALCUL LE PPCM ET LE PGCD par AnoSantino
EVALUER UNE EXPRESSION MATHÉMATIQUE par begueradj

Commentaires et avis

Commentaire de Kornferki le 16/06/2004 14:44:21

Je ne suis pas sur que la dimension des matrices soit vraiment de n et m. Si dans tes boucles tu vas de 0 a n ou m, les dimensions seraient plutot de n+1 a m+1, isnt it ???

Que se passe t il si ta matrice n est pas carree et que tu calcules le determinant ?

Commentaire de bonac le 06/07/2004 16:04:50

J'ai pour abitude de travaillé à partir de l'indexe 0, mes boucles for s'arrètes à n-1. Il y a donc bien n valeur dans [0; n-1]. En d'autres termes pour une matrice n,m avec les paramètre n,m fournie en entrée les boucle parcourirons [0,n-1](n éléments) et [0,m-1] (m éléments), ont aura bine une matrice n,m.

Commentaire de Cyber_steph le 30/07/2004 10:59:27

bonjour,

j'ai voulut utiliser cette source mais apparement la multiplication et l'inverssion ne marche pas.

C bien dommage car ce code m'interessait bc.

bye

Commentaire de zbigzo le 19/01/2005 18:06:41

c bien ce que t'as fai je te souhai 1 bon continuat°

Commentaire de Byron202 le 06/06/2005 09:54:38

Je confirme un bug dans la partie inversion de matrice.
Multiplication, j'ai pas encore vérifié.

Commentaire de Byron202 le 06/06/2005 16:30:40

Il suffit en fait de mettre le libererMatrice  "APRES" le return detA.
En effet, dans le code, on libère la mémoire avant de retourner la valeur d'où le bug et donc le calcul du determinant déconne.

Commentaire de regisbeg le 09/11/2005 18:23:44

Pour la multiplication, remplacer dans la fonction de multiplication des matrices C->P[i][j] += A->P[i][k] * B->P[k][j]; en mettant un espace de chaque coté de la multiplication sans quoi le compilateur considère B->P[k][j] comme un pointeur.

Commentaire de Amanobuo le 02/04/2007 23:31:40

Merci ! c'est exactement ce que je cherchais !
J'était frustre de pas y arriver pour la multiplications ! Mais je me suis trop embrouillé avec ces math !

Commentaire de Gaston0510 le 20/03/2008 16:53:54

merci Bonac c un enorme travail !!
enfet c presque notr sujet mai seulement avec les bibliotheque stdio.h, string.h, conio.h ..
et dans mon projet on ns demande de faire un quadrillage double lor d l'affichage des matrices ..
Alors peut tu m'aider ou m montrer comment faire ce quadrillage ?

Commentaire de didou4545 le 30/04/2009 14:43:53

Il y a une faute dans cette fonction
[code]

# Matrice Mat_invMat(Matrice A){/*renvoie la matrice inverse de A*/
# double det;
# Matrice coA,t_coA,inv_A;
# det=Mat_determinant(A);
# if(det==0)return NULL;
# coA=Mat_coMat(A);
# t_coA=Mat_transpose(coA);
# inv_A=Mat_mul(t_coA,1/det);
# libererMatrice(coA);
# libererMatrice(t_coA);
# libererMatrice(inv_A);    // ici vous libérer la matrice " inv_A " puis vous la retourné tout de suite !!
# return inv_A;
# }  


[/code]

Commentaire de snoopy77 le 22/08/2009 19:14:48

Bonjour,

Merci beaucoup pour le partage de cette source, quelques fonctions m'ont bien aidées dans l'un de mes projets. J'ai aussi une remarque a ajouter sur l'une des fonctions en plus de celles déjà données.

Donc faire simple voici un résumé des bugs dans la version courante :

1) Dans la fonction inverse:

>> Supprimer la ligne 197: libererMatrice(inv_A);

En effet la fonction est de type Matrice et donc dois renvoyer un element de ce type en l'occurence 'inv_A' qui viens d'être calculé.


2) Dans la fonction multiplication, le fait d'avoir l'étoile sans espace autour ne me pose pas de problème. A voir suivant le compilateur qui peut être peu confondre avec un pointeur en effet.

3) J'ai du ajouter des conditions dans la fonction de reduction de matrice " Matrice Mat_sousMat(Matrice A,int ib,int jb)" ligne 115. J'ai eu des problème en voulant retirer la derniére ligne/colonne.

J'ai pas le temps de refaire l'analogie avec le code de Bonac pour expliquer la correction (a confirmer quand même), cependant je vous fournis la version actuel de mon code (en anglais) avec lequel je n'ai pas de souci:

Matrix matrixReduc(Matrix A,int ib,int jb){
  int i,j;
  int is=0,js=0;
  int n=A->n;
  int k=A->k;    
  Matrix B;

B=createMatrix(n-1,k-1);

/* Extreme condition */
if(ib==A->n-1){n--;}
if(jb==A->k-1){k--;}


for(i=0;i<n;i++)
{
if(i==ib && ib!=k)
{
i++;
}
for(j=0;j<k;j++)
{
  if(j==jb && jb!=n)
  {
  j++;
  }

  B->P[is][js]=A->P[i][j];
  js++;
}
js=0;
is++;
}
return B;
}

Merci encore pour le code.

SnOoPy

 Ajouter un commentaire




Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,718 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales