/* Returns [ slope, constant, minLS ] * where minLS = sum_i w_i res_i^2 */ real_t * wLinearRegression( const real_t * w, const real_t * x, const real_t * y, const bool * allowed, const uint_fast32_t n, real_t *res){ if(NULL==w){ return NULL;} if(NULL==x){ return NULL;} if(NULL==y){ return NULL;} if(n==0){return NULL;} // Matter of definition if(NULL==res){ res = calloc(3,sizeof(real_t));} if(NULL==res){ return NULL;} real_t wmx = wmean(w,x,allowed,n); real_t wmy = wmean(w,y,allowed,n); real_t wmxx = wmeanxx(w,x,allowed,n); // Could be made more generic, to wmean(w,f(x),n); real_t wmxy = wmeanxy(w,x,y,allowed,n); real_t wmyy = wmeanxx(w,y,allowed,n); real_t ws = sum(w,allowed,n); res[0] = (wmxy-wmx*wmy)/(wmxx-wmx*wmx); // Solve LS problem for slope res[1] = wmy - res[0]*wmx; // Error remaining res[2] = ws*(wmyy - res[0] * wmxy - res[1] * wmy); return res; }
double wvar(double* x, double* w, long n){ long i; double res=0.; double nef=0.; double mm = wmean(x, w, n); for(i=0; i<n; i++){ if(isnan(x[i])==0){ res += w[i]*pow(x[i]-mm, 2.0); nef += w[i]; } } return res/nef; }
/* Weighted variance by compensated summation */ real_t wvariance( const real_t * w, const real_t * x, const bool * allowed, const uint_fast32_t n){ if(NULL==w || NULL==x){return NAN;} const real_t m = wmean(x,w,allowed,n); real_t v = 0.; real_t c = 0.; real_t wsum = 0.0; uint_fast32_t nallowed = 0; for ( uint_fast32_t i=0; i<n ; i++){ if(NULL!=allowed && !allowed[i]){ continue; } volatile real_t y = w[i]*(x[i] - m)*(x[i]-m) - c; volatile real_t t = v + y; c = (t-v) - y; v = t; // Sum of weights not compensated wsum += w[i]; nallowed++; } return v/(nallowed-1.) * nallowed/wsum; }