/**************************************************************************** genConvo.cc generation of (square convolutions) convolutions files are text arrays (with tab); the first 3 numbers caracterise the convolution the first one is the width the second one is the height the third one is the total of the number in the array (if you don't know, put 0) Launch "genConvo" for syntax ex : genConv -s 10 0 1000 10 10 generate a 10x10 Gabor (because of the sinus -s) convolution of size 10x10 with a total sinaptic weight of 1000 arno@salk.edu, Arnaud Delorme, CNL / Salk Institute, 2001 This program is free software; you can redistribute it and/or modify it. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ****************************************************************************/ #include #include #include #include #define pi 3.14159 /* les variables globales */ float angle=0; /* angle de rotation */ int dimention=19; /* dimention du tableau carre */ int centre_x=9; int centre_y=9; int decale_x=0; /* decalage x */ int decale_y=0; /* decalage y */ int transpose=0; /* permet de transposer la matirce */ int negatif=0; /* interdit les poids negatifs */ int laplac=0; /* calcul du laplacien */ int sinus=0; /* applique ou pas un filtre sinus */ int invert=0; /* inversion des valeurs */ int half=0; /* gaussien en y uniquement sur une partie des poids */ int cx=0; /* centre de la gaussienne, exact (entier) ou decale */ int cy=0; /* idem pour y */ int seuil=0; /* seuil de reponse */ int t_decale=0; /* moment du decalage */ float champx=10.0; /* determine l'etendu de la gaussienne en x */ float champy=1000.0; /* etendue de la gaussiene en y */ int norm=10000; /* normalisation des poids = poids total */ float function(int x,int y) { float z,xx,yy,tmp; double x_c2, y_c2; xx = x; yy = y; /* effectue le decalage */ if (!t_decale) { xx = (xx + decale_x); /* % dimention; */ yy = (yy + decale_y); /* % dimention; */ } /* effectue la rotation des coordonnes */ tmp = xx; xx = (xx-centre_x) * cos(-angle) - (yy-centre_y) * sin(-angle) + centre_x; yy = (yy-centre_y) * cos(-angle) + (tmp-centre_x) * sin(-angle) + centre_y; if (t_decale) { xx = (xx + decale_x); yy = (yy + decale_y); } /* effectue la transposition */ if (transpose) { xx=xx+yy; yy=xx-yy; xx=xx-yy; } /* ********************************* */ /* calcule la fonction numeriquement */ /* ********************************* */ /* z = 4-(xx-centre_x)*(xx-centre_y); */ /* sinus seul z = sin((xx+0.83)/dimention*3*pi-pi/2); */ /* gaussienne seule exp(-(xx-centre_x)*(xx-centre_x)/2);*/ x_c2 = (xx-centre_x+0.5*cx)*(xx-centre_x+0.5*cx); y_c2 = (yy-centre_y+0.5*cy)*(yy-centre_y+0.5*cy); z = exp(-x_c2/champx); if (half) if (yy>centre_y) z = z * exp(-y_c2/champy); if (!half) z = z * exp(-(yy-centre_y+0.5*cy)*(yy-centre_y+0.5*cy)/champy); if (laplac) z = z * (-2/champx - 2/champy + 4*x_c2/(champx*champx) + 4*y_c2/(champy*champy)); if (sinus) z = sin((xx+0.83)/dimention*3*pi-pi/2)*z; /* inversion des valeurs */ if (invert) z=1-z; /* suppression des valeurs trops faibles */ if (seuil) if (z<0.10) z=0; /* met a 0 les nombres negatifs */ if ((!negatif) & (z<0)) z=0; return(z); } int main(int argc,char *argv[]) { int i,j; float save[50][50]; /* sauvegarde temporaire du tableau */ float somme; /* somme totale des poids */ int somme2; /* seconde somme des poids */ int pos=1; /* position initiale du premier argument */ /* parametres */ /* ********** */ if (argc==1) { printf("usage:poids -[tnsixydS] dimention angle norm fieldx fieldy shift_x shift_y \n"); printf("\t-t tranpose\n"); printf("\t-n allow negatives values\n"); printf("\t-s apply a sinus function\n"); printf("\t-i inversion of all values\n"); printf("\t-h gaussian for y axis only on one side\n"); printf("\t-l laplacian function\n"); printf("\t-x center of gaussian field for x betwen two integer values\n"); printf("\t-y center of gaussian field for y betwen two integer values\n"); printf("\t-d shift x and y after rotation\n"); printf("\t-S value less than 10% of max response are eliminated\n"); printf("\tdimention dimention of array\n"); printf("\tangle rotation of the patern in degre (default 0)\n"); printf("\tnorm normalisation of weigth: total weigth (default 10000)\n"); printf("\tfieldx size of the receptive field x (2 sigma_x^2) (default 10)\n"); printf("\tfieldy size of the receptive field y (2 sigma_y^2) (default 1000)\n"); printf("\tshiftx shift the values on the x axis (default 0)\n"); printf("\tshifty shift the values on the y axis (default 0)\n"); exit(-1); } if ((argc>1) & (*argv[1]=='-')) { pos = 2; if (strchr(argv[1],'t')!=NULL) transpose=1; if (strchr(argv[1],'n')!=NULL) negatif=1; if (strchr(argv[1],'s')!=NULL) sinus=1; if (strchr(argv[1],'i')!=NULL) invert=1; if (strchr(argv[1],'h')!=NULL) half=1; if (strchr(argv[1],'l')!=NULL) laplac=1; if (strchr(argv[1],'x')!=NULL) cx=1; if (strchr(argv[1],'y')!=NULL) cy=1; if (strchr(argv[1],'S')!=NULL) seuil=1; if (strchr(argv[1],'d')!=NULL) t_decale=1; } if (argc>pos) { dimention = atoi(argv[pos]); centre_x = dimention / 2; centre_y = dimention /2; } if (argc>(pos+1)) angle = atof(argv[pos+1]) / 180 * pi; if (argc>(pos+2)) norm = atoi(argv[pos+2]); if (argc>(pos+3)) champx = atof(argv[pos+3]); if (argc>(pos+4)) champy = atof(argv[pos+4]); if (argc>(pos+5)) decale_x = atoi(argv[pos+5]); if (argc>(pos+6)) decale_y = atoi(argv[pos+6]); /* affichage du calcul */ /* ******************* */ somme = 0; for (i=0;i