/** * Construct the exact kernel matrix. * * @param data Input data points. * @param transformedData Matrix to output results into. * @param eigval KPCA eigenvalues will be written to this vector. * @param eigvec KPCA eigenvectors will be written to this matrix. * @param rank Rank to be used for matrix approximation. * @param kernel Kernel to be used for computation. */ static void ApplyKernelMatrix(const arma::mat& data, arma::mat& transformedData, arma::vec& eigval, arma::mat& eigvec, const size_t /* unused */, KernelType kernel = KernelType()) { // Construct the kernel matrix. arma::mat kernelMatrix; // Resize the kernel matrix to the right size. kernelMatrix.set_size(data.n_cols, data.n_cols); // Note that we only need to calculate the upper triangular part of the // kernel matrix, since it is symmetric. This helps minimize the number of // kernel evaluations. for (size_t i = 0; i < data.n_cols; ++i) { for (size_t j = i; j < data.n_cols; ++j) { // Evaluate the kernel on these two points. kernelMatrix(i, j) = kernel.Evaluate(data.unsafe_col(i), data.unsafe_col(j)); } } // Copy to the lower triangular part of the matrix. for (size_t i = 1; i < data.n_cols; ++i) for (size_t j = 0; j < i; ++j) kernelMatrix(i, j) = kernelMatrix(j, i); // For PCA the data has to be centered, even if the data is centered. But it // is not guaranteed that the data, when mapped to the kernel space, is also // centered. Since we actually never work in the feature space we cannot // center the data. So, we perform a "psuedo-centering" using the kernel // matrix. arma::rowvec rowMean = arma::sum(kernelMatrix, 0) / kernelMatrix.n_cols; kernelMatrix.each_col() -= arma::sum(kernelMatrix, 1) / kernelMatrix.n_cols; kernelMatrix.each_row() -= rowMean; kernelMatrix += arma::sum(rowMean) / kernelMatrix.n_cols; // Eigendecompose the centered kernel matrix. arma::eig_sym(eigval, eigvec, kernelMatrix); // Swap the eigenvalues since they are ordered backwards (we need largest to // smallest). for (size_t i = 0; i < floor(eigval.n_elem / 2.0); ++i) eigval.swap_rows(i, (eigval.n_elem - 1) - i); // Flip the coefficients to produce the same effect. eigvec = arma::fliplr(eigvec); transformedData = eigvec.t() * kernelMatrix; transformedData.each_col() /= arma::sqrt(eigval); }
PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* filterBuilder) { FilterEffect* input1 = filterBuilder->getEffectById(in1()); if (!input1) return 0; Vector<float> kernelMatrixValues; SVGNumberList* numbers = kernelMatrix(); ExceptionCode ec = 0; int numberOfItems = numbers->numberOfItems(); for (int i = 0; i < numberOfItems; ++i) kernelMatrixValues.append(numbers->getItem(i, ec)); int orderXValue = orderX(); int orderYValue = orderY(); if (!hasAttribute(SVGNames::orderAttr)) { orderXValue = 3; orderYValue = 3; } // The spec says this is a requirement, and should bail out if fails if (orderXValue * orderYValue != numberOfItems) return 0; int targetXValue = targetX(); int targetYValue = targetY(); if (hasAttribute(SVGNames::targetXAttr) && (targetXValue < 0 || targetXValue >= orderXValue)) return 0; // The spec says the default value is: targetX = floor ( orderX / 2 )) if (!hasAttribute(SVGNames::targetXAttr)) targetXValue = static_cast<int>(floorf(orderXValue / 2)); if (hasAttribute(SVGNames::targetYAttr) && (targetYValue < 0 || targetYValue >= orderYValue)) return 0; // The spec says the default value is: targetY = floor ( orderY / 2 )) if (!hasAttribute(SVGNames::targetYAttr)) targetYValue = static_cast<int>(floorf(orderYValue / 2)); float divisorValue = divisor(); if (hasAttribute(SVGNames::divisorAttr) && !divisorValue) return 0; if (!hasAttribute(SVGNames::divisorAttr)) { for (int i = 0; i < numberOfItems; ++i) divisorValue += kernelMatrixValues[i]; if (!divisorValue) divisorValue = 1; } RefPtr<FilterEffect> effect = FEConvolveMatrix::create( IntSize(orderXValue, orderYValue), divisorValue, bias(), IntPoint(targetXValue, targetYValue), static_cast<EdgeModeType>(edgeMode()), FloatPoint(kernelUnitLengthX(), kernelUnitLengthX()), preserveAlpha(), kernelMatrixValues); effect->inputEffects().append(input1); return effect.release(); }
void KernelMatrixCalculator::kernelMatrixGenerate(){ cout << "Inizio Generazione Matrice Kernel"<< endl; string pathTotale= pathDestination+"/"+nameFile+".ker"; ofstream kernelMatrix (pathTotale.c_str(), ios::out| ios::binary); int size=vectorMRH.size(); kernelMatrix.write((char *) &size, sizeof( size )); BinWeightScheme binWeightScheme=BIN_WEIGHT_GLOBAL; //TODO capire che è sto BinWeightScheme double similarity; for ( int i = 0; i < vectorMRH.size(); i++) { for (int j = 0; j <= i; j++) { similarity=PyramidMatcher::GetPyramidMatchSimilarity (*(vectorMRH[i]),*(vectorMRH[j]),binWeightScheme); kernelMatrix.write((char *) &similarity, sizeof( similarity )); } if (i%200==0) cout << "Finita riga: "<< i <<endl; } kernelMatrix.close(); cout << "Matrice di Kernel salvata in "<<pathTotale << endl; }
void KernelMatrixCalculator::saveKernelMatrix(){ cout << "Inizio Generazione Matrice Kernel"<< endl; string pathTotale= pathDestination+"/"+nameFile+".ker"; ofstream kernelMatrix (pathTotale.c_str(), ios::out| ios::binary); int size=vectorMRH.size(); kernelMatrix.write((char *) &size, sizeof( size )); BinWeightScheme binWeightScheme=BIN_WEIGHT_GLOBAL; //TODO capire che è sto BinWeightScheme for ( int i = 0; i < vectorMRH.size(); i++) { for (int j = 0; j <= i; j++) { kernelMatrix.write((char *) &this->kernelMatrix->at(i,j), sizeof( this->kernelMatrix->at(i,j) )); } if (i%200==0) cout << "Finita riga: "<< i <<endl; } kernelMatrix.close(); cout << "Matrice di Kernel salvata in "<<pathTotale << endl; }