void sigmaDetect(SAUIInterface* ui) { QList<QwtPlotItem*> curs; SAChart2D* chart = filter_xy_series(ui,curs); if(nullptr == chart || curs.size() <= 0) { saUI->showMessageInfo(TR("unsupport chart items"),SA::WarningMessage); return; } double sigma; bool isMark,isChangedPlot; if(!getSigmaDetectPorperty(sigma,&isMark,&isChangedPlot,ui)) { return; } if(!isMark && !isChangedPlot) { return; } QStringList infos; QScopedPointer<SAFigureOptCommand> topCmd(new SAFigureOptCommand(chart,QString("sigma %1").arg(sigma))); for (int i = 0;i<curs.size();++i) { QwtPlotItem* item = curs[i]; switch(item->rtti()) { case QwtPlotItem::Rtti_PlotCurve: { QVector<double> xs,ys; { QVector<QPointF> wave; SAChart::getPlotCurveSample(item,wave); xs.reserve(wave.size()); ys.reserve(wave.size()); std::for_each(wave.begin(),wave.end(),[&xs](const QPointF& p){xs.push_back(p.x());}); std::for_each(wave.begin(),wave.end(),[&ys](const QPointF& p){ys.push_back(p.y());}); } QString info; QString title = item->title().text(); QVector<int> indexs; saFun::sigmaDenoising(xs,ys,sigma,indexs); info = QString("sigma(\"%1\") out range datas count:%2").arg(title).arg(indexs.size()); infos.append(info); if(0 == indexs.size()) { continue; } if(isMark) { QVector<double> oxs,oys; czy::copy_inner_indexs(xs.begin(),indexs.begin(),indexs.end(),std::back_inserter(oxs)); czy::copy_inner_indexs(ys.begin(),indexs.begin(),indexs.end(),std::back_inserter(oys)); QwtPlotCurve* curs = new QwtPlotCurve(QString("%1_outSigmaMarker").arg(title)); curs->setSamples(oxs,oys); SAChart::setCurvePenStyle(curs,Qt::NoPen); QwtSymbol* sym = new QwtSymbol(QwtSymbol::XCross); sym->setColor(SARandColorMaker::getCurveColor()); sym->setSize(QSize(6,6)); curs->setSymbol(sym); new SAFigureChartItemAddCommand(chart ,curs ,QString("%1 - sigma out rang").arg(title) ,topCmd.data()); } if(isChangedPlot) { QVector<int> allIndex; QVector<int> innerIndex; const int count = xs.size(); innerIndex.resize(count); allIndex.reserve(count); for(int i=0;i<count;++i) { allIndex.append(i); } czy::copy_out_of_indexs(allIndex.begin(),allIndex.end(),indexs.begin(),indexs.end(),std::back_inserter(innerIndex)); QVector<double> oxs,oys; czy::copy_inner_indexs(xs.begin(),innerIndex.begin(),innerIndex.end(),std::back_inserter(oxs)); czy::copy_inner_indexs(ys.begin(),innerIndex.begin(),innerIndex.end(),std::back_inserter(oys)); QVector<QPointF> oxys; saFun::makeVectorPointF(oxs,oys,oxys);; new SAFigureReplaceAllDatasCommand<QPointF,QwtPlotCurve,decltype(&SAChart::setPlotCurveSample)> (chart ,item ,oxys ,TR("%1 sigma %2").arg(title).arg(sigma) ,&SAChart::setPlotCurveSample ,&SAChart::getPlotCurveSample ,topCmd.data() ); } break; } } /* QwtSeriesStore<QPointF>* series = dynamic_cast<QwtSeriesStore<QPointF>*>(item); if(nullptr == series) { continue; } QVector<double> xs,ys; if(!chart->getXYData(&xs,&ys,item)) { continue; } QString info; QString title = item->title().text(); QVector<int> indexs; saFun::sigmaDenoising(xs,ys,sigma,indexs); info = QString("sigma(\"%1\") out range datas count:%2").arg(title).arg(indexs.size()); infos.append(info); if(0 == indexs.size()) { continue; } if(isMark) { QVector<double> oxs,oys; czy::copy_inner_indexs(xs.begin(),indexs.begin(),indexs.end(),std::back_inserter(oxs)); czy::copy_inner_indexs(ys.begin(),indexs.begin(),indexs.end(),std::back_inserter(oys)); QwtPlotCurve* curs = new QwtPlotCurve(QString("%1_outSigmaMarker").arg(title)); curs->setSamples(oxs,oys); SAChart::setCurvePenStyle(curs,Qt::NoPen); QwtSymbol* sym = new QwtSymbol(QwtSymbol::XCross); sym->setColor(SARandColorMaker::getCurveColor()); sym->setSize(QSize(6,6)); curs->setSymbol(sym); new SAFigureChartItemAddCommand(chart ,curs ,QString("%1 - sigma out rang").arg(title) ,topCmd.data()); } if(isChangedPlot) { QVector<int> allIndex; QVector<int> innerIndex; const int count = xs.size(); innerIndex.resize(count); allIndex.reserve(count); for(int i=0;i<count;++i) { allIndex.append(i); } czy::copy_out_of_indexs(allIndex.begin(),allIndex.end(),indexs.begin(),indexs.end(),std::back_inserter(innerIndex)); QVector<double> oxs,oys; czy::copy_inner_indexs(xs.begin(),innerIndex.begin(),innerIndex.end(),std::back_inserter(oxs)); czy::copy_inner_indexs(ys.begin(),innerIndex.begin(),innerIndex.end(),std::back_inserter(oys)); QVector<QPointF> oxys; saFun::makeVectorPointF(oxs,oys,oxys); new SAFigureChangeXYSeriesDataCommand(chart ,series ,TR("%1 sigma %2").arg(title).arg(sigma) ,oxys ,topCmd.data()); new SAFigureReplaceAllDatasCommand<>(chart ,series ,); } */ } if(topCmd->childCount() > 0) { chart->appendCommand(topCmd.take()); saUI->showNormalMessageInfo(infos.join('\n')); } }
void polyfitInChart(SAUIInterface* ui) { QList<QwtPlotItem*> curs; SAChart2D* chart = filter_xy_series(ui,curs); if(nullptr == chart || curs.size() <= 0) { ui->showMessageInfo(TR("unsupport chart items"),SA::WarningMessage); return; } int order = 1; if(!getPolyfitConfig(order,ui)) { return; } QString strDes(""); for (int i = 0;i<curs.size();++i) { QwtPlotItem* item = curs[i]; QVector<double> xs,ys; if(chart->isRegionVisible()) { if(!chart->getXYDataInRange(&xs,&ys,nullptr,item)) { continue; } } else { if(!chart->getXYData(&xs,&ys,item)) { continue; } } QString title = item->title().text(); std::shared_ptr<SAVectorDouble> factor;//拟合的系数 std::shared_ptr<SATableVariant> info;//拟合的误差参数 std::tie(factor,info) = saFun::polyfit(xs,ys,order); if(nullptr == factor) { continue; } info->setName(QString("%1_%2PolyFitInfo").arg(title).arg(order)); std::shared_ptr<SAVectorPointF> pfitVal = SAValueManager::makeData<SAVectorPointF>(QString("%1_%2PolyFit").arg(title).arg(order)); saFun::polyval(xs,factor.get(),pfitVal.get()); saValueManager->addData(info); saValueManager->addData(pfitVal); // strDes += "<p>"; strDes += TR("%1-Polynomial Fittin, order:%2 ") .arg(title).arg(order); strDes += "<br/>"; const size_t factorSize = factor->getSize(); QString fun; for (size_t j = 0;j<factorSize;++j) { double f = factor->getAt({j}).toDouble(); if (0 == j) { fun = QString("y = %1").arg(factor->getAt({j}).toString()); continue; } if (1 == j) { if (f>0) fun += QString("+%1x").arg(f); else fun += QString("%1x").arg(f); continue; } if(f>0) fun += QString("+%1x^%2").arg(f).arg(j); else fun += QString("%1x^%2").arg(f).arg(j); } strDes += (TR("fitting results:")+fun); strDes += "<br/>"; //残差,残差平方和,回归平方和,均方根误差 strDes += TR("error:"); strDes += "<br/>"; strDes += TR("SSR(Regression Square Sum)=%1").arg(info->getAt({0,1}).toString()); strDes += "<br/>"; strDes += TR("SSE(Sum of Squares for Error)=%1").arg(info->getAt({1,1}).toString()); strDes += "<br/>"; strDes += TR("SST=%1").arg(info->getAt({2,1}).toString()); strDes += "<br/>"; strDes += TR("RMSE(Root mean square error)=%1").arg(info->getAt({3,1}).toString()); strDes += "<br/>"; strDes += TR("R-square(coefficient of determination)=%1").arg(info->getAt({4,1}).toString()); strDes += "<br/>"; strDes += TR("Goodness=%1").arg(info->getAt({5,1}).toString()); strDes += "</p>"; chart->addCurve(pfitVal.get()); saUI->showNormalMessageInfo(strDes); } }
void pointSmooth(SAUIInterface* ui) { QList<QwtPlotItem*> curs; SAChart2D* chart = filter_xy_series(ui,curs); if(nullptr == chart || curs.size() <= 0) { ui->showMessageInfo(TR("unsupport chart items"),SA::WarningMessage); return; } int m,n; if(!getPointSmoothPorperty(m,n,ui)) { return; } QStringList infos; QScopedPointer<SAFigureOptCommand> topCmd(new SAFigureOptCommand(chart,QString("%1 point %2 power").arg(m).arg(n))); for (int i = 0;i<curs.size();++i) { QwtPlotItem* item = curs[i]; QString title = item->title().text(); switch(item->rtti()) { case QwtPlotItem::Rtti_PlotCurve: { QVector<double> xs,ys; { QVector<QPointF> wave; SAChart::getPlotCurveSample(item,wave); xs.reserve(wave.size()); ys.reserve(wave.size()); std::for_each(wave.begin(),wave.end(),[&xs](const QPointF& p){xs.push_back(p.x());}); std::for_each(wave.begin(),wave.end(),[&ys](const QPointF& p){ys.push_back(p.y());}); } QVector<double> res; if(!saFun::pointSmooth(ys,m,n,res)) { continue; } QVector<QPointF> xys; saFun::makeVectorPointF(xs,res,xys); new SAFigureReplaceAllDatasCommand<QPointF,QwtPlotCurve,decltype(&SAChart::setPlotCurveSample)> (chart ,item ,xys ,TR("%1 m%2n%3").arg(title).arg(m).arg(n) ,&SAChart::setPlotCurveSample ,&SAChart::getPlotCurveSample ,topCmd.data() ); infos.append(TR("%1 m%2n%3 smooth").arg(title).arg(m).arg(n)); break; } } /* QwtSeriesStore<QPointF>* series = dynamic_cast<QwtSeriesStore<QPointF>*>(item); if(nullptr == series) { continue; } QVector<double> xs,ys; if(!chart->getXYData(&xs,&ys,item)) { continue; } if(!chart->getXYData(&xs,&ys,item)) { continue; } QVector<double> res; if(!saFun::pointSmooth(ys,m,n,res)) { continue; } QVector<QPointF> xys; saFun::makeVectorPointF(xs,res,xys); new SAFigureChangeXYSeriesDataCommand(chart ,series ,TR("%1 m%2n%3").arg(title).arg(m).arg(n) ,xys ,topCmd.data()); infos.append(TR("%1 m%2n%3 smooth").arg(title).arg(m).arg(n)); */ } if(topCmd->childCount() > 0) { chart->appendCommand(topCmd.take()); ui->showNormalMessageInfo(infos.join('\n')); } }