/* Produit de convolution d'une matrice          */
/* de double par une matrice de double           */

public class ProduitDeConvolutionEnConsole {

/* Fonction de creation d'une matrice de double  */
/* initialisee avec des nombres aleatoires       */
/* compris dans l'intervalle [0.0,max]           */
/* et quatre chiffres apres la virgule           */

  static double [][] initRandMatrice(int lignes,
                                     int colonnes,
                                     double max) {
    double [][] tab = new double[lignes][colonnes];
    for ( int i = 0 ; i < lignes ; i++ ) {
      for ( int j = 0 ; j < colonnes ; j++ ) {
        tab[i][j] = ((int) (Math.random()*max*10000.0))/10000.0; } }
    return tab;
  }

/* Fonction d'affichage des valeurs contenues    */
/* dans une matrice de double                    */
/* Affichage avec 3 chiffres apres la virgule    */

  static void affichageMatrice(double [][] t) {
    for ( int i = 0 ; i < t.length ; i++ ) {
      for ( int j = 0 ; j < t[0].length ; j++ ) {
        Console.formater("%7.4f",t[i][j]); }
      Console.sautDeLigne(); }
  }

//////////////////////////////////////////////////

/* Fonction de calcul du produit de convolution  */
/* d'une matrice de double par une matrice       */
/* de convolution                                */
/* Stockage du resultat dans la 3eme matrice     */
/* passee en entete supposee de taille           */
/* compatible avec les deux premieres            */

  static void produitDeConvolution(double [][] m,
                                   double [][] mc,
                                   double [][] mr) {
    int l = mr.length;
    int c = mr[0].length;
    int xf;
    int yf;
    double v;
    for ( int i = 0 ; i < l ; i++ ) {
      for ( int j = 0 ; j < c ; j++ ) {
        mr[i][j] = 0.0;
        yf = i+mc.length;
        xf = j+mc[0].length;
        for ( int y = i ; y < yf ; y++ ) {
          for ( int x = j ; x < xf ; x++ ) {
            mr[i][j] = mr[i][j] + mc[y-i][x-j]*m[y][x]; } } } }
  }

/* Fonction de calcul du produit de convolution  */
/* d'une matrice de double par une matrice       */
/* de convolution                                */
/* Stockage du resultat dans une matrice         */
/* allouee et retournee en resultat de fonction  */

  static double [][] produitDeConvolution(double [][] m,
                                          double [][] mc) {
    int l = m.length-mc.length+1;
    int c = m[0].length-mc[0].length+1;
    double [][] mr = new double[l][c];
    produitDeConvolution(m,mc,mr);
    return mr;
  }

//////////////////////////////////////////////////

/* Programme principal                           */

  public static void main(String [] args) {
    Console.setTitle("ProduitDeConvolution");
    int l;
    int c;
    Console.afficher("Nombre de lignes   ? ");
    l = Console.saisirInt();
    Console.afficher("Nombre de colonnes ? ");
    c = Console.saisirInt();
    double [][] m = initRandMatrice(l,c,90.0);
    Console.sautDeLigne();
    Console.afficherln("Matrice a convoluer [",
                     m.length,",",m[0].length,"]");
    affichageMatrice(m);
    double fact = 12.0;
    double [][] mc = { { 1.0/fact,1.0/fact,1.0/fact },
                       { 1.0/fact,4.0/fact,1.0/fact },
                       { 1.0/fact,1.0/fact,1.0/fact } };
    Console.sautDeLigne();
    Console.afficherln("Matrice de convolution [",
                     mc.length,",",mc[0].length,"]");
    affichageMatrice(mc);
    double [][] res = produitDeConvolution(m,mc);
    Console.sautDeLigne();
    Console.afficherln("Matrice apres convolution [",
                     res.length,",",res[0].length,"]");
    affichageMatrice(res);
  }
}