0% found this document useful (0 votes)
6 views

Unit 3 Pre-Lab Assignment 3

The document discusses data fitting techniques in physics, focusing on how to fit a line to noisy data and analyze exponential charging in RC circuits. It provides code examples for generating data, fitting functions, and plotting theoretical and noisy curves. Additionally, it includes assignments for the reader to practice fitting functions to data from RC circuits with different resistor and capacitor combinations.

Uploaded by

colinddchu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Unit 3 Pre-Lab Assignment 3

The document discusses data fitting techniques in physics, focusing on how to fit a line to noisy data and analyze exponential charging in RC circuits. It provides code examples for generating data, fitting functions, and plotting theoretical and noisy curves. Additionally, it includes assignments for the reader to practice fitting functions to data from RC circuits with different resistor and capacitor combinations.

Uploaded by

colinddchu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Fitting

developed by Pauline Arriaga

When we interpret any kind of data, our scientific result may be a number that comes from
the average of the data points, or it can be some kind of correlation. There are some kinds of
correlations in physics we expect. For example, if we are dropping an object from a certain
height, we know that the position will be

$x = \frac{1}{2} gt^2$

Therefore, if we measure positions and measure times and plot them, we should see a
parabola. However, if we have some systematic errors, meaning some effect of our system
that will affect all measurements, we won't get a perfect parabola. We therefore need to fit
our data.

In [9]: import numpy as np


import random
import matplotlib.pyplot as plt

Below I'm going to use some functions that will create arrays x_data and y_data which hold
some linear data.

In [10]: ### Generate a line with random noise

# Generate x and y array for a line


x_data = np.arange(100, dtype = float)
y_data = np.arange(100, dtype = float) * 3. + 30.

# Generate random noise


noise = [random.randint(-50,50) for i in range(100)]
y_data += noise

# Show data
plt.scatter(x_data, y_data)

Out[10]: <matplotlib.collections.PathCollection at 0x7f90f444f350>


In order to fit a function, we first need two different functions. One of them will be the
function we're trying to fit. Let's try and fit a line to the data points above. We then create a
function line() which takes an x coordinate and some parameters as the inputs. We pass in
the parameters as an array with the first element being the slope of the line and the second
being the y offset. We can have the parameters in any order. Note that below, we have used
a doc sting (the text within the quotation marks) in order to tell the reader what the
parameters should be.

The second function will get the residuals of the function. This function can just be a formula
for any fitting as it will be the same for any fitting function where we don't have error bars.
The get residuals will go point by point on the data points and will find the distance between
each data point and the fitted line. The best fit will have the smallest residuals.

In [11]: def line(x, parameters):


'''
Plots a line

Inputs:
x: a coordinate
parameters: [slope of the line, y offset of the line]
'''
m = parameters[0]
b = parameters[1]
y = m * x + b
return y

def get_residuals_line(parameters, data, x):


residuals = np.abs(data - line(x, parameters))
return -residuals

We now use the least squares which will maximize the function get residuals, finding the
best fit. Note where x and y data are input

In [12]: from scipy.optimize import least_squares


