matrix::matrix(long rows, long cols, const dvector &value) : data(vector<dvector>(rows)), colNum(cols) { for(long i=0; i<rows; i++){ data.at(i).resize(cols); for(long j=0; j<cols; j++){ data.at(i).at(j) = value.at(i * cols + j); } } }
matrix::matrix(const dvector &vec, bool isRow) : data(vector<dvector>(isRow? 1: vec.size())), colNum(isRow? vec.size(): 1) { if(isRow) { data.front() = vec; } else { for(long i = 0; i < (signed) vec.size(); i++) { data.at(i).resize(1); data.at(i).front() = vec.at(i); } } }
/* * compute the error using the last propagated input and the given * pattern */ bool MLP::computePatternError(const int id, const dvector& outUnits, double& error) const { const int lastIdx = outUnits.size(); int j; double tmp; error = 0.0; for (j=0;j<lastIdx;++j) { tmp = (outUnits.at(j)-((j==id)?on:off)); error += tmp*tmp; } error *= 0.5; return true; }
/* * calculate gradient of error surface using back-propagation algorithm * * @param input input vector * @param outputId desired output. This value must be between 0 and * the number of output elements-1. * @param grad computed gradient of the error surface * @return true if successful, or false otherwise. */ bool MLP::calcGradient(const dvector& input, const int outputId, dvector& grad) { const parameters& param = getParameters(); const int layers = param.hiddenUnits.size()+1; propagate(input); grad.resize(weights.size()); int i,j,jj,k,idx,lastIdx; int layer = layerIndex.size()-1; double delta; // compute f'(net) at unitsNet for (i=0;i<layers;++i) { param.activationFunctions[i]->deriv(unitsNet[i]); } // --------------------------------------------- // gradient for the elements of the output layer // --------------------------------------------- const dmatrix& outMat = matWeights[layer]; const dvector* theInput = 0; if (layer>0) { theInput = &unitsOut[layer-1]; } else { theInput = &input; } idx = layerIndex.at(layer); dvector lastDeltas,newDeltas; lastDeltas.resize(outMat.rows(),0,false,false); for (j=0;j<outMat.rows();++j) { delta = ((((j==outputId)?on:off) - unitsOut[layer].at(j)) * unitsNet[layer].at(j)); lastDeltas.at(j)=delta; grad.at(idx)=delta; // bias = 1.0 ++idx; for (i=0;i<theInput->size();++i,++idx) { // idx means layerIndex.at(layer)+i+j*ROWS grad.at(idx) = delta*theInput->at(i); } } // ---------------------------------------------- // gradient for the elements of the hidden layers // ---------------------------------------------- --layer; while (layer>=0) { const dmatrix& outMat = matWeights[layer]; const dmatrix& lastMat = matWeights[layer+1]; const dvector* theInput = 0; if (layer>0) { theInput = &unitsOut[layer-1]; } else { theInput = &input; } idx = layerIndex.at(layer); lastIdx = theInput->size(); newDeltas.resize(outMat.rows(),0.0,false,false); for (j=0,jj=1;j<outMat.rows();++j,++jj) { delta = 0; for (k=0;k<lastMat.rows();++k) { delta+=(lastDeltas.at(k)*lastMat.at(k,jj)); } delta*=unitsNet[layer].at(j); newDeltas.at(j)=delta; grad.at(idx)=delta; // bias = 1.0 ++idx; for (i=0;i<lastIdx;++i,++idx) { // idx means layerIndex.at(layer)+i+j*ROWS grad.at(idx) = delta*theInput->at(i); } } newDeltas.detach(lastDeltas); // continue with next layer --layer; }; return true; }
bool brightRGB::getMedian(const image& img,dvector& dest) const{ // image empty? if (img.empty()) { setStatusString("image empty"); dest.resize(0); return false; } const rgbPixel transColor = getParameters().transColor; dest.resize(3); ivector hist0(256,0); ivector hist1(256,0); ivector hist2(256,0); image::const_iterator it = img.begin(); if(getParameters().transparent) { while(it != img.end()) { if(*it != transColor) { ++hist0.at((*it).getRed()); ++hist1.at((*it).getGreen()); ++hist2.at((*it).getBlue()); } it++; } const int counterHalf = hist0.sumOfElements()/2; // check for complete image transparent if (counterHalf==0) { setStatusString("only transparent pixels"); dest.resize(0); return false; } int i,s; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist0.at(i); } dest.at(0) = i-1; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist1.at(i); } dest.at(1) = i-1; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist2.at(i); } dest.at(2) = i-1; } else { // no transparent color while(it != img.end()) { ++hist0.at((*it).getRed()); ++hist1.at((*it).getGreen()); ++hist2.at((*it).getBlue()); it++; } const int counterHalf = img.columns()*img.rows()/2; int i,s; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist0.at(i); } dest.at(0) = i-1; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist1.at(i); } dest.at(1) = i-1; i=-1,s=0; while(++i<256 && s<counterHalf) { s += hist2.at(i); } dest.at(2) = i-1; } // normalize to 0..1 dest.divide(255); return true; };
// On copy apply for type image! bool histogramRGBL::apply(const image& src,dvector& dest) const { if (src.empty()) { dest.clear(); setStatusString("input channel empty"); return false; } const parameters& param = getParameters(); int theMin(0),theMax(255); const int lastIdx = param.cells-1; const float m = float(lastIdx)/(theMax-theMin); int y,r,g,b,l; int idx; int entries; vector<rgbPixel>::const_iterator it,eit; dest.resize(4*param.cells,0.0,false,true); // initialize with 0 dvector theR(param.cells,0.0); dvector theG(param.cells,0.0); dvector theB(param.cells,0.0); dvector theL(param.cells,0.0); entries = 0; // if b too small, it's possible to calculate everything faster... // check if the ignore value if (param.considerAllData) { for (y=0;y<src.rows();++y) { const vector<rgbPixel>& vct = src.getRow(y); for (it=vct.begin(),eit=vct.end();it!=eit;++it) { r = (*it).getRed(); g = (*it).getGreen(); b = (*it).getBlue(); l = (min(r,g,b)+max(r,g,b))/2; idx = static_cast<int>(r*m); theR.at(idx)++; idx = static_cast<int>(g*m); theG.at(idx)++; idx = static_cast<int>(b*m); theB.at(idx)++; idx = static_cast<int>(l*m); theL.at(idx)++; entries++; } } } else { for (y=0;y<src.rows();++y) { const vector<rgbPixel>& vct = src.getRow(y); for (it=vct.begin(),eit=vct.end();it!=eit;++it) { if ((*it) != param.ignoreValue) { r = (*it).getRed(); g = (*it).getGreen(); b = (*it).getBlue(); l = (min(r,g,b)+max(r,g,b))/2; idx = static_cast<int>(r*m); theR.at(idx)++; idx = static_cast<int>(g*m); theG.at(idx)++; idx = static_cast<int>(b*m); theB.at(idx)++; idx = static_cast<int>(l*m); theL.at(idx)++; entries++; } } } } if (param.smooth) { convolution convolver; convolution::parameters cpar; cpar.boundaryType = lti::Mirror; cpar.setKernel(param.kernel); convolver.setParameters(cpar); matrix<double> tmp; tmp.useExternData(4,param.cells,&dest.at(0)); convolver.apply(theR,tmp.getRow(0)); convolver.apply(theG,tmp.getRow(1)); convolver.apply(theB,tmp.getRow(2)); convolver.apply(theL,tmp.getRow(3)); } else { dest.fill(theR,0); dest.fill(theG,param.cells); dest.fill(theB,2*param.cells); dest.fill(theL,3*param.cells); } if (param.normalize) { if (entries > 0) { dest.divide(entries); } } return true; };