[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [labplot/analysis_smooth] src: added lagged moving average for all weights
From:       Stefan Gerlach <stefan.gerlach () uni-konstanz ! de>
Date:       2016-05-16 18:48:44
Message-ID: E1b2NZM-00076V-Sl () scm ! kde ! org
[Download RAW message or body]

Git commit a6b130ef7c731abd330f4e781e1d82ce71d08f29 by Stefan Gerlach.
Committed on 16/05/2016 at 18:48.
Pushed by sgerlach into branch 'analysis_smooth'.

added lagged moving average for all weights

M  +130  -68   src/backend/worksheet/plots/cartesian/XYSmoothCurve.cpp
M  +1    -1    src/backend/worksheet/plots/cartesian/XYSmoothCurve.h
M  +2    -2    src/kdefrontend/dockwidgets/XYSmoothCurveDock.cpp

http://commits.kde.org/labplot/a6b130ef7c731abd330f4e781e1d82ce71d08f29

diff --git a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.cpp \
b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.cpp index de25fbc..b03feef \
                100644
--- a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.cpp
+++ b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.cpp
@@ -252,78 +252,140 @@ void XYSmoothCurvePrivate::recalculate() {
 
 	xVector->resize(n);
 	yVector->resize(n);
-	// moving average
-	for(unsigned int i=0;i<n;i++) {
-		(*xVector)[i] = xdata[i];
-
-		unsigned int diff = qMin(qMin((points-1)/2,i),n-i-1);
-		unsigned int np = 2*diff+1;
-
-		// weight (see https://en.wikipedia.org/wiki/Kernel_%28statistics%29)
-		double sum=0.0, *w = new double[np];
-		switch(weight) {
-		case XYSmoothCurve::Uniform:
-			for(unsigned int j=0;j<np;j++)
-				w[j]=1./np;
-			break;
-		case XYSmoothCurve::Triangular:
-			sum = gsl_pow_2((np+1)/2);
-			for(unsigned int j=0;j<np;j++)
-				w[j]=qMin(j+1,np-j)/sum;
-			break;
-		case XYSmoothCurve::Binomial:
-			sum = (np-1)/2.;
-			for(unsigned int j=0;j<np;j++)
-				w[j]=gsl_sf_choose(2*sum,sum+fabs(j-sum))/pow(4.,sum);
-			break;
-		case XYSmoothCurve::Parabolic:
-			for(unsigned int j=0;j<np;j++) {
-				w[j]=1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2);
-				sum += w[j];
-			}
-			for(unsigned int j=0;j<np;j++)
-				w[j] /= sum;
-			break;
-		case XYSmoothCurve::Quartic:
-			for(unsigned int j=0;j<np;j++) {
-				w[j]=gsl_pow_2(1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2));
-				sum += w[j];
-			}
-			for(unsigned int j=0;j<np;j++)
-				w[j] /= sum;
-			break;
-		case XYSmoothCurve::Triweight:
-			for(unsigned int j=0;j<np;j++) {
-				w[j]=gsl_pow_3(1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2));
-				sum += w[j];
-			}
-			for(unsigned int j=0;j<np;j++)
-				w[j] /= sum;
-			break;
-		case XYSmoothCurve::Tricube:
-			for(unsigned int j=0;j<np;j++) {
-				w[j]=gsl_pow_3(1.-gsl_pow_3(fabs(j-(np-1)/2.))/gsl_pow_3((np+1)/2));
-				sum += w[j];
+	switch(type) {
+	case XYSmoothCurve::MovingAverage:
+	case XYSmoothCurve::MovingAverageLagged:
+		for(unsigned int i=0;i<n;i++) {
+			(*xVector)[i] = xdata[i];
+
+			unsigned int diff,np;
+			if(type == XYSmoothCurve::MovingAverage) {
+				diff = qMin(qMin((points-1)/2,i),n-i-1);
+				np = 2*diff+1;
+			} else {
+				np = qMin(points,i+1);
+				diff = np-1;
 			}
-			for(unsigned int j=0;j<np;j++)
-				w[j] /= sum;
-			break;
-		case XYSmoothCurve::Cosine:
-			for(unsigned int j=0;j<np;j++) {
-				w[j]=cos(M_PI/2.*(j-(np-1)/2.)/((np+1)/2));
-				sum += w[j];
+			qDebug()<<"i ="<<i<<"np ="<<np;
+
+			// weight (see https://en.wikipedia.org/wiki/Kernel_%28statistics%29)
+			double sum=0.0, *w = new double[np];
+			switch(weight) {
+			case XYSmoothCurve::Uniform:
+				for(unsigned int j=0;j<np;j++)
+					w[j]=1./np;
+				break;
+			case XYSmoothCurve::Triangular:
+				if(type == XYSmoothCurve::MovingAverage) {
+					sum = gsl_pow_2((np+1)/2);
+					for(unsigned int j=0;j<np;j++)
+						w[j]=qMin(j+1,np-j)/sum;
+				} else {
+					sum = np*(np+1)/2;
+					for(unsigned int j=0;j<np;j++)
+						w[j]=(j+1)/sum;
+				}
+				break;
+			case XYSmoothCurve::Binomial:
+				if(type == XYSmoothCurve::MovingAverage) {
+					sum = (np-1)/2.;
+					for(unsigned int j=0;j<np;j++)
+						w[j]=gsl_sf_choose(2*sum,sum+fabs(j-sum))/pow(4.,sum);
+				} else {
+					//TODO: check even np
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_sf_choose(2*(np-1),j);
+						sum += w[j];
+					}
+					for(unsigned int j=0;j<np;j++)
+						w[j] /= sum;
+				}
+				break;
+			case XYSmoothCurve::Parabolic:
+				if(type == XYSmoothCurve::MovingAverage) {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2);
+						sum += w[j];
+					}
+				} else {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=1.-gsl_pow_2(1.-(1+j)/(double)np);
+						sum += w[j];
+					}
+				}
+				for(unsigned int j=0;j<np;j++)
+					w[j] /= sum;
+				break;
+			case XYSmoothCurve::Quartic:
+				if(type == XYSmoothCurve::MovingAverage) {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_2(1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2));
+						sum += w[j];
+					}
+				} else {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_2(1.-gsl_pow_2(1.-(1+j)/(double)np));
+						sum += w[j];
+					}
+				}
+				for(unsigned int j=0;j<np;j++)
+					w[j] /= sum;
+				break;
+			case XYSmoothCurve::Triweight:
+				if(type == XYSmoothCurve::MovingAverage) {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_3(1.-gsl_pow_2(j-(np-1)/2.)/gsl_pow_2((np+1)/2));
+						sum += w[j];
+					}
+				} else {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_3(1.-gsl_pow_2(1.-(1+j)/(double)np));
+						sum += w[j];
+					}
+				}
+				for(unsigned int j=0;j<np;j++)
+					w[j] /= sum;
+				break;
+			case XYSmoothCurve::Tricube:
+				if(type == XYSmoothCurve::MovingAverage) {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_3(1.-gsl_pow_3(fabs(j-(np-1)/2.))/gsl_pow_3((np+1)/2));
+						sum += w[j];
+					}
+				} else {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=gsl_pow_3(1.-gsl_pow_3(1.-(1+j)/(double)np));
+						sum += w[j];
+					}
+				}
+				for(unsigned int j=0;j<np;j++)
+					w[j] /= sum;
+				break;
+			case XYSmoothCurve::Cosine:
+				if(type == XYSmoothCurve::MovingAverage) {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=cos(M_PI/2.*(j-(np-1)/2.)/((np+1)/2));
+						sum += w[j];
+					}
+				} else {
+					for(unsigned int j=0;j<np;j++) {
+						w[j]=cos(M_PI/2.*(np-1-j)/np);
+						sum += w[j];
+					}
+				}
+				for(unsigned int j=0;j<np;j++)
+					w[j] /= sum;
+				break;
 			}
