DenseMatrix project(RandomAccessIterator begin, RandomAccessIterator end, FeatureVectorCallback callback, IndexType dimension, const IndexType max_iter, const ScalarType epsilon, const IndexType target_dimension, const DenseVector& mean_vector) { timed_context context("Data projection"); // The number of data points const IndexType n = end-begin; // Dense representation of the data points DenseVector current_vector(dimension); DenseMatrix X = DenseMatrix::Zero(dimension,n); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback.vector(*iter,current_vector); X.col(iter-begin) = current_vector - mean_vector; } // Initialize FA model // Initial variances DenseMatrix sig = DenseMatrix::Identity(dimension,dimension); // Initial linear mapping DenseMatrix A = DenseMatrix::Random(dimension, target_dimension).cwiseAbs(); // Main loop IndexType iter = 0; DenseMatrix invC,M,SC; ScalarType ll = 0, newll = 0; while (iter < max_iter) { ++iter; // Perform E-step // Compute the inverse of the covariance matrix invC = (A*A.transpose() + sig).inverse(); M = A.transpose()*invC*X; SC = n*(DenseMatrix::Identity(target_dimension,target_dimension) - A.transpose()*invC*A) + M*M.transpose(); // Perform M-step A = (X*M.transpose())*SC.inverse(); sig = DenseMatrix(((X*X.transpose() - A*M*X.transpose()).diagonal()/n).asDiagonal()).array() + epsilon; // Compute log-likelihood of FA model newll = 0.5*(log(invC.determinant()) - (invC*X).cwiseProduct(X).sum()/n); // Check for convergence if ((iter > 1) && (fabs(newll - ll) < epsilon)) break; ll = newll; } return X.transpose()*A; }
DenseVector compute_mean(RandomAccessIterator begin, RandomAccessIterator end, FeatureVectorCallback callback, IndexType dimension) { DenseVector mean = DenseVector::Zero(dimension); DenseVector current_vector(dimension); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback(*iter,current_vector); mean += current_vector; } mean.array() /= (end-begin); return mean; }
DenseSymmetricMatrix compute_covariance_matrix(RandomAccessIterator begin, RandomAccessIterator end, const DenseVector& mean, FeatureVectorCallback callback, IndexType dimension) { timed_context context("Constructing PCA covariance matrix"); DenseSymmetricMatrix covariance_matrix = DenseSymmetricMatrix::Zero(dimension,dimension); DenseVector current_vector(dimension); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback(*iter,current_vector); covariance_matrix.selfadjointView<Eigen::Upper>().rankUpdate(current_vector,1.0); } covariance_matrix.selfadjointView<Eigen::Upper>().rankUpdate(mean,-1.0); return covariance_matrix; }
EmbeddingResult project(const ProjectionResult& projection_result, RandomAccessIterator begin, RandomAccessIterator end, FeatureVectorCallback callback, unsigned int dimension) { timed_context context("Data projection"); DenseVector current_vector(dimension); const DenseSymmetricMatrix& projection_matrix = projection_result.first; DenseMatrix embedding = DenseMatrix::Zero((end-begin),projection_matrix.cols()); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback(*iter,current_vector); embedding.row(iter-begin) = projection_matrix.transpose()*current_vector; } return EmbeddingResult(embedding,DenseVector()); }
DenseMatrix project(const DenseMatrix& projection_matrix, const DenseVector& mean_vector, RandomAccessIterator begin, RandomAccessIterator end, FeatureVectorCallback callback, IndexType dimension) { timed_context context("Data projection"); DenseVector current_vector(dimension); DenseVector current_vector_subtracted_mean(dimension); DenseMatrix embedding = DenseMatrix::Zero((end-begin),projection_matrix.cols()); for (RandomAccessIterator iter=begin; iter!=end; ++iter) { callback(*iter,current_vector); current_vector_subtracted_mean = current_vector - mean_vector; embedding.row(iter-begin) = projection_matrix.transpose()*current_vector_subtracted_mean; } return embedding; }
ImageRAII match( IplImage * image1, IplImage * image2, std::pair< CvMat *, CvMat * > image1_keys, std::pair< CvMat *, CvMat * > image2_keys ) { ImageRAII appended_images = appendimages( image1, image2 ); ImageRAII rgb_appended_images( cvCreateImage( cvGetSize( appended_images.image ), appended_images.image->depth, 3 ) ); cvCvtColor( appended_images.image, rgb_appended_images.image, CV_GRAY2RGB ); CvScalar red; red.val[2] = 255; std::vector< std::pair< int, int > > points; // check for matches with the vectors in image1 and image2 for( int i = 0; i < image1_keys.first->height; i++ ) { double magnitude1 = 0; MatrixRAII current_vector( cvCreateMat( 1, image1_keys.first->cols, CV_32FC1 ) ); // keeps track of minimum row found b/t image1 and image2 vectors MatrixRAII min( cvCreateMat( 1, image2_keys.first->cols, CV_32FC1 ) ); cvGetRow( image1_keys.first, current_vector.matrix, i ); CvPoint point1 = cvPoint( ( int )cvmGet( current_vector.matrix, 0, 1 ), ( int )cvmGet( current_vector.matrix, 0, 0 ) ); std::map< float, int > angles; for( int k = 0; k < image1_keys.second->width; k++ ) magnitude1 += pow( cvmGet( image1_keys.second, i, k ), 2 ); magnitude1 = cvSqrt( magnitude1 ); // compare a vector in image1 to every vector in image2 by calculating the cosine simularity for( int j = 0; j < image2_keys.first->height; j++ ) { MatrixRAII descriptor1( cvCreateMat( 1, image1_keys.second->cols, CV_32FC1 ) ); MatrixRAII descriptor2( cvCreateMat( 1, image2_keys.second->cols, CV_32FC1 ) ); cvGetRow( image1_keys.second, descriptor1.matrix, i ); cvGetRow( image2_keys.second, descriptor2.matrix, j ); double dot_product = cvDotProduct( descriptor1.matrix, descriptor2.matrix ); double magnitude2 = 0; for( int k = 0; k < image2_keys.second->width; k++ ) magnitude2 += pow( cvmGet( descriptor1.matrix, 0, k ), 2 ); magnitude2 = cvSqrt( magnitude2 ); angles.insert( std::pair< float, int >( acos( dot_product / ( magnitude1 * magnitude2 ) ), j ) ); } std::map< float, int >::iterator it = angles.begin(); int index = it->second; float angle = it->first; it++; if( angle < THRESHOLD * it->first ) { points.push_back( std::make_pair( i, index ) ); } } std::vector< std::pair< int, int > >::iterator it; for( it = points.begin(); it < points.end(); it++ ) { CvPoint point1 = cvPoint( ( int )cvmGet( image1_keys.first, it->first, 1 ), ( int )cvmGet( image1_keys.first, it->first, 0 ) ); CvPoint point2 = cvPoint( ( int )cvmGet( image2_keys.first, it->second, 1 ) + image1->width, ( int )cvmGet( image2_keys.first, it->second, 0 ) ); cvLine( rgb_appended_images.image, point1, point2, red ); } return rgb_appended_images; }