Lab 5, Ioan Dragomir
Process Modeling, prof. Daniel Moga, Technical University of Cluj-Napoca
Piecewise linear approximations of measured functions.
Contents
Intro
Census example
load census; x = cdate; y = pop; plot(x, y, '*');
f = fit(x, y, 'poly1') p = coeffvalues(f) a = p(1) b = p(2) y_approx = a * x + b; hold on; plot(x, y_approx, 'r');
f = Linear model Poly1: f(x) = p1*x + p2 Coefficients (with 95% confidence bounds): p1 = 1.216 (1.045, 1.387) p2 = -2212 (-2535, -1889) p = 1.0e+03 * 0.0012 -2.2120 a = 1.2157 b = -2.2120e+03
f = fit(x, y, 'poly2'); p = coeffvalues(f); a = p(1); b = p(2); c = p(3); y_approx_2 = a * x.^2 + b * x + c; plot(x, y_approx_2, 'g');
LED
IV characteristic for an ideal LED is a sudden jump to \infty after the threshold voltage.
Measuring a real LED, we get values like these:
I_measured = [0, 0, 0, 0, 0.0002, 0, 0.0002, 0, 0.0002, 0.0002, 0.0001, ... 0.0006, 0.00189, 0.00389, 0.00598, 0.00807, 0.01027, 0.01445, ... 0.01664, 0.01874, 0.02083, 0.02302, 0.02512, 0.02950]'; V_measured = [0, 0.36091, 0.71343, 1.07434, 1.25060, 1.43525, 1.61151, ... 1.79616, 1.97242, 2.33333, 2.50959, 2.68585, 2.87050, 2.98801, ... 3.08034, 3.12230, 3.16427, 3.23981, 3.27338, 3.31535, 3.34053, ... 3.35731, 3.38249, 3.43285]'; clf; plot(V_measured, I_measured, '+');
Which we may try to fit with a single linear function:
f = fit(V_measured, I_measured, 'poly1'); p = coeffvalues(f); a1 = p(1); b1 = p(2); I_predicted1 = a1 * V_measured + b1; clf; hold on; plot(V_measured, I_measured, '+'); plot(V_measured, I_predicted1, 'r');
But this is very clearly a rather disappointing model.
Piecewise linear model
We may then attempt to model the IV curve by a set of linear pieces. The exercise mentions using 5 intervals, but not which data points each one covers, so we must decide that ourselves. After some attempts, the cleanest division I came across is:
num_intervals = 5; points_per_interval = [11, 3, 3, 6, 5];
Which can then be converted to a list of "interval boundaries" with the following code. Reverse engineering not really relevant, it just adds them in a slightly special way to allow for a one point overlap
assert(length(points_per_interval) == num_intervals);
assert(sum(points_per_interval) - num_intervals + 1 == length(V_measured));
indices = [0 cumsum(points_per_interval)] + 1 - (0:5); %Voodoo magic
I_predicted2 = zeros([1, length(V_measured)]); for i = 1 : 5 i0 = indices(i); i1 = indices(i+1); V0 = V_measured(i0); V1 = V_measured(i1); f = fit(V_measured(i0:i1), I_measured(i0:i1), 'poly1'); p = coeffvalues(f); a = p(1); b = p(2); I_predicted2(2*i-1) = a * V0 + b; I_predicted2(2*i) = a * V1 + b; plot([V0, V1], I_predicted2(2*i-1:2*i), 'g-'); end x0, x1 = xlim; y0, y1 = ylim; for x = indices plot([x, x], [y0, y1], 'k--'); end xlim([x0, x1]); ylim([y0, y1]);
Unrecognized function or variable 'x0'. Error in lab5 (line 128) x0, x1 = xlim;