Beispiel #1
0
static void menu_cb_removePoints (RealTierEditor me, EDITOR_ARGS_DIRECT) {
	Editor_save (me, U"Remove point(s)");
	RealTier tier = (RealTier) my data;
	if (my d_startSelection == my d_endSelection)
		AnyTier_removePointNear (tier->asAnyTier(), my d_startSelection);
	else
		AnyTier_removePointsBetween (tier->asAnyTier(), my d_startSelection, my d_endSelection);
	RealTierEditor_updateScaling (me);
	FunctionEditor_redraw (me);
	Editor_broadcastDataChanged (me);
}
Beispiel #2
0
double RealTier_getStandardDeviation_curve (RealTier me, double tmin, double tmax) {
	long n = my points.size, imin, imax;
	double mean, integral = 0.0;
	if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; }   // autowindow
	if (n == 0) return NUMundefined;
	if (n == 1) return 0.0;
	imin = AnyTier_timeToLowIndex (me->asAnyTier(), tmin);
	if (imin == n) return 0.0;
	imax = AnyTier_timeToHighIndex (me->asAnyTier(), tmax);
	if (imax == 1) return 0.0;
	Melder_assert (imin < n);
	Melder_assert (imax > 1);
	/*
	 * Add the areas between the points.
	 * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright).
	 */
	mean = RealTier_getMean_curve (me, tmin, tmax);
	for (long i = imin; i < imax; i ++) {
		double tleft, fleft, tright, fright, sum, diff;
		if (i == imin) {
			tleft = tmin;
			fleft = RealTier_getValueAtTime (me, tmin);
		} else {
			tleft = my points.at [i] -> number;
			fleft = my points.at [i] -> value - mean;
		}
		if (i + 1 == imax) {
			tright = tmax;
			fright = RealTier_getValueAtTime (me, tmax);
		} else {
			tright = my points.at [i + 1] -> number;
			fright = my points.at [i + 1] -> value - mean;
		}
		/*
		 * The area is integral dt f^2
		 *   = integral dt [f1 + (f2-f1)/(t2-t1) (t-t1)]^2
		 *   = int dt f1^2 + int dt 2 f1 (f2-f1)/(t2-t1) (t-t1) + int dt [(f2-f1)/(t2-t1)]^2 (t-t1)^2
		 *   = f1^2 (t2-t1) + f1 (f2-f1)/(t2-t1) (t2-t1)^2 + 1/3 [(f2-f1)/(t2-t1)]^2 (t2-t1)^3
		 *   = (t2-t1) [f1 f2 + 1/3 (f2-f1)^2]
		 *   = (t2-t1) (f1^2 + f2^2 + 1/3 f1 f2)
		 *   = (t2-t1) [1/4 (f1+f2)^2 + 1/12 (f1-f2)^2]
		 * In the last expression, we have a sum of squares, which is computationally best.
		 */
		sum = fleft + fright;
		diff = fleft - fright;
		integral += (sum * sum + (1.0/3.0) * diff * diff) * (tright - tleft);
	}
	return sqrt (0.25 * integral / (tmax - tmin));
}
Beispiel #3
0
void RealTier_removePointsBelow (RealTier me, double level) {
	for (long ipoint = my points.size; ipoint > 0; ipoint --) {
		RealPoint point = my points.at [ipoint];
		if (point -> value < level) {
			AnyTier_removePoint (me->asAnyTier(), ipoint);
		}
	}
}
Beispiel #4
0
void RealTier_draw (RealTier me, Graphics g, double tmin, double tmax, double fmin, double fmax,
	int garnish, const char32 *method, const char32 *quantity)
{
	bool drawLines = str32str (method, U"lines") || str32str (method, U"Lines");
	bool drawSpeckles = str32str (method, U"speckles") || str32str (method, U"Speckles");
	long n = my points.size, imin, imax, i;
	if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; }
	Graphics_setWindow (g, tmin, tmax, fmin, fmax);
	Graphics_setInner (g);
	imin = AnyTier_timeToHighIndex (me->asAnyTier(), tmin);
	imax = AnyTier_timeToLowIndex (me->asAnyTier(), tmax);
	if (n == 0) {
	} else if (imax < imin) {
		double fleft = RealTier_getValueAtTime (me, tmin);
		double fright = RealTier_getValueAtTime (me, tmax);
		if (drawLines) Graphics_line (g, tmin, fleft, tmax, fright);
	} else for (i = imin; i <= imax; i ++) {
		RealPoint point = my points.at [i];
		double t = point -> number, f = point -> value;
		if (drawSpeckles) Graphics_speckle (g, t, f);
		if (drawLines) {
			if (i == 1)
				Graphics_line (g, tmin, f, t, f);
			else if (i == imin)
				Graphics_line (g, t, f, tmin, RealTier_getValueAtTime (me, tmin));
			if (i == n)
				Graphics_line (g, t, f, tmax, f);
			else if (i == imax)
				Graphics_line (g, t, f, tmax, RealTier_getValueAtTime (me, tmax));
			else {
				RealPoint pointRight = my points.at [i + 1];
				Graphics_line (g, t, f, pointRight -> number, pointRight -> value);
			}
		}
	}
	Graphics_unsetInner (g);
	if (garnish) {
		Graphics_drawInnerBox (g);
		Graphics_textBottom (g, true, my v_getUnitText (0, 0, 0));
		Graphics_marksBottom (g, 2, true, true, false);
		Graphics_marksLeft (g, 2, true, true, false);
		if (quantity) Graphics_textLeft (g, true, quantity);
	}
}
Beispiel #5
0
double RealTier_getMean_points (RealTier me, double tmin, double tmax) {
	long n = my points.size, imin, imax;
	double sum = 0.0;
	if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; }   // autowindow
	n = AnyTier_getWindowPoints (me->asAnyTier(), tmin, tmax, & imin, & imax);
	if (n == 0) return NUMundefined;
	for (long i = imin; i <= imax; i ++)
		sum += my points.at [i] -> value;
	return sum / n;
}
Beispiel #6
0
double RealTier_getStandardDeviation_points (RealTier me, double tmin, double tmax) {
	long n = my points.size, imin, imax;
	double mean, sum = 0.0;
	if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; }   // autowindow
	n = AnyTier_getWindowPoints (me->asAnyTier(), tmin, tmax, & imin, & imax);
	if (n < 2) return NUMundefined;
	mean = RealTier_getMean_points (me, tmin, tmax);
	for (long i = imin; i <= imax; i ++) {
		double diff = my points.at [i] -> value - mean;
		sum += diff * diff;
	}
	return sqrt (sum / (n - 1));
}
Beispiel #7
0
double RealTier_getArea (RealTier me, double tmin, double tmax) {
	long n = my points.size, imin, imax;
	//RealPoint *points = & my points [0];
	if (n == 0) return NUMundefined;
	if (n == 1) return (tmax - tmin) * my points.at [1] -> value;
	imin = AnyTier_timeToLowIndex (me->asAnyTier(), tmin);
	if (imin == n) return (tmax - tmin) * my points.at [n] -> value;
	imax = AnyTier_timeToHighIndex (me->asAnyTier(), tmax);
	if (imax == 1) return (tmax - tmin) * my points.at [1] -> value;
	Melder_assert (imin < n);
	Melder_assert (imax > 1);
	/*
	 * Sum the areas between the points.
	 * This works even if imin is 0 (offleft) and/or imax is n + 1 (offright).
	 */
	double area = 0.0;
	for (long i = imin; i < imax; i ++) {
		double tleft, fleft, tright, fright;
		if (i == imin) {
			tleft = tmin;
			fleft = RealTier_getValueAtTime (me, tmin);
		} else {
			tleft = my points.at [i] -> number;
			fleft = my points.at [i] -> value;
		}
		if (i + 1 == imax) {
			tright = tmax;
			fright = RealTier_getValueAtTime (me, tmax);
		} else {
			tright = my points.at [i + 1] -> number;
			fright = my points.at [i + 1] -> value;
		}
		area += 0.5 * (fleft + fright) * (tright - tleft);
	}
	return area;
}
Beispiel #8
0
double RealTier_getValueAtTime (RealTier me, double t) {
	long n = my points.size;
	if (n == 0) return NUMundefined;
	RealPoint pointRight = my points.at [1];
	if (t <= pointRight -> number) return pointRight -> value;   // constant extrapolation
	RealPoint pointLeft = my points.at [n];
	if (t >= pointLeft -> number) return pointLeft -> value;   // constant extrapolation
	Melder_assert (n >= 2);
	long ileft = AnyTier_timeToLowIndex (me->asAnyTier(), t), iright = ileft + 1;
	Melder_assert (ileft >= 1 && iright <= n);
	pointLeft = my points.at [ileft];
	pointRight = my points.at [iright];
	double tleft = pointLeft -> number, fleft = pointLeft -> value;
	double tright = pointRight -> number, fright = pointRight -> value;
	return t == tright ? fright   // be very accurate
		: tleft == tright ? 0.5 * (fleft + fright)   // unusual, but possible; no preference
		: fleft + (t - tleft) * (fright - fleft) / (tright - tleft);   // linear interpolation
}