বুস্ট ব্যবহার করে নমুনা সম্বলিত ভেক্টরের জন্য গড় এবং স্ট্যান্ডার্ড বিচ্যুতি গণনার কোনও উপায় আছে কি ?
বা আমাকে কী একটি সঞ্চয়ী তৈরি করতে এবং এতে ভেক্টরকে খাওয়ানো উচিত?
বুস্ট ব্যবহার করে নমুনা সম্বলিত ভেক্টরের জন্য গড় এবং স্ট্যান্ডার্ড বিচ্যুতি গণনার কোনও উপায় আছে কি ?
বা আমাকে কী একটি সঞ্চয়ী তৈরি করতে এবং এতে ভেক্টরকে খাওয়ানো উচিত?
উত্তর:
Accumulators ব্যবহার হয় উপায় উপায়ে এবং স্ট্যান্ডার্ড ডেভিয়েশন গনা বুস্ট ।
accumulator_set<double, stats<tag::variance> > acc;
for_each(a_vec.begin(), a_vec.end(), bind<void>(ref(acc), _1));
cout << mean(acc) << endl;
cout << sqrt(variance(acc)) << endl;
second moment - squared mean
যা গোলটি ত্রুটির কারণে ভেরিয়েন্স খুব ছোট হলে ভুল ফলাফল আনবে। এটি আসলে নেতিবাচক বৈকল্পিক উত্পাদন করতে পারে।
আমি জানি না বুস্টের আরও নির্দিষ্ট ফাংশন রয়েছে কিনা তবে আপনি এটি স্ট্যান্ডার্ড লাইব্রেরি দিয়ে করতে পারেন।
প্রদত্ত std::vector<double> v
, এটি নিখুঁত উপায়:
#include <numeric>
double sum = std::accumulate(v.begin(), v.end(), 0.0);
double mean = sum / v.size();
double sq_sum = std::inner_product(v.begin(), v.end(), v.begin(), 0.0);
double stdev = std::sqrt(sq_sum / v.size() - mean * mean);
এটি বিশাল বা ক্ষুদ্র মানের জন্য উপচে পড়া বা আন্ডারফ্লোতে সংবেদনশীল। স্ট্যান্ডার্ড বিচ্যুতি গণনা করার জন্য কিছুটা ভাল উপায় হ'ল:
double sum = std::accumulate(v.begin(), v.end(), 0.0);
double mean = sum / v.size();
std::vector<double> diff(v.size());
std::transform(v.begin(), v.end(), diff.begin(),
std::bind2nd(std::minus<double>(), mean));
double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
double stdev = std::sqrt(sq_sum / v.size());
সি ++ 11 এর জন্য আপডেট করুন :
কলটির std::transform
পরিবর্তে ল্যাম্বডা ফাংশন ব্যবহার করে std::minus
এবং std::bind2nd
(এখন অবহেলিত) লেখা যেতে পারে :
std::transform(v.begin(), v.end(), diff.begin(), [mean](double x) { return x - mean; });
mean
উপরের অংশে গণনার মানের উপর নির্ভর করে ।
(v.size() - 1)
জন্য v.size()
উপরে গত লাইনে: std::sqrt(sq_sum / (v.size() - 1))
। (প্রথম পদ্ধতির জন্য, এটি কিছুটা জটিল: std::sqrt(sq_sum / (v.size() - 1) - mean * mean * v.size() / (v.size() - 1))
...
std::inner_product
বর্গাকার যোগফলের জন্য ব্যবহার করা খুব ঝরঝরে।
যদি পারফরম্যান্স আপনার পক্ষে গুরুত্বপূর্ণ, এবং আপনার সংকলক ল্যাম্বডাসকে সমর্থন করে তবে স্টাডিভ গণনাটি দ্রুত এবং সহজতর করা যেতে পারে: ভিএস ২০১২ এর সাথে পরীক্ষাগুলিতে আমি খুঁজে পেয়েছি যে নির্বাচিত উত্তরে প্রদত্ত বুস্ট কোডের চেয়ে নীচের কোডটি 10 এক্স এর বেশি দ্রুত ; এটি ম্যাসিফিল দ্বারা প্রদত্ত স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করে উত্তরের নিরাপদ সংস্করণের চেয়ে 5 এক্স দ্রুত।
দ্রষ্টব্য আমি নমুনা স্ট্যান্ডার্ড বিচ্যুতি ব্যবহার করছি, তাই নীচের কোডটি কিছুটা আলাদা ফলাফল দেয় ( স্ট্যান্ডার্ড বিচ্যুতির ক্ষেত্রে একটি বিয়োগ কেন আছে )
double sum = std::accumulate(std::begin(v), std::end(v), 0.0);
double m = sum / v.size();
double accum = 0.0;
std::for_each (std::begin(v), std::end(v), [&](const double d) {
accum += (d - m) * (d - m);
});
double stdev = sqrt(accum / (v.size()-1));
std::end()
ফাংশন ক্ষেত্রে জন্য সি ++ 11 মান দ্বারা যোগ করা হয়েছিল যখন মত কিছুই আছে v.end()
। std::end
কম মান ধারক জন্য ওভারলোড করা যেতে পারে - দেখুন en.cppreference.com/w/cpp/iterator/end
ম্যাসিফিল দ্বারা উত্তরের উন্নতি করে , আপনি diff
কেবল অস্থায়ী ভেক্টর ছাড়াই একটি স্ট্যান্ডার্ড বিচ্যুতি ফাংশন লিখতে পারেন , কেবল inner_product
সি ++ 11 ল্যাম্বদা ক্ষমতা সহ একক কল ব্যবহার করে:
double stddev(std::vector<double> const & func)
{
double mean = std::accumulate(func.begin(), func.end(), 0.0) / func.size();
double sq_sum = std::inner_product(func.begin(), func.end(), func.begin(), 0.0,
[](double const & x, double const & y) { return x + y; },
[mean](double const & x, double const & y) { return (x - mean)*(y - mean); });
return std::sqrt(sq_sum / ( func.size() - 1 ));
}
আমি সন্দেহ করি যে অতিরিক্ত মধ্যবর্তী স্টোরেজটি ব্যবহারের চেয়ে একাধিকবার বিয়োগ করা কম দামের এবং আমি মনে করি এটি আরও পাঠযোগ্য, তবে আমি এখনও সম্পাদনটি পরীক্ষা করে দেখিনি।
দেখে মনে হচ্ছে এটি নীচের মার্জিত পুনরাবৃত্ত সমাধান সমাধান করা হয় নি, যদিও এটি দীর্ঘ সময় ধরে ছিল। নুথের আর্ট অফ কম্পিউটার প্রোগ্রামিংকে উল্লেখ করে,
mean_1 = x_1, variance_1 = 0; //initial conditions; edge case;
//for k >= 2,
mean_k = mean_k-1 + (x_k - mean_k-1) / k;
variance_k = variance_k-1 + (x_k - mean_k-1) * (x_k - mean_k);
তারপরে n>=2
মানগুলির তালিকার জন্য , প্রমিত বিচ্যুতির প্রাক্কলনটি হ'ল:
stddev = std::sqrt(variance_n / (n-1)).
আশাকরি এটা সাহায্য করবে!
আমার উত্তর জোশ গ্রিফারের মতো তবে একই সাথে সাধারণভাবে প্রচার করা হয়েছে ov নমুনা বৈকল্পিক মাত্র নমুনা covarانس হয় তবে দুটি ইনপুট একই। এর মধ্যে বেসেলের পারস্পরিক সম্পর্ক রয়েছে।
template <class Iter> typename Iter::value_type cov(const Iter &x, const Iter &y)
{
double sum_x = std::accumulate(std::begin(x), std::end(x), 0.0);
double sum_y = std::accumulate(std::begin(y), std::end(y), 0.0);
double mx = sum_x / x.size();
double my = sum_y / y.size();
double accum = 0.0;
for (auto i = 0; i < x.size(); i++)
{
accum += (x.at(i) - mx) * (y.at(i) - my);
}
return accum / (x.size() - 1);
}
পূর্বে উল্লিখিত সংস্করণগুলির চেয়ে 2x দ্রুত - বেশিরভাগ কারণ রূপান্তর () এবং অভ্যন্তরীণ_প্রডাক্ট () লুপগুলি যোগদান করেছে। আমার শর্টকাট / টাইপিডস / ম্যাক্রো সম্পর্কে দুঃখিত: ফ্লো = ফ্লোট। সিআর কনস্ট রেফ ভিএফ্লো - ভেক্টর ভিএস2010-এ পরীক্ষিত
#define fe(EL, CONTAINER) for each (auto EL in CONTAINER) //VS2010
Flo stdDev(VFlo CR crVec) {
SZ n = crVec.size(); if (n < 2) return 0.0f;
Flo fSqSum = 0.0f, fSum = 0.0f;
fe(f, crVec) fSqSum += f * f; // EDIT: was Cit(VFlo, crVec) {
fe(f, crVec) fSum += f;
Flo fSumSq = fSum * fSum;
Flo fSumSqDivN = fSumSq / n;
Flo fSubSqSum = fSqSum - fSumSqDivN;
Flo fPreSqrt = fSubSqSum / (n - 1);
return sqrt(fPreSqrt);
}
for( float f : crVec ) { fSqSum += f * f; fSum += f; }
?
আপনার নিজস্ব ধারক তৈরি করুন:
template <class T>
class statList : public std::list<T>
{
public:
statList() : std::list<T>::list() {}
~statList() {}
T mean() {
return accumulate(begin(),end(),0.0)/size();
}
T stddev() {
T diff_sum = 0;
T m = mean();
for(iterator it= begin(); it != end(); ++it)
diff_sum += ((*it - m)*(*it -m));
return diff_sum/size();
}
};
এটির কিছু সীমাবদ্ধতা রয়েছে তবে আপনি কী করছেন জানেন যখন এটি সুন্দরভাবে কাজ করে।
// এর অর্থ সি ++ এ বিচ্যুতি
/ একটি বিচ্যুতি যা একটি পর্যবেক্ষণ করা মান এবং স্বার্থের পরিমাণের প্রকৃত মূল্যের মধ্যে পার্থক্য (যেমন একটি জনসংখ্যার অর্থ) একটি ত্রুটি এবং এমন একটি বিচ্যুতি যা পর্যবেক্ষণকৃত মান এবং সত্য মানের একটি অনুমানের মধ্যে পার্থক্য (যেমন অনুমান একটি নমুনা গড় হতে পারে) একটি অবশিষ্টাংশ। এই ধারণাগুলি পরিমাপের ব্যবধান এবং অনুপাত স্তরের ডেটার জন্য প্রযোজ্য। /
#include <iostream>
#include <conio.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv)
{
int i,cnt;
cout<<"please inter count:\t";
cin>>cnt;
float *num=new float [cnt];
float *s=new float [cnt];
float sum=0,ave,M,M_D;
for(i=0;i<cnt;i++)
{
cin>>num[i];
sum+=num[i];
}
ave=sum/cnt;
for(i=0;i<cnt;i++)
{
s[i]=ave-num[i];
if(s[i]<0)
{
s[i]=s[i]*(-1);
}
cout<<"\n|ave - number| = "<<s[i];
M+=s[i];
}
M_D=M/cnt;
cout<<"\n\n Average: "<<ave;
cout<<"\n M.D(Mean Deviation): "<<M_D;
getch();
return 0;
}