Homework 0

From PrattWiki
Jump to navigation Jump to search


This page is a supplement to "Homework 0," an assignment for students in engineering courses meant as a refresher (or introduction) for computational methods learned in EGR 103 that might prove useful in later classes. The assignment below is specifically written for ECE 110 (Fundamentals of ECE), ECE 280 (Signals and Systems), or EGR 224 (Electrical Fundamentals of Mechatronics) though over time it may evolve to be either more general or to have more specific examples for other classes (such as EGR 201). The files that are needed for these assignments are in a Google Drive folder, which includes the files individually and a zip file that has them collectively.

1 Background

This page comes from an assignment Dr. G would give out to classes that have EGR 103 as a pre-requisite to give an idea of what kinds of computational abilities might come into play over the course of the semester. The assignment was not graded, but students were expected to complete it and ask questions about any topics they were unsure of. Given that, it might as well live on Pundit! Both MATLAB and Python solutions are available, though starting in Fall of 2021 the last of the MATLAB EGR 103 students will have generally graduated and so most people will be using Python. If you did not take EGR 103 or CS 101 (i.e. you have never seen Python), there will be some Pundit pages that should help out.

2 Problems

2.1 Linear fit

Many systems you will be learning about have some kind of linear relationship between an applied field and a measured response. This problem explores that for a circuit and the relationship between the voltage across an element and the current through it. There is a link above to data sets for ten experimental runs where a particular voltage was applied to an element and the current through it was measured. The voltage is in the first column and the current is in the second column - the files do not have a header row. Assuming the voltage is the independent variable and the current is the dependent variable, write code that automates the process of

  • Loading data from a file,
  • Determining the line of best fit for the current as a function of the voltage ($$i=mv+b$$ or $$i=P[0]\,v+P[1]$$), and
  • Storing the slope and intercept of the fit into arrays called slope and intercept, respectively.

Once all data files are processed, print a table with results of all 10 runs to the screen using scientific notation with four significant figures (i.e. three after the decimal point) for all the numbers and making sure the numbers line up under each other. Note that the slopes will generally be positive but the intercepts may be negative so you should account for the sign in your space allocation.

2.1.1 References

2.1.2 Answers

Your code should end up displaying the following:

     Slope  Intercept
 5.787e+00  1.440e-01
 4.640e+00  3.912e-02
 5.934e+00  1.174e-01
 5.234e+00  9.758e-02
 4.898e+00  1.168e-01
 5.923e+00  1.745e-01
 4.179e+00 -9.780e-02
 5.296e+00  8.575e-02
 5.206e+00  1.369e-01
 5.205e+00  4.678e-02

2.1.3 Solutions

2.1.3.1 Python

2.1.3.2 MATLAB
%% Initialize workspace
clear; format short e

%% First line of table
fprintf('%10s %10s\n', 'Slope', 'Intercept')

%% Initialize variables
N = 10;
slope = zeros(N, 1);
intercept = zeros(N, 1);

%% Loop to find, store, and print slope and intercept
for k=1:10
    eval(sprintf('data = load(''file%02.0f.dat'');', k));
    v = data(:, 1);
    i = data(:, 2);
    p = polyfit(v, i, 1);
    slope(k) = p(1);
    intercept(k) = p(2);
    fprintf('%10.3e %10.3e\n', slope(k), intercept(k))
end

2.2 Nonlinear Fit

Some of the elements you will be learning about have nonlinear relationships. In this case, you will once again be looking at the relationship between the voltage across an element and the current through it, but this time,. the element is nonlinear. There will be a link to a file below containing measurements from a circuit with an independent voltage source connected to a 1 k$$\Omega$$ resistor and an LED in series. The file has three columns. The first is total voltage across the resistor and LED; it turns out you won't need to do anything with this one. The second is the voltage over the resistor; you will divide this by 1000 to get the LED current. The third is the voltage across the LED; you will use this as the LED voltage. Given a model of: $$ \begin{align*} i&=Ae^{Bv}+C \end{align*} $$ use nonlinear regression to determine values for $$A$$, $$B$$, and $$C$$. Good initial values for the three coefficients are 1e-15, 20, and 0, respectively. Make sure the values are displayed onscreen. Once you have calculated the values, make a plot of the current through the LED as a function of the voltage across the LED that has a curve for the original data as a solid black line and the model as a dashed green line. Label the axes, include a legend, and turn on the grid.

