Difference between revisions of "Homework 0"

From PrattWiki
Jump to navigation Jump to search
(Nonlinear fit)
(Linear fit)
 
(23 intermediate revisions by the same user not shown)
Line 1: Line 1:
This page is a supplement to "Homework 0," an assignment for students in 2nd-year and later 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 either ECE 110 (Fundamentals of ECE) 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).
+
__NUMBEREDHEADINGS__
  
== Assignment ==
+
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 [https://drive.google.com/drive/folders/1FbVRzjof2huV7WrkRD6kSJljBbd-eRPo?usp=sharing Google Drive folder], which includes the files individually and a zip file that has them collectively.
  
=== Introduction ===
+
== Background ==  
The problems for this assignment focus on computational tools from EGR 103 you will need to solve some problems in this class. You will not be turning it in for a gradeYou can use either MATLAB or Python (or both!).  The solution will be posted on the Sakai site. If you have never used Python or MATLAB (or even if you have), there will be guidance on Pratt Pundit for how to do these problems.
+
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 ofGiven 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.  
=== Problems ===
 
  
==== Linear fit ====
+
== Problems ==
Most of the elements you will be learning about in this class have some kind of linear relationship between the voltage across the element and the current through it.  You can get files for ten experimental runs where a particular voltage was applied to an element and the current through it was measured - they are on [https://duke.box.com/v/Homework0Files Box] and are named '''fileNN.dat''Write code that automates the process of  
+
=== 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 rowAssuming 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,  
 
* Loading data from a file,  
* Determining the line of best fit for the current as a function of the voltage, and  
+
* 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 <code>slope</code> and <code>intercept</code>, respectively.
 
* Storing the slope and intercept of the fit into arrays called <code>slope</code> and <code>intercept</code>, respectively.
Once all data files are finished, print a table with results of all 10 runs to the screen using scientific notation 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. 
 
* References: [[Python:Fitting]] and specifically [[Python:Fitting#Polynomial_Fitting]], [[Python:Loading and Saving Data]], and [[Python:Flexible Programming]]
 
  
====Nonlinear fit====
+
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. 
Some of the elements you will be learning about have a nonlinear relationship between the voltage across the element and the current through it.  You can get a file with voltages across a circuit with a resistor and an LED in series - it is on [https://duke.box.com/v/Homework0Files Box] and is named '''LED_01_GREEN.mat'''. The file has three columns. The first is total voltage across the resistor and LED; you won't need 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:
+
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== References====
 +
<div class="mw-collapsible-content">
 +
* [[Python:Iterative Structures]] - loops in Python
 +
* [[Python:Flexible Programming]] - a couple ways to look for files in a folder and load them
 +
* [[Python:Fitting]] - how to do curve fits in Python; for this problem, you only need [[Python:Fitting#Polynomial_Fitting]]
 +
* [https://peps.python.org/pep-3101/#format-strings https://peps.python.org/pep-3101/#format-strings] and [https://peps.python.org/pep-3101/#standard-format-specifiers https://peps.python.org/pep-3101/#standard-format-specifiers] for formatting strings
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Answers ====
 +
<div class="mw-collapsible-content">
 +
Your code should end up displaying the following:
 +
<syntaxhighlight lang=text>
 +
    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
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
<iframe src="https://trinket.io/embed/python3/e86d4c5d86?start=result" width="100%" height="370" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>
 +
</html>
 +
===== MATLAB =====
 +
<syntaxhighlight lang=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
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
=== 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 nonlinearThere 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.
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== References====
 +
<div class="mw-collapsible-content">
 +
* [[Python:Loading and Saving Data]] and especially [[Python:Loading_and_Saving_Data#MATLAB_.mat_Files]]
 +
* [[Python:Fitting]] and especially [[Python:Fitting#Nonlinear_Regression]]
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Answers ====
 +
<div class="mw-collapsible-content">
 
<center><math>
 
<center><math>
 
\begin{align*}
 
\begin{align*}
i&=Ae^{Bv}+C
+
A&\approx1e-18 & B&\approx18 & C&\approx7.5e-6
 
\end{align*}
 
\end{align*}
 
</math></center>
 
</math></center>
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.
+
<gallery>
* References: [[Python:Fitting]] and specifically [[Python:Fitting#Nonlinear_Regression]], [[Python:Loading and Saving Data]] and specifically [[Python:Loading_and_Saving_Data#MATLAB_.mat_Files]], and [[Python:Plotting]]
+
File:HW0_Nonlin_python.png|Python Version
 +
File:HW0_Nonlin_matlab.png|MATLAB Version
 +
</gallery>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
<iframe src="https://trinket.io/embed/python3/40335b0944" width="100%" height="370" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>
 +
</html>
 +
===== MATLAB =====
 +
<syntaxhighlight lang=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
 +
</syntaxhighlight>
 +
</div>
 +
 
  
==== Linear Algebra ====
+
=== 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_1$$, $$v_2$$, and $$v_3$$ assuming known values of:
+
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:
 
<center><math>
 
<center><math>
 
\begin{align*}
 
\begin{align*}
v_s&=10{\mbox V}& R_k&=1000~\Omega
+
v_s&=10~{\mbox V}& R_k&=1000~\Omega
 
\end{align*}
 
\end{align*}
 
</math></center>
 
</math></center>
Line 40: Line 157:
 
\end{align*}
 
\end{align*}
 
</math></center>
 
</math></center>
* References: [[Python:Linear Algebra]]
 
  
==== Linear Algebra Sweep ====
+
<div class="mw-collapsible mw-collapsed" style="width:100%">
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:
+
==== References/Hints ====
 +
<div class="mw-collapsible-content">
 +
* [[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:<center><math>
 +
\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*}
 +
</math></center>
 +
* Once you have done that, and assuming that all the $$R_k$$ values are the same ($$R$$), you should get:<center><math>
 +
\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*}
 +
</math></center>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Answers ====
 +
<div class="mw-collapsible-content">
 +
<center><math>
 +
\begin{align*}
 +
v_a&=6.25 & v_b&=5.0 & v_c&=3.75
 +
\end{align*}
 +
</math></center>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
<iframe src="https://trinket.io/embed/python3/e04ff45635" width="100%" height="370" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>
 +
 
 +
</html>
 +
 
 +
===== MATLAB =====
 +
<syntaxhighlight lang=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)</syntaxhighlight>
 +
</div>
 +
 
 +
=== 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:
 
<center><math>
 
<center><math>
 
\begin{align*}
 
\begin{align*}
Line 52: Line 231:
  
 
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.
 
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.
* References: [[Python:Linear Algebra]] and specifically [[Python:Linear_Algebra#Sweeping_a_Parameter]] and [[Python:Plotting]]
 
  
==== ODE ====
+
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== References====
 +
<div class="mw-collapsible-content">
 +
* [[Python:Linear Algebra]] and specifically [[Python:Linear_Algebra#Sweeping_a_Parameter]]
 +
* [[Python:Plotting]]
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Answers ====
 +
<div class="mw-collapsible-content">
 +
<gallery>
 +
File:HW0_IvsRpyplot.png|Python Version
 +
File:HW0_IvsRmatplot.png|MATLAB Version
 +
</gallery>
 +
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
<iframe src="https://trinket.io/embed/python3/b1d76c2f26" width="100%" height="370" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>
 +
</html>
 +
 
 +
===== MATLAB =====
 +
<syntaxhighlight lang=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
 +
</syntaxhighlight>
 +
</div>
 +
 
 +
=== 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!   
 
'''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!   
  
Line 69: Line 298:
 
* $$y(0)=4$$, $$(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 <code>Case N</code> where <code>N</code> is the case number.
 
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 <code>Case N</code> where <code>N</code> is the case number.
* References: [[Python:Ordinary Differential Equations]] and [[Python:Plotting]]
 
  
=== Numerical / Graphical Solutions ===
+
<div class="mw-collapsible mw-collapsed" style="width:100%">
The codes to solve these problems will beon Sakai; for now, here are the outputs from the programs:
+
==== References====
 +
<div class="mw-collapsible-content">
 +
* [[Python:Ordinary Differential Equations]]
 +
* [[Python:Plotting]]
 +
</div>
  
==== Linear fit ====
+
<div class="mw-collapsible mw-collapsed" style="width:100%">
<syntaxhighlight lang="bash">
+
==== Answers ====
    Slope  Intercept
+
<div class="mw-collapsible-content">
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
 
</syntaxhighlight>
 
 
 
==== Nonlinear fit ====
 
<center><math>
 
\begin{align*}
 
A&\approx1e-18 & B&\approx18 & C&\approx7.5e-6
 
\end{align*}
 
</math></center>
 
<gallery>
 
File:HW0_Nonlin_python.png|Python Version
 
File:HW0_Nonlin_matlab.png|MATLAB Version
 
</gallery>
 
 
 
==== Linear Algebra ====
 
<center><math>
 
\begin{align*}
 
v_a&=6.25 & v_b&=5.0 & v_c&=3.75
 
\end{align*}
 
</math></center>
 
 
 
==== Linear Algebra Sweep ====
 
<gallery>
 
File:HW0_IvsRpyplot.png|Python Version
 
File:HW0_IvsRmatplot.png|MATLAB Version
 
</gallery>
 
 
 
==== ODE ====
 
 
<gallery>
 
<gallery>
 
File:HW0_Case1pyplot.png|Case 1 Python
 
File:HW0_Case1pyplot.png|Case 1 Python
Line 124: Line 319:
 
File:HW0_Case4matplot.png|Case 4 MATLAB
 
File:HW0_Case4matplot.png|Case 4 MATLAB
 
</gallery>
 
</gallery>
 +
</div>
 +
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
 +
<iframe src="https://trinket.io/embed/python3/dae1c39594" width="100%" height="370" frameborder="0" marginwidth="0" marginheight="0" allowfullscreen></iframe>
 +
</html>
 +
 +
===== MATLAB =====
 +
<syntaxhighlight lang=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
 +
</syntaxhighlight>
 +
</div>
 +
 +
<!--
 +
=== Problem ===
 +
 +
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== References====
 +
<div class="mw-collapsible-content">
 +
*
 +
 +
</div>
 +
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Answers ====
 +
<div class="mw-collapsible-content">
 +
 +
 +
</div>
 +
 +
<div class="mw-collapsible mw-collapsed" style="width:100%">
 +
==== Solutions ====
 +
<div class="mw-collapsible-content">
 +
===== Python =====
 +
<html>
 +
 +
 +
</html>
 +
===== MATLAB =====
 +
<syntaxhighlight lang=matlab>
 +
 +
</syntaxhighlight>
 +
</div>
 +
-->

Latest revision as of 03:41, 12 January 2024


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