/*******M step, maximazize log-likelihood*/ void Plsa::M_step(MatrixXd &data) { MatrixXd X; for (int i=0;i<K;i++) { Pw_z.col(i)=(Pz_wd[i].cwiseProduct(data)).rowwise().sum();//suma de filas[vector(1XN)] Pd_z.col(i)=(Pz_wd[i].cwiseProduct(data)).colwise().sum();//suma de columnas[vector(1XN)] } //normalize RowVectorXd Temp; RowVectorXd C; VectorXd E; VectorXd T; Temp=RowVectorXd::Ones(K); T=VectorXd::Ones(K); // vector of K with ones P_z=Pd_z.colwise().sum(); cout<<P_z; C=Pd_z.colwise().sum(); //suma de columnas[vector(1XN)] Temp=Temp.cwiseQuotient(C); Pd_z=Pd_z*(Temp.asDiagonal()); C=Pw_z.colwise().sum(); // Temp=Temp.cwiseQuotient(C); Pw_z=Pw_z*(Temp.asDiagonal()); E=P_z.rowwise().sum(); P_z=P_z.cwiseProduct(T.cwiseQuotient(E)); }
/* compares evaluations on corner cases */ void eval_spline3d_onbrks() { Spline3d spline = spline3d(); RowVectorXd u = spline.knots(); MatrixXd pts(11,3); pts << 0.959743958516081, 0.340385726666133, 0.585267750979777, 0.959743958516081, 0.340385726666133, 0.585267750979777, 0.959743958516081, 0.340385726666133, 0.585267750979777, 0.430282980289940, 0.713074680056118, 0.720373307943349, 0.558074875553060, 0.681617921034459, 0.804417124839942, 0.407076008291750, 0.349707710518163, 0.617275937419545, 0.240037008286602, 0.738739390398014, 0.324554153129411, 0.302434111480572, 0.781162443963899, 0.240177089094644, 0.251083857976031, 0.616044676146639, 0.473288848902729, 0.251083857976031, 0.616044676146639, 0.473288848902729, 0.251083857976031, 0.616044676146639, 0.473288848902729; pts.transposeInPlace(); for (int i=0; i<u.size(); ++i) { Vector3d pt = spline(u(i)); VERIFY( (pt - pts.col(i)).norm() < 1e-14 ); } }
void Plsa::Normalize(MatrixXd &Mat) { RowVectorXd Temp; Temp=RowVectorXd::Ones(K); Temp=Temp.cwiseQuotient(Mat.colwise().sum()); Mat=Mat*Temp.asDiagonal(); }
void RelativeEulerAnglePcaDecoder::Encode(array_view<const DirectX::Quaternion> rots, VectorType & x) { RelativeEulerAngleDecoder::Encode(rots, x); RowVectorXd dx = x.transpose().cast<double>(); dx -= meanY; dx *= pcaY; x = dx.transpose().cast<float>(); }
QMap<int,QList<QPair<int,double> > > DetectTrigger::detectTriggerFlanksGrad(const MatrixXd& data, const QList<int>& lTriggerChannels, int iOffsetIndex, double dThreshold, bool bRemoveOffset, const QString& type, int iBurstLengthSamp) { QMap<int,QList<QPair<int,double> > > qMapDetectedTrigger; RowVectorXd tGradient = RowVectorXd::Zero(data.cols()); //Find all triggers above threshold in the data block for(int i = 0; i < lTriggerChannels.size(); ++i) { // QTime time; // time.start(); int iChIdx = lTriggerChannels.at(i); //Add empty list to map QList<QPair<int,double> > temp; qMapDetectedTrigger.insert(iChIdx, temp); //detect the actual triggers in the current data matrix if(iChIdx > data.rows() || iChIdx < 0) { return qMapDetectedTrigger; } //Compute gradient for(int t = 1; t<tGradient.cols(); t++) { tGradient(t) = data(iChIdx,t)-data(iChIdx,t-1); } // If falling flanks are to be detected flip the gradient's sign if(type == "Falling") { tGradient = tGradient * -1; } //Find positive maximum in gradient vector. This position is equal to the rising trigger flank. for(int j = 0; j < tGradient.cols(); ++j) { double dMatVal = bRemoveOffset ? tGradient(j) - data(iChIdx,0) : tGradient(j); if(dMatVal >= dThreshold) { QPair<int,double> pair; pair.first = iOffsetIndex+j; pair.second = tGradient(j); qMapDetectedTrigger[iChIdx].append(pair); j += iBurstLengthSamp; } } // int timeElapsed = time.elapsed(); // std::cout<<"timeElapsed: "<<timeElapsed<<std::endl; } return qMapDetectedTrigger; }
RowVectorXd FilterData::applyFFTFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const { #ifdef EIGEN_FFTW_DEFAULT fftw_make_planner_thread_safe(); #endif if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData) { qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols()); return data; } // std::cout<<"m_iFFTlength: "<<m_iFFTlength<<std::endl; // std::cout<<"2*m_dCoeffA.cols() + data.cols(): "<<2*m_dCoeffA.cols() + data.cols()<<std::endl; if(2*m_dCoeffA.cols() + data.cols()>m_iFFTlength) { qDebug()<<"Error in FilterData: Number of mirroring/zeropadding size plus data size is bigger then fft length!"; return data; } //Do zero padding or mirroring depending on user input RowVectorXd t_dataZeroPad = RowVectorXd::Zero(m_iFFTlength); switch(compensateEdgeEffects) { case MirrorData: t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse(); //front t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data; //middle t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse(); //back break; case ZeroPad: t_dataZeroPad.head(data.cols()) = data; break; default: t_dataZeroPad.head(data.cols()) = data; break; } //generate fft object Eigen::FFT<double> fft; fft.SetFlag(fft.HalfSpectrum); //fft-transform data sequence RowVectorXcd t_freqData; fft.fwd(t_freqData,t_dataZeroPad); //perform frequency-domain filtering RowVectorXcd t_filteredFreq = m_dFFTCoeffA.array()*t_freqData.array(); //inverse-FFT RowVectorXd t_filteredTime; fft.inv(t_filteredTime,t_filteredFreq); //Return filtered data if(!keepOverhead) return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols()); return t_filteredTime.head(data.cols()+m_dCoeffA.cols()); }
QPair< int,QList<double> > BCI::applyFeatureCalcConcurrentlyOnSensorLevel(const QPair<int, RowVectorXd> &chdata) { RowVectorXd data = chdata.second; QList<double> features; // TODO: Divide into subsignals //features << data.squaredNorm(); // Compute variance features << abs(log10(data.squaredNorm())); // Compute log of variance return QPair< int,QList<double> >(chdata.first, features); }
RowVectorXd DataPackage::cutData(const RowVectorXd &originalData, int cutFront, int cutBack) { if(originalData.cols()-cutFront-cutBack < 0 || cutFront>originalData.cols()) { qDebug()<<"DataPackage::cutData - cutFront or cutBack do not fit. Aborting mapping and returning original data."; RowVectorXd returnVec = originalData; return returnVec; } //Cut original data using segment return (RowVectorXd)originalData.segment(cutFront, originalData.cols()-cutFront-cutBack); }
CDataObject::CDataObject(int total_pts, enumStreetIndices br_ndx, int times_acted, int ndealt, eBetType action_type) : m_npoints(total_pts), m_br(br_ndx), m_nacted(times_acted), m_ndealt(ndealt), m_action(action_type) { assert(br_ndx >= ePreflopIndex && br_ndx < eRoundIndices); assert(times_acted >= 0); m_ndims = times_acted + (br_ndx == ePreflopIndex ? num_prior_dims_preflop : num_prior_dims_postflop) + 1; // this is only used for ann m_data = new double*[m_npoints]; // allocate hand_ids for corresponding data points m_hand_ids = new long[m_npoints]; for(long i = 0; i < m_npoints; i++) m_hand_ids[i] = -1L; m_profits = VectorXd::Zero(m_npoints); m_points = Matrix<double, Dynamic, Dynamic, RowMajor>::Zero(m_npoints, m_ndims); CDatabase p_db; GetData(&p_db); // Set the weights diag_factor = Matrix<double, Dynamic, Dynamic, RowMajor>::Identity(m_ndims, m_ndims); #ifdef KASPER_WEIGHTS RowVectorXd tmp; if(ePreflopIndex == br_ndx) { tmp = RowVectorXd::Zero(9); tmp << 10, 20, 100, 10, 0, 0, 2, 2, 20; } else { tmp = RowVectorXd::Zero(11); tmp << 10, 80, 10, 0, 0, 0, 2, 2, 50, 1, 1; } diag_factor.bottomRightCorner(tmp.cols(), tmp.cols()) = tmp.asDiagonal(); #else FeatureNormalize(); CRegressionObject regress(m_points, m_profits); diag_factor = regress.get_theta().asDiagonal(); #endif gLog.WriteLog(eSeverityInfo, eCatPerformance, "br%d_%d: %8s - %8d points\n", br_ndx+1, times_acted, bets_str[action_type], m_npoints); }
void IKoptions::setAdditionaltSamples(const RowVectorXd &t_samples) { if (t_samples.size() > 0) { set<double> unique_sort_t(t_samples.data(), t_samples.data() + t_samples.size()); this->additional_tSamples.resize(unique_sort_t.size()); int t_idx = 0; for (auto it = unique_sort_t.begin(); it != unique_sort_t.end(); it++) { this->additional_tSamples(t_idx) = *it; t_idx++; } } else { this->additional_tSamples.resize(0); } }
QPair<int,double> ConnectivityMeasures::calcCrossCorrelation(const RowVectorXd& vecFirst, const RowVectorXd& vecSecond) { Eigen::FFT<double> fft; int N = std::max(vecFirst.cols(), vecSecond.cols()); //Compute the FFT size as the "next power of 2" of the input vector's length (max) int b = ceil(log2(2.0 * N - 1)); int fftsize = pow(2,b); // int end = fftsize - 1; // int maxlag = N - 1; //Zero Padd RowVectorXd xCorrInputVecFirst = RowVectorXd::Zero(fftsize); xCorrInputVecFirst.head(vecFirst.cols()) = vecFirst; RowVectorXd xCorrInputVecSecond = RowVectorXd::Zero(fftsize); xCorrInputVecSecond.head(vecSecond.cols()) = vecSecond; //FFT for freq domain to both vectors RowVectorXcd freqvec; RowVectorXcd freqvec2; fft.fwd(freqvec, xCorrInputVecFirst); fft.fwd(freqvec2, xCorrInputVecSecond); //Create conjugate complex freqvec2.conjugate(); //Main step of cross corr for (int i = 0; i < fftsize; i++) { freqvec[i] = freqvec[i] * freqvec2[i]; } RowVectorXd result; fft.inv(result, freqvec); //Will get rid of extra zero padding RowVectorXd result2 = result;//.segment(maxlag, N); QPair<int,int> minMaxRange; int idx = 0; result2.minCoeff(&idx); minMaxRange.first = idx; result2.maxCoeff(&idx); minMaxRange.second = idx; // std::cout<<"result2(minMaxRange.first)"<<result2(minMaxRange.first)<<std::endl; // std::cout<<"result2(minMaxRange.second)"<<result2(minMaxRange.second)<<std::endl; // std::cout<<"b"<<b<<std::endl; // std::cout<<"fftsize"<<fftsize<<std::endl; // std::cout<<"end"<<end<<std::endl; // std::cout<<"maxlag"<<maxlag<<std::endl; //Return val int resultIndex = minMaxRange.second; double maxValue = result2(resultIndex); return QPair<int,double>(resultIndex, maxValue); }
void PatchSample::sample_frustum(double hfov, double vfov, int nh, int nv, Vector3d p, Vector3d u, MatrixXd &mx, MatrixXd &my, MatrixXd &mz) { //TBD: check input args // pointing, up, left p = p/p.norm(); u = u/u.norm(); Vector3d l = u.cross(p); // sample like a camera would double ll = (tan(hfov/2.0)*((double)(nh-1)))/nh; double uu = (tan(vfov/2.0)*((double)(nv-1)))/nv; RowVectorXd y; y.setLinSpaced(nh,-ll,ll); MatrixXd yy; yy = y.replicate(nv,1); VectorXd z; z.setLinSpaced(nv,-uu,uu); MatrixXd zz; zz = z.replicate(1,nh); MatrixXd xx = MatrixXd::Ones(nv,nh); MatrixXd nn = (xx.array().square() + yy.array().square() + zz.array().square()).cwiseSqrt(); xx = xx.array() / nn.array(); yy = yy.array() / nn.array(); zz = zz.array() / nn.array(); // rotation matrix Matrix3d rr; rr << p, l, u; // rotate points MatrixXd xyz; MatrixXd cam (3,xx.rows()*xx.cols()); cam.row(0) = vectorizeColWise(xx); cam.row(1) = vectorizeColWise(yy); cam.row(2) = vectorizeColWise(zz); xyz = rr*cam; // extract coordinates xx = xyz.row(0); yy = xyz.row(1); zz = xyz.row(2); mx = Map<MatrixXd>(xx.data(),nv,nh); my = Map<MatrixXd>(yy.data(),nv,nh); mz = Map<MatrixXd>(zz.data(),nv,nh); }
QList<QPair<int,double> > DetectTrigger::detectTriggerFlanksGrad(const MatrixXd &data, int iTriggerChannelIdx, int iOffsetIndex, double dThreshold, bool bRemoveOffset, const QString& type, int iBurstLengthSamp) { QList<QPair<int,double> > lDetectedTriggers; RowVectorXd tGradient = RowVectorXd::Zero(data.cols()); // QTime time; // time.start(); //detect the actual triggers in the current data matrix if(iTriggerChannelIdx > data.rows() || iTriggerChannelIdx < 0) { return lDetectedTriggers; } //Compute gradient for(int t = 1; t < tGradient.cols(); ++t) { tGradient(t) = data(iTriggerChannelIdx,t) - data(iTriggerChannelIdx,t-1); } //If falling flanks are to be detected flip the gradient's sign if(type == "Falling") { tGradient = tGradient * -1; } //Find all triggers above threshold in the data block for(int j = 0; j < tGradient.cols(); ++j) { double dMatVal = bRemoveOffset ? tGradient(j) - data(iTriggerChannelIdx,0) : tGradient(j); if(dMatVal >= dThreshold) { QPair<int,double> pair; pair.first = iOffsetIndex+j; pair.second = tGradient(j); lDetectedTriggers.append(pair); j += iBurstLengthSamp; } } // int timeElapsed = time.elapsed(); // std::cout<<"timeElapsed: "<<timeElapsed<<std::endl; return lDetectedTriggers; }
VectorXd probutils::mahaldist ( const MatrixXd& X, const RowVectorXd& mu, const MatrixXd& A ) { // Check for same number of dimensions, D if((X.cols() != mu.cols()) || (X.cols() != A.cols())) throw invalid_argument("Arguments do not have the same dimensionality"); // Check if A is square if (A.rows() != A.cols()) throw invalid_argument("Matrix A must be square!"); // Decompose A LDLT<MatrixXd> Aldl(A); // Check if A is PD if ((Aldl.vectorD().array() <= 0).any() == true) throw invalid_argument("Matrix A is not positive definite"); // Do the Mahalanobis distance for each sample (N times) MatrixXd X_mu = (X.rowwise() - mu).transpose(); return ((X_mu.array() * (Aldl.solve(X_mu)).array()) .colwise().sum()).transpose(); }
void FrequencySpectrumDelegate::createPlotPath(const QModelIndex &index, const QStyleOptionViewItem &option, QPainterPath& path, RowVectorXd& data) const { const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model()); float fMaxValue = data.maxCoeff(); float fValue; float fScaleY = option.rect.height()/(fMaxValue*0.5); float y_base = path.currentPosition().y(); QPointF qSamplePosition; qint32 lowerIdx = t_pModel->getLowerFrqBound(); qint32 upperIdx = t_pModel->getUpperFrqBound(); //Move to initial starting point if(data.size() > 0) { float val = 0; fValue = val*fScaleY; float newY = y_base+fValue; qSamplePosition.setY(newY); qSamplePosition.setX((double)option.rect.width()*t_pModel->getFreqScaleBound()[lowerIdx]); path.moveTo(qSamplePosition); } //create lines from one to the next sample qint32 i; for(i = lowerIdx+1; i <= upperIdx; ++i) { float val = data[i]-data[0]; //remove first sample data[0] as offset fValue = val*fScaleY; float newY = y_base+fValue; qSamplePosition.setY(newY); qSamplePosition.setX((double)option.rect.width()*t_pModel->getFreqScaleBound()[i]); path.lineTo(qSamplePosition); } }
//target function przyjmuje macierz, wiec mozemy oba porownywane punkty polaczyc i przeslac. bool NelderMead::Compare(RowVectorXd first, RowVectorXd second) { RowVector2d val; MatrixXd temp(2, first.cols()); temp.row(0) = first; temp.row(1) = second; val = this->TargetFunction(temp); return val[0] < val[1]; }
vector <RowVectorXd> findCorners(vector <int> quadMap) { RowVectorXd corners; corners << 0, 0, 1, 1; RowVectorXd tempCorners; vector <RowVectorXd> finalCorners; vector<int>::size_type sz = quadMap.size(); for(int i = 0; i < sz; i++) switch(quadMap[i]) { case 0: tempCorners.resize(4); tempCorners << corners[0], corners[1], (corners[3] + corners[0]) / 2, (corners[4] + corners[1]) / 2; corners = tempCorners; break; case 1: tempCorners.resize(4); tempCorners << corners[0], (corners[4] + corners[1]) / 2, (corners[3] + corners[0]) / 2, corners[4]; corners = tempCorners; break; case 2: tempCorners.resize(4); tempCorners << (corners[3] + corners[0]) / 2, corners[1], corners[3], (corners[4] + corners[1]) / 2; corners = tempCorners; break; case 3: tempCorners.resize(4); tempCorners << (corners[3] + corners[0]) / 2, (corners[4] + corners[1]) / 2, corners[0], corners[1]; corners = tempCorners; break; } finalCorners.push_back({corners[0], corners[1]}); finalCorners.push_back({corners[2], corners[3]}); return finalCorners; }
RowVectorXd FilterData::applyConvFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const { if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData){ qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols()); return data; } //Do zero padding or mirroring depending on user input RowVectorXd t_dataZeroPad = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols()); RowVectorXd t_filteredTime = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols()); switch(compensateEdgeEffects) { case MirrorData: t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse(); //front t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data; //middle t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse(); //back break; case ZeroPad: t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data; break; default: t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data; break; } //Do the convolution for(int i=m_dCoeffA.cols(); i<t_filteredTime.cols(); i++) t_filteredTime(i-m_dCoeffA.cols()) = t_dataZeroPad.segment(i-m_dCoeffA.cols(),m_dCoeffA.cols()) * m_dCoeffA.transpose(); //Return filtered data if(!keepOverhead) return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols()); return t_filteredTime.head(data.cols()+m_dCoeffA.cols()); }
bool qbd_compute_pi0(const MatrixXd & R, const MatrixXd & B0, const MatrixXd & A0, RowVectorXd & pi0, const qbd_parms & parms) throw (Exc) { if(R.rows()!=R.cols()) EXC_PRINT("R had to be square"); if (!check_sizes(A0,R) || !check_sizes(A0,B0)) EXC_PRINT("A0, A1, A2 matrixes have to be square and equal size"); if ((R.minCoeff()<0)&&parms.verbose) cerr<<"QBD_COMPUTE_PI0: Warning: R has negative coeeficients"<<endl; SelfAdjointEigenSolver<MatrixXd> eigensolver(R); if (eigensolver.info() != Success) { if (parms.verbose) cerr<<"QBD_COMPUTE_PI0: cannot compute eigenvalues of R"<<endl; return false; } if ((ArrayXd(eigensolver.eigenvalues()).abs().maxCoeff()>1)&&parms.verbose) cerr<<"QBD_COMPUTE_PI0: Warning: R has spectral radius greater than 1"<<endl; int n = R.rows(); MatrixXd Id = MatrixXd::Identity(n,n); VectorXd u(n); u.setOnes(); MatrixXd M(n,n+1); M.block(0,0,n,n)= B0+R*A0-Id; M.block(0,n,n,1)= (Id-R).inverse()*u; FullPivLU<MatrixXd> lu_decomp(M); if(lu_decomp.rank()<n) { if (parms.verbose) cerr<<"QBD_COMPUTE_PI0: No unique solution"<<endl; return false; } RowVectorXd work(n+1); work.setZero(); work(n)=1; MatrixXd W1; pseudoInverse<MatrixXd>(M,W1); pi0 = work*W1; if ((pi0.minCoeff()<0)&&parms.verbose) cerr<<"QBD_COMPUTE_PI0: Warning: x0 has negative elements"<<endl; return true; }
void DataPackage::setMappedProcData(const RowVectorXd &originalProcData, int row, int cutFront, int cutBack) { if(originalProcData.cols()-cutFront-cutBack != m_dataProcMapped.cols() || row >= m_dataProcMapped.rows()){ qDebug()<<"DataPackage::setMappedProcData - cannot set row data to m_dataProcOriginal"; return; } //Cut data m_dataProcMapped.row(row) = cutData(originalProcData, cutFront, cutBack); if(cutFront != m_iCutFrontProc) m_iCutFrontProc = cutFront; if(cutBack != m_iCutBackProc) m_iCutBackProc = cutBack; //Calculate mean m_dataProcMean(row) = calculateRowMean(m_dataProcMapped.row(row)); }
void DataPackage::setOrigRawData(const RowVectorXd &originalRawData, int row, int cutFront, int cutBack) { if(originalRawData.cols() != m_dataRawOriginal.cols() || row >= m_dataRawOriginal.rows()){ qDebug()<<"DataPackage::setOrigRawData - cannot set row data to m_dataRawOriginal"; return; } //set orignal data at row row m_dataRawOriginal.row(row) = originalRawData; //Cut data m_dataRawMapped.row(row) = cutData(m_dataRawOriginal, cutFront, cutBack); if(cutFront != m_iCutFrontRaw) m_iCutFrontRaw = cutFront; if(cutBack != m_iCutBackRaw) m_iCutBackRaw = cutBack; //Calculate mean m_dataRawMean(row) = calculateRowMean(m_dataRawMapped.row(row)); }
// barebones version of the lasso for fixed lambda // Eigen library is used for linear algebra // x .............. predictor matrix // y .............. response // lambda ......... penalty parameter // useSubset ...... logical indicating whether lasso should be computed on a // subset // subset ......... indices of subset on which lasso should be computed // normalize ...... logical indicating whether predictors should be normalized // useIntercept ... logical indicating whether intercept should be included // eps ............ small numerical value (effective zero) // useGram ........ logical indicating whether Gram matrix should be computed // in advance // useCrit ........ logical indicating whether to compute objective function void fastLasso(const MatrixXd& x, const VectorXd& y, const double& lambda, const bool& useSubset, const VectorXi& subset, const bool& normalize, const bool& useIntercept, const double& eps, const bool& useGram, const bool& useCrit, // intercept, coefficients, residuals and objective function are returned // through the following parameters double& intercept, VectorXd& beta, VectorXd& residuals, double& crit) { // data initializations int n, p = x.cols(); MatrixXd xs; VectorXd ys; if(useSubset) { n = subset.size(); xs.resize(n, p); ys.resize(n); int s; for(int i = 0; i < n; i++) { s = subset(i); xs.row(i) = x.row(s); ys(i) = y(s); } } else { n = x.rows(); xs = x; // does this copy memory? ys = y; // does this copy memory? } double rescaledLambda = n * lambda / 2; // center data and store means RowVectorXd meanX; double meanY; if(useIntercept) { meanX = xs.colwise().mean(); // columnwise means of predictors xs.rowwise() -= meanX; // sweep out columnwise means meanY = ys.mean(); // mean of response for(int i = 0; i < n; i++) { ys(i) -= meanY; // sweep out mean } } else { meanY = 0; // just to avoid warning, this is never used // intercept = 0; // zero intercept } // some initializations VectorXi inactive(p); // inactive predictors int m = 0; // number of inactive predictors VectorXi ignores; // indicates variables to be ignored int s = 0; // number of ignored variables // normalize predictors and store norms RowVectorXd normX; if(normalize) { normX = xs.colwise().norm(); // columnwise norms double epsNorm = eps * sqrt(n); // R package 'lars' uses n, not n-1 for(int j = 0; j < p; j++) { if(normX(j) < epsNorm) { // variance is too small: ignore variable ignores.append(j, s); s++; // set norm to tolerance to avoid numerical problems normX(j) = epsNorm; } else { inactive(m) = j; // add variable to inactive set m++; // increase number of inactive variables } xs.col(j) /= normX(j); // sweep out norm } // resize inactive set and update number of variables if necessary if(m < p) { inactive.conservativeResize(m); p = m; } } else { for(int j = 0; j < p; j++) inactive(j) = j; // add variable to inactive set m = p; } // compute Gram matrix if requested (saves time if number of variables is // not too large) MatrixXd Gram; if(useGram) { Gram.noalias() = xs.transpose() * xs; } // further initializations for iterative steps RowVectorXd corY; corY.noalias() = ys.transpose() * xs; // current correlations beta.resize(p+s); // final coefficients // compute lasso solution if(p == 1) { // special case of only one variable (with sufficiently large norm) int j = inactive(0); // set maximum step size in the direction of that variable double maxStep = corY(j); if(maxStep < 0) maxStep = -maxStep; // absolute value // compute coefficients for least squares solution VectorXd betaLS = xs.col(j).householderQr().solve(ys); // compute lasso coefficients beta.setZero(); if(rescaledLambda < maxStep) { // interpolate towards least squares solution beta(j) = (maxStep - rescaledLambda) * betaLS(0) / maxStep; } } else { // further initializations for iterative steps VectorXi active; // active predictors int k = 0; // number of active predictors // previous and current regression coefficients VectorXd previousBeta = VectorXd::Zero(p+s), currentBeta = VectorXd::Zero(p+s); // previous and current penalty parameter double previousLambda = 0, currentLambda = 0; // indicates variables to be dropped VectorXi drops; // keep track of sign of correlations for the active variables // (double precision is necessary for solve()) VectorXd signs; // Cholesky L of Gram matrix of active variables MatrixXd L; int rank = 0; // rank of Cholesky L // maximum number of variables to be sequenced int maxActive = findMaxActive(n, p, useIntercept); // modified LARS algorithm for lasso solution while(k < maxActive) { // extract current correlations of inactive variables VectorXd corInactiveY(m); for(int j = 0; j < m; j++) { corInactiveY(j) = corY(inactive(j)); } // compute absolute values of correlations and find maximum VectorXd absCorInactiveY = corInactiveY.cwiseAbs(); double maxCor = absCorInactiveY.maxCoeff(); // update current lambda if(k == 0) { // no active variables previousLambda = maxCor; } else { previousLambda = currentLambda; } currentLambda = maxCor; if(currentLambda <= rescaledLambda) break; if(drops.size() == 0) { // new active variables VectorXi newActive = findNewActive(absCorInactiveY, maxCor - eps); // do calculations for new active variables for(int j = 0; j < newActive.size(); j++) { // update Cholesky L of Gram matrix of active variables // TODO: put this into void function int newJ = inactive(newActive(j)); VectorXd xNewJ; double newX; if(useGram) { newX = Gram(newJ, newJ); } else { xNewJ = xs.col(newJ); newX = xNewJ.squaredNorm(); } double normNewX = sqrt(newX); if(k == 0) { // no active variables, L is empty L.resize(1,1); L(0, 0) = normNewX; rank = 1; } else { VectorXd oldX(k); if(useGram) { for(int j = 0; j < k; j++) { oldX(j) = Gram(active(j), newJ); } } else { for(int j = 0; j < k; j++) { oldX(j) = xNewJ.dot(xs.col(active(j))); } } VectorXd l = L.triangularView<Lower>().solve(oldX); double lkk = newX - l.squaredNorm(); // check if L is machine singular if(lkk > eps) { // no singularity: update Cholesky L lkk = sqrt(lkk); rank++; // add new row and column to Cholesky L // this is a little trick: sometimes we need // lower triangular matrix, sometimes upper // hence we define quadratic matrix and use // triangularView() to interpret matrix the // correct way L.conservativeResize(k+1, k+1); for(int j = 0; j < k; j++) { L(k, j) = l(j); L(j, k) = l(j); } L(k,k) = lkk; } } // add new variable to active set or drop it for good // in case of singularity if(rank == k) { // singularity: drop variable for good ignores.append(newJ, s); s++; // increase number of ignored variables p--; // decrease number of variables if(p < maxActive) { // adjust maximum number of active variables maxActive = p; } } else { // no singularity: add variable to active set active.append(newJ, k); // keep track of sign of correlation for new active variable signs.append(sign(corY(newJ)), k); k++; // increase number of active variables } } // remove new active or ignored variables from inactive variables // and corresponding vector of current correlations inactive.remove(newActive); corInactiveY.remove(newActive); m = inactive.size(); // update number of inactive variables } // prepare for computation of step size // here double precision of signs is necessary VectorXd b = L.triangularView<Lower>().solve(signs); VectorXd G = L.triangularView<Upper>().solve(b); // correlations of active variables with equiangular vector double corActiveU = 1/sqrt(G.dot(signs)); // coefficients of active variables in linear combination forming the // equiangular vector VectorXd w = G * corActiveU; // note that this has the right signs // equiangular vector VectorXd u; if(!useGram) { // we only need equiangular vector if we don't use the precomputed // Gram matrix, otherwise we can compute the correlations directly // from the Gram matrix u = VectorXd::Zero(n); for(int i = 0; i < n; i++) { for(int j = 0; j < k; j++) { u(i) += xs(i, active(j)) * w(j); } } } // compute step size in equiangular direction double step; if(k < maxActive) { // correlations of inactive variables with equiangular vector VectorXd corInactiveU(m); if(useGram) { for(int j = 0; j < m; j++) { corInactiveU(j) = 0; for(int i = 0; i < k; i++) { corInactiveU(j) += w(i) * Gram(active(i), inactive(j)); } } } else { for(int j = 0; j < m; j++) { corInactiveU(j) = u.dot(xs.col(inactive(j))); } } // compute step size in the direction of the equiangular vector step = findStep(maxCor, corInactiveY, corActiveU, corInactiveU, eps); } else { // last step: take maximum possible step step = maxCor/corActiveU; } // adjust step size if any sign changes and drop corresponding variables drops = findDrops(currentBeta, active, w, eps, step); // update current regression coefficients previousBeta = currentBeta; for(int j = 0; j < k; j++) { currentBeta(active(j)) += step * w(j); } // update current correlations if(useGram) { // we also need to do this for active variables, since they may be // dropped at a later stage // TODO: computing a vector step * w in advance may save some computation time for(int j = 0; j < Gram.cols(); j++) { for(int i = 0; i < k; i++) { corY(j) -= step * w(i) * Gram(active(i), j); } } } else { ys -= step * u; // take step in equiangular direction corY.noalias() = ys.transpose() * xs; // update correlations } // drop variables if necessary if(drops.size() > 0) { // downdate Cholesky L // TODO: put this into void function for(int j = drops.size()-1; j >= 0; j--) { // variables need to be dropped in descending order int drop = drops(j); // index with respect to active set // modify upper triangular part as in R package 'lars' // simply deleting columns is not enough, other computations // necessary but complicated due to Fortran code L.removeCol(drop); VectorXd z = VectorXd::Constant(k, 1, 1); k--; // decrease number of active variables for(int i = drop; i < k; i++) { double a = L(i,i), b = L(i+1,i); if(b != 0.0) { // compute the rotation double tau, s, c; if(std::abs(b) > std::abs(a)) { tau = -a/b; s = 1.0/sqrt(1.0+tau*tau); c = s * tau; } else { tau = -b/a; c = 1.0/sqrt(1.0+tau*tau); s = c * tau; } // update 'L' and 'z'; L(i,i) = c*a - s*b; for(int j = i+1; j < k; j++) { a = L(i,j); b = L(i+1,j); L(i,j) = c*a - s*b; L(i+1,j) = s*a + c*b; } a = z(i); b = z(i+1); z(i) = c*a - s*b; z(i+1) = s*a + c*b; } } // TODO: removing all rows together may save some computation time L.conservativeResize(k, NoChange); rank--; } // mirror lower triangular part for(int j = 0; j < k; j++) { for(int i = j+1; i < k; i++) { L(i,j) = L(j,i); } } // add dropped variables to inactive set and make sure // coefficients are 0 inactive.conservativeResize(m + drops.size()); for(int j = 0; j < drops.size(); j++) { int newInactive = active(drops(j)); inactive(m + j) = newInactive; currentBeta(newInactive) = 0; // make sure coefficient is 0 } m = inactive.size(); // update number of inactive variables // drop variables from active set and sign vector // number of active variables is already updated above active.remove(drops); signs.remove(drops); } } // interpolate coefficients for given lambda if(k == 0) { // lambda larger than largest lambda from steps of LARS algorithm beta.setZero(); } else { // penalty parameter within two steps if(k == maxActive) { // current coefficients are the least squares solution (in the // high-dimensional case, as far along the solution path as possible) // current and previous values of the penalty parameter need to be // reset for interpolation previousLambda = currentLambda; currentLambda = 0; } // interpolate coefficients beta = ((rescaledLambda - currentLambda) * previousBeta + (previousLambda - rescaledLambda) * currentBeta) / (previousLambda - currentLambda); } } // transform coefficients back VectorXd normedBeta; if(normalize) { if(useCrit) normedBeta = beta; for(int j = 0; j < p; j++) beta(j) /= normX(j); } if(useIntercept) intercept = meanY - beta.dot(meanX); // compute residuals for all observations n = x.rows(); residuals = y - x * beta; if(useIntercept) { for(int i = 0; i < n; i++) residuals(i) -= intercept; } // compute value of objective function on the subset if(useCrit && useSubset) { if(normalize) crit = objective(normedBeta, residuals, subset, lambda); else crit = objective(beta, residuals, subset, lambda); } }
void RealTimeButterflyPlot::createPlotPath(qint32 row, QPainterPath& path) const { //get maximum range of respective channel type (range value in FiffChInfo does not seem to contain a reasonable value) qint32 kind = m_pRealTimeEvokedModel->getKind(row); float fMaxValue = 1e-9f; switch(kind) { case FIFFV_MEG_CH: { qint32 unit =m_pRealTimeEvokedModel->getUnit(row); if(unit == FIFF_UNIT_T_M) { //gradiometers fMaxValue = 1e-10f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFF_UNIT_T_M)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFF_UNIT_T_M]; } else if(unit == FIFF_UNIT_T) //magnitometers { if(m_pRealTimeEvokedModel->getCoil(row) == FIFFV_COIL_BABY_MAG) fMaxValue = 1e-11f; else fMaxValue = 1e-11f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFF_UNIT_T)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFF_UNIT_T]; } break; } case FIFFV_REF_MEG_CH: { /*11/04/14 Added by Limin: MEG reference channel */ fMaxValue = 1e-11f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFF_UNIT_T)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFF_UNIT_T]; break; } case FIFFV_EEG_CH: { fMaxValue = 1e-4f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFFV_EEG_CH)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFFV_EEG_CH]; break; } case FIFFV_EOG_CH: { fMaxValue = 1e-3f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFFV_EOG_CH)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFFV_EOG_CH]; break; } case FIFFV_STIM_CH: { fMaxValue = 5; if(m_pRealTimeEvokedModel->getScaling().contains(FIFFV_STIM_CH)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFFV_STIM_CH]; break; } case FIFFV_MISC_CH: { fMaxValue = 1e-3f; if(m_pRealTimeEvokedModel->getScaling().contains(FIFFV_MISC_CH)) fMaxValue = m_pRealTimeEvokedModel->getScaling()[FIFFV_MISC_CH]; break; } } float fValue; float fScaleY = this->height()/(2*fMaxValue); //restrictions for paint performance float fWinMaxVal = ((float)this->height()-2)/2.0f; qint32 iDownSampling = (m_pRealTimeEvokedModel->getNumSamples() * 4 / (this->width()-2)); if(iDownSampling < 1) iDownSampling = 1; float y_base = path.currentPosition().y(); QPointF qSamplePosition; float fDx = (float)(this->width()-2) / ((float)m_pRealTimeEvokedModel->getNumSamples()-1.0f);//((float)option.rect.width()) / m_pRealTimeEvokedModel->getMaxSamples(); // fDx *= iDownSampling; RowVectorXd rowVec = m_pRealTimeEvokedModel->data(row,1).value<RowVectorXd>(); //Move to initial starting point if(rowVec.size() > 0) { float val = rowVec[0]; fValue = (val/*-rowVec[m_pRealTimeEvokedModel->getNumPreStimSamples()-1]*/)*fScaleY;//ToDo -> -2 PreStim is one too short float newY = y_base+fValue; qSamplePosition.setY(-newY); qSamplePosition.setX(path.currentPosition().x()); path.moveTo(qSamplePosition); } //create lines from one to the next sample qint32 i; for(i = 1; i < rowVec.size(); ++i) { // if(i != m_pRealTimeEvokedModel->getNumPreStimSamples() - 2) // { float val = /*rowVec[m_pRealTimeEvokedModel->getNumPreStimSamples()-1] - */rowVec[i]; //remove first sample data[0] as offset fValue = val*fScaleY; fValue = fValue > fWinMaxVal ? fWinMaxVal : fValue < -fWinMaxVal ? -fWinMaxVal : fValue; float newY = y_base+fValue; qSamplePosition.setY(-newY); // } // else // qSamplePosition.setY(y_base); qSamplePosition.setX(path.currentPosition().x()+fDx); path.lineTo(qSamplePosition); } // //create lines from one to the next sample for last path // qint32 sample_offset = m_pRealTimeEvokedModel->numVLines() + 1; // qSamplePosition.setX(qSamplePosition.x() + fDx*sample_offset); // lastPath.moveTo(qSamplePosition); // for(i += sample_offset; i < lastData.size(); ++i) { // float val = lastData[i] - lastData[0]; //remove first sample lastData[0] as offset // fValue = val*fScaleY; // float newY = y_base+fValue; // qSamplePosition.setY(newY); // qSamplePosition.setX(lastPath.currentPosition().x()+fDx); // lastPath.lineTo(qSamplePosition); // } }
void FrequencySpectrumDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { float t_fPlotHeight = option.rect.height(); switch(index.column()) { case 0: { //chnames painter->save(); painter->rotate(-90); painter->drawText(QRectF(-option.rect.y()-t_fPlotHeight,0,t_fPlotHeight,20),Qt::AlignCenter,index.model()->data(index,Qt::DisplayRole).toString()); painter->restore(); break; } case 1: { //data plot painter->save(); //draw special background when channel is marked as bad // QVariant v = index.model()->data(index,Qt::BackgroundRole); // if(v.canConvert<QBrush>() && !(option.state & QStyle::State_Selected)) { // QPointF oldBO = painter->brushOrigin(); // painter->setBrushOrigin(option.rect.topLeft()); // painter->fillRect(option.rect, qvariant_cast<QBrush>(v)); // painter->setBrushOrigin(oldBO); // } // //Highlight selected channels // if(option.state & QStyle::State_Selected) { // QPointF oldBO = painter->brushOrigin(); // painter->setBrushOrigin(option.rect.topLeft()); // painter->fillRect(option.rect, option.palette.highlight()); // painter->setBrushOrigin(oldBO); // } //Get data QVariant variant = index.model()->data(index,Qt::DisplayRole); RowVectorXd data = variant.value< RowVectorXd >(); const FrequencySpectrumModel* t_pModel = static_cast<const FrequencySpectrumModel*>(index.model()); if(data.size() > 0) { QPainterPath path(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor()-1,option.rect.y())); //Plot grid painter->setRenderHint(QPainter::Antialiasing, false); createGridPath(index, option, path, data); createGridTick(index, option, painter); //capture the mouse capturePoint(index, option, path, data, painter); painter->save(); QPen pen; pen.setStyle(Qt::DotLine); pen.setWidthF(0.5); painter->setPen(pen); painter->drawPath(path); painter->restore(); //Plot data path path = QPainterPath(QPointF(option.rect.x(),option.rect.y()));//QPointF(option.rect.x()+t_rtmsaModel->relFiffCursor(),option.rect.y())); createPlotPath(index, option, path, data); painter->save(); painter->translate(0,t_fPlotHeight/2); painter->setRenderHint(QPainter::Antialiasing, true); if(option.state & QStyle::State_Selected) painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkRed : Qt::red, 1, Qt::SolidLine)); else painter->setPen(QPen(t_pModel->isFreezed() ? Qt::darkGray : Qt::darkBlue, 1, Qt::SolidLine)); painter->drawPath(path); painter->restore(); } painter->restore(); break; } } }
//#define IGL_LINPROG_VERBOSE IGL_INLINE bool igl::linprog( const Eigen::VectorXd & c, const Eigen::MatrixXd & _A, const Eigen::VectorXd & b, const int k, Eigen::VectorXd & x) { // This is a very literal translation of // http://www.mathworks.com/matlabcentral/fileexchange/2166-introduction-to-linear-algebra/content/strang/linprog.m using namespace Eigen; using namespace std; bool success = true; // number of constraints const int m = _A.rows(); // number of original variables const int n = _A.cols(); // number of iterations int it = 0; // maximum number of iterations //const int MAXIT = 10*m; const int MAXIT = 100*m; // residual tolerance const double tol = 1e-10; const auto & sign = [](const Eigen::VectorXd & B) -> Eigen::VectorXd { Eigen::VectorXd Bsign(B.size()); for(int i = 0;i<B.size();i++) { Bsign(i) = B(i)>0?1:(B(i)<0?-1:0); } return Bsign; }; // initial (inverse) basis matrix VectorXd Dv = sign(sign(b).array()+0.5); Dv.head(k).setConstant(1.); MatrixXd D = Dv.asDiagonal(); // Incorporate slack variables MatrixXd A(_A.rows(),_A.cols()+D.cols()); A<<_A,D; // Initial basis VectorXi B = igl::colon<int>(n,n+m-1); // non-basis, may turn out that vector<> would be better here VectorXi N = igl::colon<int>(0,n-1); int j; double bmin = b.minCoeff(&j); int phase; VectorXd xb; VectorXd s; VectorXi J; if(k>0 && bmin<0) { phase = 1; xb = VectorXd::Ones(m); // super cost s.resize(n+m+1); s<<VectorXd::Zero(n+k),VectorXd::Ones(m-k+1); N.resize(n+1); N<<igl::colon<int>(0,n-1),B(j); J.resize(B.size()-1); // [0 1 2 3 4] // ^ // [0 1] // [3 4] J.head(j) = B.head(j); J.tail(B.size()-j-1) = B.tail(B.size()-j-1); B(j) = n+m; MatrixXd AJ; igl::slice(A,J,2,AJ); const VectorXd a = b - AJ.rowwise().sum(); { MatrixXd old_A = A; A.resize(A.rows(),A.cols()+a.cols()); A<<old_A,a; } D.col(j) = -a/a(j); D(j,j) = 1./a(j); }else if(k==m) { phase = 2; xb = b; s.resize(c.size()+m); // cost function s<<c,VectorXd::Zero(m); }else //k = 0 or bmin >=0 { phase = 1; xb = b.array().abs(); s.resize(n+m); // super cost s<<VectorXd::Zero(n+k),VectorXd::Ones(m-k); } while(phase<3) { double df = -1; int t = std::numeric_limits<int>::max(); // Lagrange mutipliers fro Ax=b VectorXd yb = D.transpose() * igl::slice(s,B); while(true) { if(MAXIT>0 && it>=MAXIT) { #ifdef IGL_LINPROG_VERBOSE cerr<<"linprog: warning! maximum iterations without convergence."<<endl; #endif success = false; break; } // no freedom for minimization if(N.size() == 0) { break; } // reduced costs VectorXd sN = igl::slice(s,N); MatrixXd AN = igl::slice(A,N,2); VectorXd r = sN - AN.transpose() * yb; int q; // determine new basic variable double rmin = r.minCoeff(&q); // optimal! infinity norm if(rmin>=-tol*(sN.array().abs().maxCoeff()+1)) { break; } // increment iteration count it++; // apply Bland's rule to avoid cycling if(df>=0) { if(MAXIT == -1) { #ifdef IGL_LINPROG_VERBOSE cerr<<"linprog: warning! degenerate vertex"<<endl; #endif success = false; } igl::find((r.array()<0).eval(),J); double Nq = igl::slice(N,J).minCoeff(); // again seems like q is assumed to be a scalar though matlab code // could produce a vector for multiple matches (N.array()==Nq).cast<int>().maxCoeff(&q); } VectorXd d = D*A.col(N(q)); VectorXi I; igl::find((d.array()>tol).eval(),I); if(I.size() == 0) { #ifdef IGL_LINPROG_VERBOSE cerr<<"linprog: warning! solution is unbounded"<<endl; #endif // This seems dubious: it=-it; success = false; break; } VectorXd xbd = igl::slice(xb,I).array()/igl::slice(d,I).array(); // new use of r int p; { double r; r = xbd.minCoeff(&p); p = I(p); // apply Bland's rule to avoid cycling if(df>=0) { igl::find((xbd.array()==r).eval(),J); double Bp = igl::slice(B,igl::slice(I,J)).minCoeff(); // idiotic way of finding index in B of Bp // code down the line seems to assume p is a scalar though the matlab // code could find a vector of matches) (B.array()==Bp).cast<int>().maxCoeff(&p); } // update x xb -= r*d; xb(p) = r; // change in f df = r*rmin; } // row vector RowVectorXd v = D.row(p)/d(p); yb += v.transpose() * (s(N(q)) - d.transpose()*igl::slice(s,B)); d(p)-=1; // update inverse basis matrix D = D - d*v; t = B(p); B(p) = N(q); if(t>(n+k-1)) { // remove qth entry from N VectorXi old_N = N; N.resize(N.size()-1); N.head(q) = old_N.head(q); N.head(q) = old_N.head(q); N.tail(old_N.size()-q-1) = old_N.tail(old_N.size()-q-1); }else { N(q) = t; } } // iterative refinement xb = (xb+D*(b-igl::slice(A,B,2)*xb)).eval(); // must be due to rounding VectorXi I; igl::find((xb.array()<0).eval(),I); if(I.size()>0) { // so correct VectorXd Z = VectorXd::Zero(I.size(),1); igl::slice_into(Z,I,xb); } // B, xb,n,m,res=A(:,B)*xb-b if(phase == 2 || it<0) { break; } if(xb.transpose()*igl::slice(s,B) > tol) { it = -it; #ifdef IGL_LINPROG_VERBOSE cerr<<"linprog: warning, no feasible solution"<<endl; #endif success = false; break; } // re-initialize for Phase 2 phase = phase+1; s*=1e6*c.array().abs().maxCoeff(); s.head(n) = c; } x.resize(std::max(B.maxCoeff()+1,n)); igl::slice_into(xb,B,x); x = x.head(n).eval(); return success; }
MatrixXd RtFilter::filterChannelsConcurrently(const MatrixXd& matDataIn, int iMaxFilterLength, const QVector<int>& lFilterChannelList, const QList<FilterData>& lFilterData) { //Initialise the overlay matrix if(m_matOverlap.cols() != iMaxFilterLength || m_matOverlap.rows() < matDataIn.rows()) { m_matOverlap.resize(matDataIn.rows(), iMaxFilterLength); m_matOverlap.setZero(); } if(m_matDelay.cols() != iMaxFilterLength/2 || m_matOverlap.rows() < matDataIn.rows()) { m_matDelay.resize(matDataIn.rows(), iMaxFilterLength/2); m_matDelay.setZero(); } //Resize output matrix to match input matrix MatrixXd matDataOut(matDataIn.rows(), matDataIn.cols()); //Generate QList structure which can be handled by the QConcurrent framework QList<QPair<QList<FilterData>,QPair<int,RowVectorXd> > > timeData; QList<int> notFilterChannelIndex; //Only select channels specified in lFilterChannelList for(qint32 i = 0; i < matDataIn.rows(); ++i) { int pos = lFilterChannelList.indexOf(i); if(pos != -1 && pos < matDataIn.rows()) { timeData.append(QPair<QList<FilterData>,QPair<int,RowVectorXd> >(lFilterData,QPair<int,RowVectorXd>(pos,matDataIn.row(pos)))); } else { notFilterChannelIndex.append(i); } } //Do the concurrent filtering if(!timeData.isEmpty()) { QFuture<void> future = QtConcurrent::map(timeData, doFilterPerChannelRTMSA); future.waitForFinished(); //Do the overlap add method and store in matDataOut int iFilteredNumberCols = timeData.at(0).second.second.cols(); for(int r = 0; r < timeData.size(); r++) { //Get the currently filtered data. This data has a delay of filterLength/2 in front and back. RowVectorXd tempData = timeData.at(r).second.second; //Perform the actual overlap add by adding the last filterlength data to the newly filtered one tempData.head(iMaxFilterLength) += m_matOverlap.row(timeData.at(r).second.first); //Write the newly calulated filtered data to the filter data matrix. Keep in mind that the current block also effect last part of the last block (begin at dataIndex-iFilterDelay). int start = 0; matDataOut.row(timeData.at(r).second.first).segment(start,iFilteredNumberCols-iMaxFilterLength) = tempData.head(iFilteredNumberCols-iMaxFilterLength); //Refresh the m_matOverlap with the new calculated filtered data. m_matOverlap.row(timeData.at(r).second.first) = timeData.at(r).second.second.tail(iMaxFilterLength); } } //Fill filtered data with raw data if the channel was not filtered for(int i = 0; i < notFilterChannelIndex.size(); ++i) { matDataOut.row(notFilterChannelIndex.at(i)) << m_matDelay.row(notFilterChannelIndex.at(i)), matDataIn.row(notFilterChannelIndex.at(i)).head(matDataIn.cols() - iMaxFilterLength/2); //matDataOut.row(notFilterChannelIndex.at(i)).segment(0, matDataIn.row(notFilterChannelIndex.at(i)).cols()) = matDataIn.row(notFilterChannelIndex.at(i)); } m_matDelay = matDataIn.block(0, matDataIn.cols()-iMaxFilterLength/2, matDataIn.rows(), iMaxFilterLength/2); return matDataOut; }
void Dataset::normalize(void){ MatrixXd m = Map<Matrix<double,Dynamic,Dynamic,RowMajor> >(this->x,this->records,this->features); RowVectorXd mean = m.colwise().mean(); RowVectorXd var = (m.rowwise() - mean).array().square().colwise().mean().sqrt(); m = (m.rowwise() - mean).array().rowwise() / var.array(); }
virtual void Transform(_Out_ frame_view target_frame, _In_ const_frame_view source_frame, _In_ const_frame_view last_frame, float frame_time) override { //if (!g_UseVelocity) //{ // Transform(target_frame, source_frame); // return; //} const auto& blocks = *pBlockArmature; int pvDim = inputExtractor.GetDimension(*blocks[0]); RowVectorXd X(g_UseVelocity ? pvDim * 2 : pvDim), Y; double semga = 1000; RowVectorXf yf; std::vector<RowVectorXd> Xabs; for (auto& block : blocks) { //X[0] *= 13; if (block->Index > 0 && block->ActiveActions.size() > 0) { auto& sik = pController->GetStylizedIK(block->Index); auto& gpr = sik.Gplvm(); auto& joints = block->Joints; RowVectorXf xf = inputExtractor.Get(*block, source_frame); RowVectorXf xfl = inputExtractor.Get(*block, last_frame); yf = outputExtractor.Get(*block, target_frame); auto xyf = inputExtractor.Get(*block, target_frame); auto pDecoder = sik.getDecoder(); auto baseRot = target_frame[block->parent()->Joints.back()->ID].GblRotation; sik.setBaseRotation(baseRot); sik.setChain(block->Joints, target_frame); //sik.SetGplvmWeight(block->Wx.cast<double>()); //std::vector<DirectX::Quaternion, XMAllocator> corrrots(joints.size()); //std::vector<DirectX::Quaternion, XMAllocator> rots(joints.size()); //for (int i = 0; i < joints.size(); i++) //{ // corrrots[i] = target_frame[joints[i]->ID].LclRotation; //} //(*pDecoder)(rots.data(), yf.cast<double>()); ////outputExtractor.Set(*block, target_frame, yf); //auto ep = sik.EndPosition(reinterpret_cast<XMFLOAT4A*>(rots.data())); X.segment(0, pvDim) = xf.cast<double>(); auto Xd = X.segment(0, pvDim); auto uXd = gpr.uX.segment(0, pvDim); //auto uXv = block->PdGpr.uX.segment<3>(3); //Xv = (Xv - uXv).array() * g_NoiseInterpolation.array() + uXv.array(); Xd = (Xd - uXd).array(); double varZ = (Xd.array() * (g_NoiseInterpolation.array() - 1.0)).cwiseAbs2().sum(); // if no noise varZ = std::max(varZ, 1e-5); Xd = Xd.array() * g_NoiseInterpolation.array() + uXd.array(); RowVector3d Xld = (xfl.cast<double>() - uXd).array() * g_NoiseInterpolation.array() + uXd.array(); if (g_UseVelocity) { auto Xv = X.segment(pvDim, pvDim); Xv = (Xd - Xld) / (frame_time * g_FrameTimeScaleFactor); } xf = X.cast<float>(); SetVisualizeHandle(block, xf); //m_Xs.row(block->Index) = X; Xabs.emplace_back(X); // Beyesian majarnlize over X //size_t detail = 3; //MatrixXd Xs(detail*2+1,g_PvDimension), Ys; //Xs = gaussian_sample(X, X, detail); //VectorXd Pxs = (Xs - X.replicate(detail * 2 + 1, 1)).cwiseAbs2().rowwise().sum(); //Pxs = (-Pxs.array() / semga).exp(); //VectorXd Py_xs = block->PdGpr.get_expectation_and_likelihood(Xs, &Ys); //Py_xs = (-Py_xs.array()).exp() * Pxs.array(); //Py_xs /= Py_xs.sum(); //Y = (Ys.array() * Py_xs.replicate(1, Ys.cols()).array()).colwise().sum(); MatrixXd covObsr(g_PvDimension, g_PvDimension); covObsr.setZero(); covObsr.diagonal() = g_NoiseInterpolation.replicate(1, g_PvDimension / 3).transpose() * varZ; //block->PdGpr.get_expectation_from_observation(X, covObsr, &Y); //block->PdGpr.get_expectation(X, &Y); //auto yc = yf; //yf = Y.cast<float>(); //yf.array() *= block->Wx.cwiseInverse().array().transpose(); //block->PdStyleIk.SetHint(); if (!g_UseVelocity) Y = sik.apply(X.transpose(), baseRot).cast<double>(); else Y = sik.apply(X.segment(0, pvDim).transpose(), Vector3d(X.segment(pvDim, pvDim).transpose()), baseRot).cast<double>(); //block->PdStyleIk.SetGoal(X.leftCols<3>()); //auto scoref = block->PdStyleIk.objective(X, yf.cast<double>()); //auto scorec = block->PdStyleIk.objective(X, yc.cast<double>()); //std::cout << "Gpr score : " << scoref << " ; Cannonical score : " << scorec << endl; //auto ep = sik.EndPosition(yf.cast<double>()); //Y = yf.cast<double>(); outputExtractor.Set(*block, target_frame, Y.cast<float>()); for (int i = 0; i < block->Joints.size(); i++) { target_frame[block->Joints[i]->ID].UpdateGlobalData(target_frame[block->Joints[i]->parent()->ID]); } auto ep2 = target_frame[block->Joints.back()->ID].GblTranslation - target_frame[block->Joints[0]->parent()->ID].GblTranslation; //break; } } // Fill Xabpv if (g_EnableDependentControl) { RowVectorXd Xabpv; Xabpv.resize(pController->uXabpv.size()); int i = 0; for (const auto& xab : Xabs) { auto Yi = Xabpv.segment(i, xab.size()); Yi = xab; i += xab.size(); } auto _x = (Xabpv.cast<float>() - pController->uXabpv) * pController->XabpvT; auto _xd = _x.cast<double>().eval(); for (auto& block : blocks) { if (block->ActiveActions.size() == 0 && block->SubActiveActions.size() > 0) { auto& sik = pController->GetStylizedIK(block->Index); auto& gpr = sik.Gplvm(); auto lk = gpr.get_expectation_and_likelihood(_xd, &Y); yf = Y.cast<float>(); //yf *= block->Wx.cwiseInverse().asDiagonal(); outputExtractor.Set(*block, target_frame, yf); } } } target_frame[0].LclTranslation = source_frame[0].LclTranslation; target_frame[0].GblTranslation = source_frame[0].GblTranslation; FrameRebuildGlobal(*m_tArmature, target_frame); }