-			for(unsigned int j=0;j<np;j++)
-				w[j] /= sum;
-			break;
-		}
 
-		// calculate weighted average
-		(*yVector)[i] = 0.0;
-		for(unsigned int j=0;j<np;j++)
-			(*yVector)[i] += w[j]*ydata[i-diff+j];
+			// calculate weighted average
+			(*yVector)[i] = 0.0;
+			for(unsigned int j=0;j<np;j++)
+				(*yVector)[i] += w[j]*ydata[i-diff+j];
 
-		delete[] w;
+			delete[] w;
+		}
+		break;
 	}
 
 ///////////////////////////////////////////////////////////
diff --git a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h \
b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h index ab9808a..83bb371 100644
--- a/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h
+++ b/src/backend/worksheet/plots/cartesian/XYSmoothCurve.h
@@ -36,7 +36,7 @@ class XYSmoothCurve: public XYCurve {
 	Q_OBJECT
 
 	public:
-		enum SmoothType {MovingAverage};
+		enum SmoothType {MovingAverage,MovingAverageLagged};
 		enum WeightType {Uniform, Triangular, Binomial, Parabolic, Quartic, Triweight, \
Tricube, Cosine};  
 		struct SmoothData {
diff --git a/src/kdefrontend/dockwidgets/XYSmoothCurveDock.cpp \
b/src/kdefrontend/dockwidgets/XYSmoothCurveDock.cpp index d62566e..142ea45 100644
--- a/src/kdefrontend/dockwidgets/XYSmoothCurveDock.cpp
+++ b/src/kdefrontend/dockwidgets/XYSmoothCurveDock.cpp
@@ -83,7 +83,7 @@ void XYSmoothCurveDock::setupGeneral() {
 	gridLayout->addWidget(cbYDataColumn, 5, 3, 1, 2);
 
 	uiGeneralTab.cbType->addItem(i18n("moving average (central)"));
-//	uiGeneralTab.cbType->addItem(i18n("moving average (lagged)"));
+	uiGeneralTab.cbType->addItem(i18n("moving average (lagged)"));
 //	uiGeneralTab.cbType->addItem(i18n("percentile"));
 //	uiGeneralTab.cbType->addItem(i18n("Savitzky-Golay"));
 //	uiGeneralTab.cbType->addItem(i18n("LOWESS/LOESS"));
@@ -97,7 +97,7 @@ void XYSmoothCurveDock::setupGeneral() {
 	uiGeneralTab.cbWeight->addItem(i18n("triweight"));
 	uiGeneralTab.cbWeight->addItem(i18n("tricube"));
 	uiGeneralTab.cbWeight->addItem(i18n("cosine"));
-// IIR
+// IIR	-> np="all"
 //	uiGeneralTab.cbWeight->addItem(i18n("exponential"));
 //	uiGeneralTab.cbWeight->addItem(i18n("Gaussian"));
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic