MachineABC* LeastSquareTrainer::Train(DataSet* pData) { LeastSquareMachine* pMachine=new LeastSquareMachine; Matd* m_pmData=new Matd((double**)pData->m_pprData, pData->m_nCount, pData->m_nDim); Vecd* m_pvObj=new Vecd((double*)pData->m_prCls, pData->m_nCount); Mat mB(m_pmData->Cols(), m_pmData->Cols(), MAT_Tdouble); MatOp::TrAA(&mB, m_pmData); mB.Invert(); Mat mTemp(m_pmData->Cols(), m_pmData->Rows(), MAT_Tdouble); Mat mTr(m_pmData->Cols(), m_pmData->Rows(), MAT_Tdouble); MatOp::Transpose (&mTr, m_pmData); MatOp::Mul(&mTemp, &mB, &mTr); pMachine->m_vCoeff.Create (m_pmData->Cols(), MAT_Tfloat); Vec vRet(m_pmData->Cols(), MAT_Tdouble); MatOp::Mul(&vRet, &mTemp, m_pvObj); for (int i = 0; i < vRet.Length(); i ++) pMachine->m_vCoeff.data.fl[i] = (float)vRet.data.db[i]; delete m_pmData; delete m_pvObj; return pMachine; }
var& var::operator = (const var& mVar) { if (&mVar != this) { var mTemp(mVar); swap(mTemp); } return *this; }
//Diskretisierter Zeitentwicklungsoperator Eigen::MatrixXcd S_H(double deltaT, std::function<double(int,int,double)> H, double dXi, double xiMax, double xiMin) { int n_max = floor((xiMax - xiMin + 3/2*dXi)/dXi); Eigen::MatrixXd mH(n_max,n_max); Eigen::MatrixXcd mS_H(n_max,n_max), mTemp(n_max,n_max), mTempi(n_max,n_max); for (int i = 0; i < n_max; i++) { for (int j = 0; j < n_max; j++) { mH(i,j) = H((i-floor(n_max/2)),(j-floor(n_max/2)),dXi); } } mTemp.real() = Eigen::MatrixXd::Identity(n_max,n_max); mTemp.imag() = -0.5*mH*deltaT; mTempi.real() = Eigen::MatrixXd::Identity(n_max,n_max); mTempi.imag() = 0.5*mH*deltaT; mS_H = mTempi.inverse() * mTemp; return mS_H; }
int LinearRegressorTrainer::Train (ClassifierABC* pMachine) { LinearRegressor* pRegressor = (LinearRegressor*)pMachine; int i; Mat mB(m_pmData->Cols(), m_pmData->Cols(), MAT_Tdouble); MatOp::TrAA(&mB, m_pmData); LUDecomposition lu(&mB); Mat mI(m_pmData->Cols(), m_pmData->Cols(), MAT_Tdouble); mI.Zero(); for (i = 0; i < mI.Rows(); i ++) mI.data.db[i][i] = 1.0; Mat* pmInverse = lu.Solve (&mI); if (pmInverse==0) return 0; Mat mTemp(m_pmData->Cols(), m_pmData->Rows(), MAT_Tdouble); Mat mTr(m_pmData->Cols(), m_pmData->Rows(), MAT_Tdouble); MatOp::Transpose (&mTr, m_pmData); MatOp::Mul(&mTemp, pmInverse, &mTr); pRegressor->m_vCoeff.Create (m_pmData->Cols(), MAT_Tfloat); Vec vRet(m_pmData->Cols(), MAT_Tdouble); MatOp::Mul(&vRet, &mTemp, m_pvObj); for (i = 0; i < vRet.Length(); i ++) pRegressor->m_vCoeff.data.fl[i] = (float)vRet.data.db[i]; ReleaseMat(pmInverse); mTemp.Release(); mTr.Release(); mI.Release(); mB.Release(); return 1; }
XMATRIX& XMATRIX::operator -= ( const XMATRIX &pIn ) { XMATRIX mTemp(*this); *this = mTemp-pIn; return *this; }
// input: the pressure data, after static calibration (tare) but otherwise raw. // input feeds a state machine that first collects a normalization map, then // collects a touch shape, or kernel, at each point. int TouchTracker::Calibrator::addSample(const MLSignal& m) { int r = 0; static Vec2 intPeak1; static MLSignal f2(mSrcWidth, mSrcHeight); static MLSignal input(mSrcWidth, mSrcHeight); static MLSignal tare(mSrcWidth, mSrcHeight); static MLSignal normTemp(mSrcWidth, mSrcHeight); // decreasing this will collect a wider area during normalization, // smoothing the results. const float kNormalizeThreshold = 0.125f; float kc, ke, kk; kc = 4./16.; ke = 2./16.; kk=1./16.; // simple lopass time filter for calibration f2 = m; f2.subtract(mFilteredInput); f2.scale(0.1f); mFilteredInput.add(f2); input = mFilteredInput; input.sigMax(0.); // get peak of sample data Vec3 testPeak = input.findPeak(); float peakZ = testPeak.z(); const int startupSamples = 1000; const int waitAfterNormalize = 2000; if (mTotalSamples < startupSamples) { age = 0; mStartupSum += peakZ; if(mTotalSamples % 100 == 0) { MLConsole() << "."; } } else if (mTotalSamples == startupSamples) { age = 0; //mAutoThresh = kNormalizeThresh; mAutoThresh = mStartupSum / (float)startupSamples * 10.f; MLConsole() << "\n****************************************************************\n\n"; MLConsole() << "OK, done collecting silence (auto threshold: " << mAutoThresh << "). \n"; MLConsole() << "Now please slide your palm across the surface, \n"; MLConsole() << "applying a firm and even pressure, until all the rectangles \n"; MLConsole() << "at left turn blue. \n\n"; mNormalizeMap.clear(); mNormalizeCount.clear(); mCollectingNormalizeMap = true; } else if (mCollectingNormalizeMap) { // smooth temp signal, duplicating values at border normTemp.copy(input); normTemp.convolve3x3rb(kc, ke, kk); normTemp.convolve3x3rb(kc, ke, kk); normTemp.convolve3x3rb(kc, ke, kk); if(peakZ > mAutoThresh) { // collect additions in temp signals mTemp.clear(); // adds to map mTemp2.clear(); // adds to sample count // where input > thresh and input is near max current input, add data. for(int j=0; j<mHeight; ++j) { for(int i=0; i<mWidth; ++i) { // test threshold with smoothed data float zSmooth = normTemp(i, j); // but add actual samples from unsmoothed input float z = input(i, j); if(zSmooth > peakZ * kNormalizeThreshold) { // map must = count * z/peakZ mTemp(i, j) = z / peakZ; mTemp2(i, j) = 1.0f; } } } // add temp signals to data mNormalizeMap.add(mTemp); mNormalizeCount.add(mTemp2); mVisSignal.copy(mNormalizeCount); mVisSignal.scale(1.f / (float)kNormMapSamples); } if(doneCollectingNormalizeMap()) { float mapMaximum = makeNormalizeMap(); MLConsole() << "\n****************************************************************\n\n"; MLConsole() << "\n\nOK, done collecting normalize map. (max = " << mapMaximum << ").\n"; MLConsole() << "Please lift your hands."; mCollectingNormalizeMap = false; mWaitSamplesAfterNormalize = 0; mVisSignal.clear(); mStartupSum = 0; } } else { if(mWaitSamplesAfterNormalize < waitAfterNormalize) { mStartupSum += peakZ; mWaitSamplesAfterNormalize++; if(mTotalSamples % 100 == 0) { MLConsole() << "."; } } else if(mWaitSamplesAfterNormalize == waitAfterNormalize) { mWaitSamplesAfterNormalize++; mAutoThresh *= 1.5f; MLConsole() << "\nOK, done collecting silence again (auto threshold: " << mAutoThresh << "). \n"; MLConsole() << "\n****************************************************************\n\n"; MLConsole() << "Now please slide a single finger over the \n"; MLConsole() << "Soundplane surface, visiting each area twice \n"; MLConsole() << "until all the areas are colored green at left. \n"; MLConsole() << "Sliding over a key the first time will turn it gray. \n"; MLConsole() << "Sliding over a key the second time will turn it green.\n"; MLConsole() << "\n"; } else if(peakZ > mAutoThresh) { // normalize input mTemp.copy(input); mTemp.multiply(mNormalizeMap); // smooth input mTemp.convolve3x3r(kc, ke, kk); mTemp.convolve3x3r(kc, ke, kk); mTemp.convolve3x3r(kc, ke, kk); // get corrected peak mPeak = mTemp.findPeak(); mPeak = mTemp.correctPeak(mPeak.x(), mPeak.y()); Vec2 minPos(2.0, 0.); Vec2 maxPos(mWidth - 2., mHeight - 1.); mPeak = vclamp(mPeak, minPos, maxPos); age++; // continue touch // get sample from input around peak and normalize mIncomingSample.clear(); mIncomingSample.add2D(m, -mPeak + Vec2(kTemplateRadius, kTemplateRadius)); mIncomingSample.sigMax(0.f); mIncomingSample.scale(1.f / mIncomingSample(kTemplateRadius, kTemplateRadius)); // get integer bin Vec2 binPeak = getBinPosition(mPeak); mVisPeak = binPeak - Vec2(0.5, 0.5); int bix = binPeak.x(); int biy = binPeak.y(); // clamp to calibratable area bix = clamp(bix, 2, mWidth - 2); biy = clamp(biy, 0, mHeight - 1); Vec2 bIntPeak(bix, biy); // count sum and minimum of all kernel samples for the bin int dataIdx = biy*mWidth + bix; mDataSum[dataIdx].add(mIncomingSample); mData[dataIdx].sigMin(mIncomingSample); mSampleCount[dataIdx]++; if(bIntPeak != intPeak1) { // entering new bin. intPeak1 = bIntPeak; if(mPassesCount[dataIdx] < kPassesToCalibrate) { mPassesCount[dataIdx]++; mVisSignal(bix, biy) = (float)mPassesCount[dataIdx] / (float)kPassesToCalibrate; } } // check for done if(isDone()) { mCalibrateSignal.setDims(kTemplateSize, kTemplateSize, mWidth*mHeight); // get result for each junction for(int j=0; j<mHeight; ++j) { for(int i=0; i<mWidth; ++i) { int idx = j*mWidth + i; // copy to 3d signal mCalibrateSignal.setFrame(idx, mData[idx]); } } getAverageTemplateDistance(); mHasCalibration = true; mActive = false; r = 1; MLConsole() << "\n****************************************************************\n\n"; MLConsole() << "Calibration is now complete and will be auto-saved in the file \n"; MLConsole() << "SoundplaneAppState.txt. \n"; MLConsole() << "\n****************************************************************\n\n"; } } else { age = 0; intPeak1 = Vec2(-1, -1); mVisPeak = Vec2(-1, -1); } } mTotalSamples++; return r; }