guess_parameters = [1., 1.]
res_lsq = least_squares(get_residuals_line, guess_parameters, args = (y_data, x_dat

We now extract the best parameters from the results

In [13]: parameters = res_lsq['x']


print(parameters)

[ 2.95787579 29.64514846]

Let's check to see how good our fit is

In [14]: x_axis = np.arange(110.)


fitted_line = line(x_axis, parameters)
plt.plot(x_axis, fitted_line, color = 'green', label = 'Fitted line')

plt.scatter(x_data, y_data, label = 'Data')

plt.legend()

Out[14]: <matplotlib.legend.Legend at 0x7f90ea6ae490>


Assignment
Simiarly to the previous tutorial, you will create a function, but one that discribes the
exponential charging of an RC circuit.

$v = v_0(1-exp(-t/\tau))$

where tau is the RC time constant and v0 is the maximum voltage the circuit will acheive. Use
the RC values descirbed in the slides and v0 = 1 V.

In [15]: # Create the exponential curve

def rc_exponential(t, parameters):


v0, tau = parameters
v = v0 * (1 - np.exp(-t / tau))
return v

def get_residuals_rc(parameters, data, t):


residuals = np.abs(data - rc_exponential(t, parameters))
return -residuals

In [24]: # Create a time array that is 5 times the length of the time constant
time_constant = 10e-3
time = np.linspace(0, 5 * time_constant, 500)

# Call the rc_exponential function and obtain the voltage values


v0 = 1 # Initial voltage
voltage_values = rc_exponential(time, [v0, time_constant])

# Plot your theoretical function


plt.figure
plt.plot(time, voltage_values, label='Theoretical RC Curve', color='blue')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title('Theoretical RC Exponential Charging Curve')
plt.legend()
plt.show()
Now that you know how to plot a single RC curve, plot the following combinations:

Plot 1: 10 uF Capacitor with 100 Ohm Resistor and 10 uF Capacitor with 1k Ohm Resistor

Plot 2: 1k Ohm Resistor with 10 uF Capacitor and 1k Ohm Resistor with 100 uF Capacitor

To make your graphs look nice and even, choose you time vector to be as a function of the
greatest tau value.

In [25]: # Plot 1: 10 uF Capacitor with 100 Ohm Resistor and 10 uF Capacitor with 1k Ohm Res
# Define parameters for Plot 1
v0 = 1 # Initial voltage in volts

# Time constants for each combination


C1, R1 = 10e-6, 100 # 10 µF, 100 Ω
tau1 = C1 * R1 # Time constant for the first combination

C2, R2 = 10e-6, 1000 # 10 µF, 1 kΩ


tau2 = C2 * R2 # Time constant for the second combination

# Create a time array based on the greatest tau value (5 * max_tau)


max_tau = max(tau1, tau2)
time = np.linspace(0, 5 * max_tau, 500)

# Calculate voltage values for each combination


voltage1 = rc_exponential(time, [v0, tau1])
voltage2 = rc_exponential(time, [v0, tau2])
# Plot the RC curves
plt.figure
plt.plot(time, voltage1, label=f'C=10 µF, R=100 Ω, τ={tau1:.2e} s', color='blue')
plt.plot(time, voltage2, label=f'C=10 µF, R=1 kΩ, τ={tau2:.2e} s', color='orange')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title("Plot 1: 10 µF Capacitor with 100 Ω and 1 kΩ Resistors")
plt.legend()
plt.show()

In [22]: # Define parameters for Plot 2


v0 = 1 # Initial voltage in volts

# Time constants for each combination


C1, R1 = 10e-6, 1000 # 10 µF, 1 kΩ
tau1 = C1 * R1 # Time constant for the first combination

C2, R2 = 100e-6, 1000 # 100 µF, 1 kΩ


tau2 = C2 * R2 # Time constant for the second combination

# Create a time array based on the greatest tau value (5 * max_tau)


max_tau = max(tau1, tau2)
time = np.linspace(0, 5 * max_tau, 500)

# Calculate voltage values for each combination


voltage1 = rc_exponential(time, [v0, tau1])
voltage2 = rc_exponential(time, [v0, tau2])
# Plot the RC curves
plt.figure(figsize=(10, 6))
plt.plot(time, voltage1, label=f'C=10 µF, R=1 kΩ, τ={tau1:.2e} s', color='blue')
plt.plot(time, voltage2, label=f'C=100 µF, R=1 kΩ, τ={tau2:.2e} s', color='orange')
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title("Plot 2: 1 kΩ Resistor with 10 µF and 100 µF Capacitors")
plt.legend()
plt.show()

Take your RC charge plot you created in the previous python notebook and add 5-10% noise
to it. After adding noise to your theoretical plot, create

In [26]: import numpy as np


import matplotlib.pyplot as plt
import random

# Define the RC exponential function


def rc_exponential(t, parameters):
'''
Plots an RC exponential charging curve.

Inputs:
t: time
parameters: [initial voltage, time constant]
'''
v0, tau = parameters
return v0 * (1 - np.exp(-t / tau))

# Parameters for the RC curve


v0 = 1 # Initial voltage
R = 1000 # Resistance in Ohms
C = 10e-6 # Capacitance in Farads
tau = R * C # Time constant

# Create the time array


time = np.linspace(0, 5 * tau, 500)

# Calculate the theoretical voltage values


theoretical_voltage = rc_exponential(time, [v0, tau])

# Generate random noise (similar to the provided example)


random_noise = [random.randint(-10, 10) * 0.01 for _ in range(len(theoretical_volta
noisy_voltage = theoretical_voltage + random_noise

# Plot the theoretical and noisy data


plt.figure
plt.plot(time, theoretical_voltage, label='Theoretical Curve', color='blue', linewi
plt.scatter(time, noisy_voltage, label='Noisy Data', color='orange', s=10, alpha=0.
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title('Theoretical and Noisy RC Curve')
plt.legend()
plt.show()

Lastly, take your noisy data and fit a the theoretical function back to it.

Plot all 3: Theoretical, Noisy, and Fit.


Did the input plot paramters change?

In [27]: # Perform least squares fit


guess_parameters = [0.9, tau * 0.9] # Initial guesses for [v0, tau]
res_lsq = least_squares(get_residuals_rc, guess_parameters, args=(noisy_voltage, ti
fitted_parameters = res_lsq['x']
print("Fitted Parameters:", fitted_parameters)

# Create a fit curve


fitted_curve = rc_exponential(time, fitted_parameters)

# Plot all 3 plots together and show legend


plt.figure
plt.plot(time, theoretical_voltage, label='Theoretical Curve', color='blue', linewi
plt.scatter(time, noisy_voltage, label='Noisy Data', color='orange', s=10, alpha=0.
plt.plot(time, fitted_curve, label='Fitted Curve', color='green', linestyle='--', l
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.title('Theoretical, Noisy, and Fitted RC Curve')
plt.legend()
plt.show()

Fitted Parameters: [1.00391179 0.01030179]


Developed by P. Arriaga

rev. 2.1 E. Kramer 04-15-2021

rev. 2.2 J. Carmona 10-15-2021

© Regents of the University of California

In [ ]:

You might also like