From f9432cb3daed9f16fcf5cf3baa8194b015d0dadb Mon Sep 17 00:00:00 2001 From: Marcel Hendrix Date: Thu, 16 Apr 2015 21:05:52 +0200 Subject: [PATCH] frontend/com_measure2.c, bug fix for "meas AVG" meas "AVG" did merely the average of the given values, without consideration of their spacing on the "scale" axis. now use trapezoidal summing to calculate the AVG note, there is "meas INTEG" which goes beyond trapezoidal summing --- src/frontend/com_measure2.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/frontend/com_measure2.c b/src/frontend/com_measure2.c index cb47aabc2..ebf217783 100644 --- a/src/frontend/com_measure2.c +++ b/src/frontend/com_measure2.c @@ -696,9 +696,10 @@ measure_minMaxAvg( ANALYSIS_TYPE_T mFunctionType /* in: one of AT_AVG, AT_MIN, AT_MAX, AT_MIN_AT, AT_MAX_AT */ ) { - int i, avgCnt; + int i; struct dvec *d, *dScale; double value, svalue, mValue, mValueAt; + double pvalue = 0.0, sprev = 0.0, Tsum = 0.0; int first; bool ac_check = FALSE, sp_check = FALSE, dc_check = FALSE, tran_check = FALSE; @@ -707,7 +708,6 @@ measure_minMaxAvg( meas->m_measured = NAN; meas->m_measured_at = NAN; first = 0; - avgCnt = 0; d = vec_get(meas->m_vec); if (d == NULL) { @@ -778,10 +778,26 @@ measure_minMaxAvg( } if (first == 0) { - mValue = value; - mValueAt = svalue; first = 1; + switch (mFunctionType) { + case AT_MIN: + case AT_MIN_AT: + case AT_MAX_AT: + case AT_MAX: + mValue = value; + mValueAt = svalue; + break; + case AT_AVG: + mValue = 0.0; + mValueAt = svalue; + Tsum = 0.0; + pvalue = value; + sprev = svalue; + break; + default: + fprintf(cp_err, "Error: improper min/max/avg call.\n"); + } } else { switch (mFunctionType) { case AT_MIN: @@ -801,8 +817,10 @@ measure_minMaxAvg( break; } case AT_AVG: { - mValue = mValue + value; - avgCnt ++; + mValue += 0.5 * (value + pvalue) * (svalue - sprev); + Tsum += (svalue - sprev); + pvalue = value; + sprev = svalue; break; } default : @@ -815,7 +833,7 @@ measure_minMaxAvg( switch (mFunctionType) { case AT_AVG: { - meas->m_measured = (mValue / avgCnt); + meas->m_measured = mValue / (first ? Tsum : 1.0); meas->m_measured_at = svalue; break; }