2.2.1 References

2.2.2 Answers

\( \begin{align*} A&\approx1e-18 & B&\approx18 & C&\approx7.5e-6 \end{align*} \)

2.2.3 Solutions

2.2.3.1 Python

2.2.3.2 MATLAB
%% Initialize the workspace
clear; format short e

%% Get data from mat file
load('LED_01_GREEN.mat')
total_v = Voltages(:, 1); res_v = Voltages(:, 2); led_v = Voltages(:, 3);
led_i = res_v/1000;

%% Define nonlinear model
yfun = @(x, coefs) coefs(1) * exp(coefs(2)*x) + coefs(3);

%% Determine and display coefficients
fSSR = @(x, y, coefs) sum(( y - yfun(x, coefs) ).^2);
MyCoefs = fminsearch(@(cd) fSSR(led_v, led_i, cd), [1e-18, 20, 0])
% Can use lsqcurvefit; it doesn't seem to try as hard, though
[MyCoefs2, res] = lsqcurvefit(@(cd, x) yfun(x, cd),[1e-18, 20, 0], led_v, led_i)

%% Make graph
figure(1); clf
plot(led_v, led_i, 'k-', led_v, yfun(led_v, MyCoefs), 'g--')
xlabel('Voltage, V'), ylabel('Current, A'), grid on
legend('data', 'model', 'location', 'best')
print -dpng nonlin_matlab


2.3 Linear Algebra

While there are several methods for coming up with systems of equations for a circuit, with purely resistive circuits these methods generally lead to a system of linear algebra equations to solve. Write code to numerically solve for the unknown values $$v_a$$, $$v_b$$, and $$v_c$$ assuming known values of:

\( \begin{align*} v_s&=10~{\mbox V}& R_k&=1000~\Omega \end{align*} \)

for all $$k=1..7$$ and given the following equations:

\( \begin{align*} \frac{v_a-v_s}{R_1}+\frac{v_a-v_b}{R_3}+\frac{v_a-v_c}{R_2}&=0\\ \frac{v_b-v_s}{R_4}+\frac{v_b-v_a}{R_3}+\frac{v_b-v_c}{R_5}+\frac{v_b}{R_6}&=0\\ \frac{v_c-v_a}{R_2}+\frac{v_c-v_b}{R_5}+\frac{v_c}{R_7}&=0\\ \end{align*} \)

2.3.1 References/Hints

  • Python:Linear Algebra
  • You will first need to re-write the expressions in the form $$Ax=b$$ where $$A$$ will be the coefficients on the variables, $$x$$ will be a column of the variables, and $$b$$ will be any constants not attached to variables. For example the first equation can be written as:
    \( \begin{align*} \left(\frac{1}{R_1}+\frac{1}{R_3}+\frac{1}{R_2}\right)v_a+ \left(-\frac{1}{R_3}\right)v_b+ \left(-\frac{1}{R_2}\right)v_c&=\frac{v_s}{R_1} \end{align*} \)
  • Once you have done that, and assuming that all the $$R_k$$ values are the same ($$R$$), you should get:
    \( \begin{align*} A&=\begin{bmatrix} \frac{3}{R} & -\frac{1}{R} & -\frac{1}{R} \\ -\frac{1}{R} & \frac{4}{R} & -\frac{1}{R} \\ -\frac{1}{R} & -\frac{1}{R} & \frac{3}{R} \\ \end{bmatrix} & b&=\begin{bmatrix} \frac{v_s}{R} \\ \frac{v_s}{R} \\ 0 \end{bmatrix} \end{align*} \)

