double psiPrime(base_t data,double * descente,double pas) { int i,j; double gradient[(data.n)]; for(i=0;i<data.n;i++){ data.w[i]=data.w[i]+pas*descente[i]; gradient[i]=0; } for(i=0;i<data.p;i++){ for(j=0;j<(data.n);j++){ gradient[j]=gradient[j]-(data.c[i]-produitScalaire((data.x)[i],data.w,(data.n)))*data.x[i][j]; } } return produitScalaire(gradient,descente,(data.n)); }
void adaline(base_t * data,double seuil){ int j,i,test=0,compteur=0; double o=0; double copie[(data->n)]; double descente[(data->n)]; double epsilon; srand(time(0)); for(i=0;i<(data->n);i++) (data->w)[i]=rand()%10; j=0; do{ for(i=0;i<(data->n);i++) copie[i]=(data->w)[i]; o=produitScalaire((data->x)[j],data->w,(data->n)); for(i=0;i<(data->n);i++) { descente[i]=(((data->c)[j]-o)*((data->x)[j][i])); /*printf("sur l'échantillon %d, la direction sur %d est %lf\n",j,i,descente[i]);*/ } epsilon=pas(data,descente); /*printf("epsilon %e\n",epsilon);*/ for(i=0;i<data->n;i++){ data->w[i]=data->w[i]+descente[i]*epsilon; } j=(j+1)%(data->p); compteur++; /*printf(" Le pas vaut %lf, echantillon %d\n",epsilon,j);*/ if(j==0){ test=testb(copie,data->w,data->n,seuil); } }while(compteur<data->p*20||!test); afficherW(data); printf("%d corrections avec adaline\n",compteur); }
int testb(double * copie,double * w,int size,double seuil) { int i; double normeW=0,normeVariation=0, temp[size]; for(i=0;i<size;i++){ temp[i]=w[i]-copie[i]; } normeVariation=sqrt(produitScalaire(temp,temp,size)); normeW=sqrt(produitScalaire(w,w,size)); return ((normeVariation/normeW)<seuil); }
void descenteGradient(base_t * data,double seuil){ int i,j,compteur=0; double copie[(data->n)]; double descente[(data->n)]; double o[(data->p)]; double epsilon; srand(time(0)); for(i=0;i<(data->n);i++){ (data->w)[i]=rand()%100; } do{ for(i=0;i<(data->n);i++){ descente[i]=0; copie[i]=data->w[i]; } for(i=0;i<data->p;i++){ for(j=0;j<(data->n);j++){ descente[j]=descente[j]+(data->c[i]-produitScalaire((data->x)[i],data->w,(data->n)))*data->x[i][j]; } } epsilon=pas(data,descente); /*printf("epsilon %e\n",epsilon);*/ for(i=0;i<data->n;i++){ data->w[i]=data->w[i]+descente[i]*epsilon; /*descente[i]=descente[i]*epsilon;*/ } compteur++; }while(!testb(copie,data->w,(data->n),seuil)||compteur<data->p); afficherW(data); printf("On a %d corrections avec descente de gradient\n",compteur*(data->n)); }
/////////////////////////////////////////////////////////////////////////////// /// /// @fn bool Droite3D::intersection(const Plan3D& planCoupe, Vecteur3& intersection) /// /// Cette fonction permet de trouver l'intersection entre une droite et un plan /// dans l'espace 3D. La droite ne doit pas être parallèle au plan. \n /// /// Si /// @f$ a @f$ /// est différent de zéro, alors l'intersection est donnée par :\n /// /// \f[ x = \left ( { \frac {\left ( \frac { ( B b + C c) x_0} {a} - B y_0 - C z_0 - D \right)} { ( A + B \frac {b} {a} + C \frac{c} {b})} }\right) \f] /// \f[ y = \left ( { \frac {\left ( C \frac {c}{b} y_0 - C z_0 - D \right)} { ( B + C \frac {c} {b}) } }\right) \f] /// \f[ z = \frac{c} {a} (x - x_0) + z_0 \f] /// /// Si /// @f$ b @f$ /// est différent de zéro, alors l'intersection est donnée par :\n /// /// \f[ x = x_0 \f] /// \f[ y = \frac{c} {b} (x - x_0) + y_0 \f] /// \f[ z = \frac{c} {b} (y - y_0) + z_0 \f] /// /// Sinon, l'intersection est donnée par :\n /// /// \f[ x = x_0 \f] /// \f[ y = y_0 \f] /// \f[ z = \frac{(D + A x_0 + B y_0)} {C} \f] /// /// @param[in] planCoupe : Le plan avec lequel on veut trouver l'intersection. /// @param[out] intersection : Le résultat de l'intersection @f$ (s, y, z) @f$ . /// /// @return Faux si la droite est parallèle au plan, donc si donc /// l'intersection ne peut être trouvée, vrai autrement. /// /////////////////////////////////////////////////////////////////////////////// bool Droite3D::intersection( const Plan3D& planCoupe, Vecteur3& intersection ) { // Initialisation de variables const double x0 = pointDroite_[0]; const double y0 = pointDroite_[1]; const double z0 = pointDroite_[2]; const double a = direction_[0]; const double b = direction_[1]; const double c = direction_[2]; double A, B, C, D; planCoupe.lireParam( A, B, C, D ); //Le résultat double x, y, z; // On regarde si le plan et la droite sont parallèles. bool bParalleles = utilitaire::EGAL_ZERO( produitScalaire( planCoupe.lireNormale(), direction_ ) ); if ( !bParalleles ) { // On doit faire attention aux divisions par 0 if ( !utilitaire::EGAL_ZERO ( a ) ) { x = ( ( B * b + C * c ) * x0 / a - B * y0 - C * z0 - D ) / ( A + B * b / a + C * c / a ); y = b / a * ( x - x0 ) + y0; z = c / a * ( x - x0 ) + z0; } else if ( !utilitaire::EGAL_ZERO ( b ) ) { y = ( C * c / b * y0 - A * x0 - C * z0 - D ) / ( B + C * c / b ); x = x0; z = c / b * ( y - y0 ) + z0; } else { x = x0; y = y0; z = -( D + A * x0 + B * y0 ) / C; } intersection[0] = x; intersection[1] = y; intersection[2] = z; } return !bParalleles; }
double Vector3D::angle(const Vector3D& vec) const { if(vec.estNul()) return 0; return acos(produitScalaire(vec)/(norme()*vec.norme())); }
float norme(Vecteur a){ return sqrt(produitScalaire(a,a)); }
Vecteur3D rotationAutourDunVecteur(const Vecteur3D& v1, const Vecteur3D& v2, float angle) { Vecteur3D res; res = v1*cosf(angle)+(1-cosf(angle))*(produitScalaire(v1,v2))*v2+sinf(angle)*produitVectoriel(v2,v1); return res; }