return train(TrainData::create(samples, layout, responses));
}
-float StatModel::calcError( const Ptr<TrainData>& data, bool testerr, OutputArray _resp ) const
+class ParallelCalcError : public ParallelLoopBody
+{
+private:
+ const Ptr<TrainData>& data;
+ bool &testerr;
+ Mat &resp;
+ const StatModel &s;
+ vector<double> &errStrip;
+public:
+ ParallelCalcError(const Ptr<TrainData>& d, bool &t, Mat &_r,const StatModel &w, vector<double> &e) :
+ data(d),
+ testerr(t),
+ resp(_r),
+ s(w),
+ errStrip(e)
+ {
+ }
+ virtual void operator()(const Range& range) const
+ {
+ int idxErr = range.start;
+ CV_TRACE_FUNCTION_SKIP_NESTED();
+ Mat samples = data->getSamples();
+ int layout = data->getLayout();
+ Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
+ const int* sidx_ptr = sidx.ptr<int>();
+ bool isclassifier = s.isClassifier();
+ Mat responses = data->getResponses();
+ int responses_type = responses.type();
+
+ double err = 0;
+
+ for (int i = range.start; i < range.end; i++)
+ {
+ int si = sidx_ptr ? sidx_ptr[i] : i;
+ Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
+ float val = s.predict(sample);
+ float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
+
+ if (isclassifier)
+ err += fabs(val - val0) > FLT_EPSILON;
+ else
+ err += (val - val0)*(val - val0);
+ if (!resp.empty())
+ resp.at<float>(i) = val;
+ }
+
+
+ errStrip[idxErr]=err ;
+
+ };
+ ParallelCalcError& operator=(const ParallelCalcError &) {
+ return *this;
+ };
+};
+
+
+float StatModel::calcError(const Ptr<TrainData>& data, bool testerr, OutputArray _resp) const
{
CV_TRACE_FUNCTION_SKIP_NESTED();
Mat samples = data->getSamples();
- int layout = data->getLayout();
Mat sidx = testerr ? data->getTestSampleIdx() : data->getTrainSampleIdx();
- const int* sidx_ptr = sidx.ptr<int>();
- int i, n = (int)sidx.total();
+ int n = (int)sidx.total();
bool isclassifier = isClassifier();
Mat responses = data->getResponses();
- int responses_type = responses.type();
- if( n == 0 )
+ if (n == 0)
n = data->getNSamples();
- if( n == 0 )
+ if (n == 0)
return -FLT_MAX;
Mat resp;
- if( _resp.needed() )
+ if (_resp.needed())
resp.create(n, 1, CV_32F);
double err = 0;
- for( i = 0; i < n; i++ )
- {
- int si = sidx_ptr ? sidx_ptr[i] : i;
- Mat sample = layout == ROW_SAMPLE ? samples.row(si) : samples.col(si);
- float val = predict(sample);
- float val0 = (responses_type == CV_32S) ? (float)responses.at<int>(si) : responses.at<float>(si);
-
- if( isclassifier )
- err += fabs(val - val0) > FLT_EPSILON;
- else
- err += (val - val0)*(val - val0);
- if( !resp.empty() )
- resp.at<float>(i) = val;
- /*if( i < 100 )
- {
- printf("%d. ref %.1f vs pred %.1f\n", i, val0, val);
- }*/
- }
+ vector<double> errStrip(n,0.0);
+ ParallelCalcError x(data, testerr, resp, *this,errStrip);
+
+ parallel_for_(Range(0,n),x);
+
+ for (size_t i = 0; i < errStrip.size(); i++)
+ err += errStrip[i];
- if( _resp.needed() )
+ if (_resp.needed())
resp.copyTo(_resp);
return (float)(err / n * (isclassifier ? 100 : 1));