Код
/*
*
* Copyright (C) 2007 Matwey V. Kornilov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <cmath>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>
namespace std{
template<class T, class U> std::istream& operator>>(std::istream& stm, std::pair<T,U>& p);
template<class T, class U> std::ostream& operator<<(std::ostream& stm, const std::pair<T,U>& p);
template<class T, class U> std::pair<T,U> operator+(const std::pair<T,U>& a, const std::pair<T,U>& b);
template<class T, class U, class V> std::pair<T,U> operator/(const std::pair<T,U>& a, V b);
};
template<class T, class U>
std::istream& std::operator>>(std::istream& stm, std::pair<T,U>& p){
return stm >> p.first >> p.second;
}
template<class T, class U>
std::ostream& std::operator<<(std::ostream& stm, const std::pair<T,U>& p){
return stm << p.first << "," << p.second;
}
template<class T, class U>
std::pair<T,U> std::operator+(const std::pair<T,U>& a, const std::pair<T,U>& b){
return std::pair<T,U> (a.first+b.first,a.second+b.second);
}
template<class T, class U, class V>
std::pair<T,U> std::operator/(const std::pair<T,U>& a, V b){
return std::pair<T,U> (a.first/b,a.second/b);
}
namespace{
typedef double value_type;
typedef std::pair< value_type, value_type > pair_type;
typedef std::vector< pair_type > container_type;
};
template<class T, class U> class op_diff{
private:
U m_avg;
T m_diff_mult;
T m_diff_xpow;
T m_diff_ypow;
public:
op_diff( const U& avg );
void operator()( const U& elem );
T diff_mult() const;
T diff_xpow() const;
T diff_ypow() const;
};
template<class T, class U>
op_diff<T,U>::op_diff( const U& avg ) : m_avg(avg),m_diff_mult(0),m_diff_xpow(0),m_diff_ypow(0) {
}
template<class T, class U>
void op_diff<T,U>::operator()( const U& elem ){
m_diff_mult += ( m_avg.first - elem.first ) * ( m_avg.second - elem.second );
m_diff_xpow += std::pow( m_avg.first - elem.first, 2 );
m_diff_ypow += std::pow( m_avg.second - elem.second, 2 );
}
template<class T, class U> T op_diff<T,U>::diff_mult() const { return m_diff_mult; }
template<class T, class U> T op_diff<T,U>::diff_xpow() const { return m_diff_xpow; }
template<class T, class U> T op_diff<T,U>::diff_ypow() const { return m_diff_ypow; }
container_type g_mvec;
int main( int argc, char** argv ){
std::copy(
std::istream_iterator< pair_type > ( std::cin ),
std::istream_iterator< pair_type > ( ),
std::back_inserter( g_mvec )
);
pair_type average = std::accumulate( g_mvec.begin(), g_mvec.end(), pair_type(0,0) ) / g_mvec.size();
op_diff<value_type,pair_type> diff = std::for_each( g_mvec.begin(), g_mvec.end(), op_diff<value_type,pair_type>( average ) );
value_type diff_mult = diff.diff_mult();
value_type diff_xpow = diff.diff_xpow();
value_type diff_ypow = diff.diff_ypow();
value_type Sx = std::sqrt( diff_xpow / ( g_mvec.size() - 1 ) );
value_type Sy = std::sqrt( diff_ypow / ( g_mvec.size() - 1 ) );
value_type r = diff_mult / ( ( g_mvec.size() - 1 ) * Sx * Sy );
value_type SB = Sy/Sx * std::sqrt( ( 1 - std::pow(r,2) ) / ( g_mvec.size() - 2 ) );
value_type B = ( diff_mult ) / ( diff_xpow );
value_type H = average.second - B * average.first;
std::cout << "Average: " << average << std::endl;
std::cout << "Sx: " << Sx << std::endl;
std::cout << "Sy: " << Sy << std::endl;
std::cout << "Correlation rate: " << r << std::endl;
std::cout << "Standard deviation: " << SB << std::endl;
std::cout << "B: ( y = Bx + H ) " << B << std::endl;
std::cout << "H: " << H << std::endl;
return 0;
}