Example #1
0
void Evrot::evrot() {

	// definitions
	int max_iter = 200;
	double dQ,Q,Q_new,Q_old1,Q_old2,Q_up,Q_down;
	double alpha;
	int iter,d;

	Eigen::VectorXd theta = Eigen::VectorXd::Zero(mNumAngles);
	Eigen::VectorXd theta_new = Eigen::VectorXd::Zero(mNumAngles);

	Q = evqual(mX); // initial quality
	if( DEBUG )
		std::cout << "Q = " << Q << std::endl;
	Q_old1 = Q;
	Q_old2 = Q;
	iter = 0;
	while( iter < max_iter ){ // iterate to refine quality
		iter++;
		for( d = 0; d < mNumAngles; d++ ){
			if( mMethod == 2 ){ // descend through numerical drivative
				alpha = 0.1;
				{
					// move up
					theta_new[d] = theta[d] + alpha;
					Eigen::MatrixXd& Xrot = rotate_givens(theta_new);
					Q_up = evqual(Xrot);
					delete &Xrot;
				}
				{
					// move down
					theta_new[d] = theta[d] - alpha;
					Eigen::MatrixXd& Xrot = rotate_givens(theta_new);
					Q_down = evqual(Xrot);
					delete &Xrot;
				}

				// update only if at least one of them is better
				if( Q_up > Q || Q_down > Q){
					if( Q_up > Q_down ){
						theta[d] = theta[d] + alpha;
						theta_new[d] = theta[d];
						Q = Q_up;
					} else {
						theta[d] = theta[d] - alpha;
						theta_new[d] = theta[d];
						Q = Q_down;
					}
				}
			} else { // descend through true derivative
				alpha = 1.0;
				dQ = evqualitygrad(theta, d);
				theta_new[d] = theta[d] - alpha * dQ;
				Eigen::MatrixXd& Xrot = rotate_givens(theta_new);
				Q_new = evqual(Xrot);
				delete &Xrot;

				if( Q_new > Q){
					theta[d] = theta_new[d];
					Q = Q_new;
				}
				else{
					theta_new[d] = theta[d];
				}
			}
		}
		// stopping criteria
		if( iter > 2 ){
			if( Q - Q_old2 < 1e-3 ){
				break;
			}
		}
		Q_old2 = Q_old1;
		Q_old1 = Q;
	}

	if (DEBUG)
		std::cout << "Done after " << iter << " iterations, Quality is " << Q << std::endl;

	mXrot = rotate_givens(theta_new);
	cluster_assign();

	//output
	mQuality = Q;
}
double evrot(double* mat,int dim,int ndata,int* out_clusts,double* out_xrot,int method)
{
		int tmpi=0;
		int tmpk=0;
		int tmpj=0;
		int vari=0;
		int varj=0;
		int dk=5;
		int max_iter = 200;    
		double dQ=0;
		double Q=0;
		double Q_new=0;
		double Q_old1=0;
		double Q_old2=0;
		double Q_up=0;
		double Q_down=0;
		double alpha=0;
		int iter=0;
		int d=0;
		double tmpDouble=0;
		int angle_num=0;
		angle_num=(int)(dim*(dim-1)/2);
		double* theta=new double[angle_num];
		double* theta_new=new double[angle_num];
		int* jk=new int[angle_num];
		int* ik=new int[angle_num];
		double* p_theta=theta;
		double* p_theta_new=theta_new;
		tmpi=0;
		for(vari=0;vari<dim-1;vari++)
			for(varj=vari+1;varj<=dim-1;varj++)
			{
				ik[tmpi]=vari;
				jk[tmpi]=varj;
				tmpi++;
			}

		Q = evqual(mat,dim,ndata);

				///getchar();
		Q_old1 = Q;
		Q_old2 = Q;
		iter = 0;

		MatrixInitZeros(out_xrot,dim,ndata);
		MatrixInitZeros(p_theta,1,angle_num);
		MatrixInitZeros(p_theta_new,1,angle_num);
		
		while( iter < max_iter )
		{/* iterate to refine quality */
			iter++;
			cout<<"iter "<<iter<<endl;
			for( d = 0; d < angle_num; d++ )
			{
				if( method == 2 )
            	{ /* descend through numerical drivative */
					alpha = 0.1;
               		/* move up */                
               		p_theta_new[d] = p_theta[d] + alpha;
               		rotate_givens(mat,theta_new,ik,jk,angle_num,ndata,dim,out_xrot);
					Q_up = evqual(out_xrot,dim,ndata);
				   	MatrixInitZeros(out_xrot,ndata,dim);
					 /* move down */
              		p_theta_new[d] = p_theta[d] - alpha;
              		rotate_givens(mat,theta_new,ik,jk,angle_num,ndata,dim,out_xrot);
              		Q_down = evqual(out_xrot,dim,ndata);
              		MatrixInitZeros(out_xrot,ndata,dim);

	                /* update only if at least one of them is better */
    	            if( Q_up > Q || Q_down > Q)
    	            {
     	               if( Q_up > Q_down )
    	                { 
    	                    p_theta[d] = p_theta[d] + alpha;
    	                    p_theta_new[d] = p_theta[d];
    	                    Q = Q_up;
    	                }
						else 
						{
							p_theta[d] = p_theta[d] - alpha;
							p_theta_new[d] = p_theta[d];
						    Q = Q_down;
						}
					}
				} 
				else 
				{ /* descend through true derivative */
					alpha = 1.0;

					dQ = evqualitygrad(mat,theta,ik,jk,angle_num,d,dim,ndata);
					//cout<<"the dQ is \t "<<dQ<<endl;
					p_theta_new[d] = p_theta[d] - alpha * dQ;
               		rotate_givens(mat,theta_new,ik,jk,angle_num,ndata,dim,out_xrot);
					Q_new = evqual(out_xrot,dim,ndata);                                    
				    if( Q_new > Q)
					{
						p_theta[d] = p_theta_new[d];
						Q = Q_new;
					 }
					else
					{
						p_theta_new[d] = p_theta[d];
					}
               		MatrixInitZeros(out_xrot,dim,ndata);
				}
			}        
			/* stopping criteria */
			if( iter > 2 )
			{
				if( Q - Q_old2 < 1e-3 )
				{
		
					break;
				}
			 }

			Q_old2 = Q_old1;
			Q_old1 = Q;
    }
    rotate_givens(mat,theta_new,ik,jk,angle_num,ndata,dim,out_xrot);
    cluster_assign(out_xrot,out_clusts,dim,ndata);

    /* free allocated memory */

    delete [] theta;
    delete [] theta_new;
	delete [] ik;
    delete [] jk;
	return Q;
};