2.3.2 Answers

\( \begin{align*} v_a&=6.25 & v_b&=5.0 & v_c&=3.75 \end{align*} \)

2.3.3 Solutions

2.3.3.1 Python

2.3.3.2 MATLAB
%% Initialize workspace
clear; format short e

%% Set up equations
vs = 10;
R = 1000;

A = [3/R, -1/R, -1/R; ...
    -1/R,  4/R, -1/R; ...
    -1/R, -1/R,  3/R];
b = [vs/R; vs/R; 0];

%% Solve and print
voltages = A\b;
disp(voltages)

2.4 Linear Algebra Sweep

Once you have symbolically solved for a system of equations, you may want to see what impact changing one or more of the values will have on the results. Given the following system of equations, assume that you want to know how the values of $$i_1$$ and $$i_2$$ change as $$R_4$$ changes:

\( \begin{align*} -10+1000i_1+3000(i_1-i_2)&=0\\ 3000(i_2-i_1)+750i_2+R_4i_2&=0 \end{align*} \)

Write code that will solve $$i_1$$ and $$i_2$$ as a function of $$R_4$$ for 2000 linearly spaced values of $$R_4$$ between 0 and 5000. Make a figure with two subplots - the top one should be a graph of $$i_1$$ as a function of $$R_4$$ and the bottom one should be a graph of $$i_2$$ as a function of $$R_4$$. You do not need to label or title these plots nor do you need legends or grids.

2.4.1 References

2.4.2 Answers

2.4.3 Solutions

2.4.3.1 Python

2.4.3.2 MATLAB
%% Initialize workspace
clear; format short e


%% Set up equations
R4 = linspace(0, 5000, 2000);
i1 = 0*R4;
i2 = 0*R4;
for k=1:2000
    A = [4000, -3000; -3000, 3750+R4(k)];
    b = [10; 0];
    currents = A\b;
    i1(k)=currents(1);
    i2(k)=currents(2);
end
    
%% Make plots
figure(1); clf
subplot(2, 1, 1), plot(R4, i1, 'k-')
subplot(2, 1, 2), plot(R4, i2, 'k-')

print -dpng ivsRmatplot

2.5 ODE

Note: Some offerings of EGR 103 did not cover setting up and solving differential equations. Please take a look at the Pundit page Python:Ordinary Differential Equations for it!

Once we start working with reactive elements (capacitors and inductors), the models will move from linear algebra to differential equations. Write code to calculate the values of $$y$$ for 1000 times between 0 and 10 for the following differential equation:

\( \begin{align*} 2\frac{dy(t)}{dt}+y(t)=f(t) \end{align*} \)

with the following initial conditions and forcing functions:

  • $$y(0)=0$$, $$f(t)=1$$
  • $$y(0)=4$$, $$f(t)=1$$
  • $$y(0)=0$$, $$f(t)=\sin(6t)$$
  • $$y(0)=4$$, $$(t)=\sin(6t)$$

For each of the four cases, your code should make a new figure that graphs $$f(t)$$ as a solid blue line and $$y(t)$$ as a solid red line. Each graph should have a legend and a title that looks like Case N where N is the case number.

2.5.1 References

2.5.2 Answers

2.5.3 Solutions

2.5.3.1 Python

2.5.3.2 MATLAB
%% Initialize workspace
clear; format short e

%% 
t = linspace(0, 10, 1000);
for k=1:4
    if k==1 | k==3
        y0 = 0;
    else
        y0 = 4;
    end
    if k<=2
        f = @(t) 1*t.^0;
    else
        f = @(t) sin(6*t);
    end
    [tout, yout] = ode45(@(t, y) (f(t)-y(1))/2, t, y0);
    figure(k); clf
    plot(t, f(t), 'k-', t, yout, 'r-')
    title(sprintf('Case %d', k))
    eval(sprintf('print -dpng case%dmatplot', k))
end