Linear regression using scipy.ODR gives 0 error on all paramaters

1 day ago 3
ARTICLE AD BOX

I was trying to use scipy ODR to fit a linear graph as that would take into account both my xerror and yerror for each value. It does infact get me paramaters out but I just end up with it saying that I have absolutley NO error whatsoever. The output from my code is as below:

Beta: [0.00046253 0.00025365] Beta Std Error: [0. 0.] Beta Covariance: [[0. 0.] [0. 0.]] Residual Variance: 0.0 Inverse Condition #: 0.0 Reason(s) for Halting: Problem is not full rank at solution Sum of squares convergence fitted values of Gradient and Intercept: [0.00046253 0.00025365] error on Gradient and Intercept: [0. 0.]

The ODR related section of my code is below.

Note that the NC suffix is just for "No Core" (Lab investigating faradays law, efficiencies with different cores of primary and secondary coils, not really relevant but its the context of my code) as I was going to copy paste the same code but change the suffix and the directory its iterating over (I know this sounds convoluted but I am already iterating over files in a directory and if I'm being honest its too close to my lab report being due to for me to do it a nicer way)

# This one is for the ODR method because uhm i cant do weights with both the xerror and yerror def fit_function_linear(m_and_c_vector, x): #cuz y = mx + c m = m_and_c_vector[0] c = m_and_c_vector[1] output = m*x + c return output ... (other code) linear_model_NC = odr.Model(fit_function_linear) Data_For_This_NC = odr.RealData(x_values_NC, Isecondary_NC, sx=x_err_NC, sy=err_Isecondary_NC) odrThingyThatIDontReallyUnderstand_NC = odr.ODR(Data_For_This_NC, linear_model_NC, beta0=[(Temp_Isecondary_value/Temp_x_value), (Temp_Isecondary_value - (Temp_Isecondary_value/Temp_x_value))]) output_Thing_For_Fit_NC = odrThingyThatIDontReallyUnderstand_NC.run() output_Thing_For_Fit_NC.pprint() print("") print(f"fitted values of Gradient and Intercept: {output_Thing_For_Fit_NC.beta}") print("") print(f"error on Gradient and Intercept: {output_Thing_For_Fit_NC.sd_beta}")

If it helps, im just going to attach my whole programme:

#might also want to do the calculation method of V_p = V_supply * R_p / (R+R_p), probably should do this for the lab report import numpy as np import matplotlib.pyplot as plt import pandas as pd from scipy.optimize import curve_fit import os import scipy.odr from scipy import odr def calcurr_and_error(Voltage, Resistance, err_Voltage, err_Resistance): Current = Voltage/Resistance err_Current = Current*((err_Voltage/Voltage)**2 + (err_Resistance/Resistance)**2)**0.5 return Current, err_Current def Error_Vr18_multimeter(Voltage): power_of_10_of_rightmost_digit = -3 err_Vr18 = Voltage*(0.01) + 4*10**power_of_10_of_rightmost_digit # we can do this as in ALL of the readings the power of 10 is -3. thank FUCK return err_Vr18 def calculate_error_on_x_value_AND_calculate_x_value(Vp, Ip, Vs, err_Vp, err_Ip, err_Vs): #not the right method for calculating uncertainties as its second order. talk about monte carlo simulations and how we dont know how do these yet in 1st year in lab report x = Vp*Ip / Vs err_x = x*((err_Vp/Vp)**2 + (err_Ip/Ip)**2 + (err_Vs/Vs)**2)**0.5 return x, err_x # This one is for the ODR method because uhm i cant do weights with both the xerror and yerror def fit_function_linear(m_and_c_vector, x): #cuz y = mx + c m = m_and_c_vector[0] c = m_and_c_vector[1] output = m*x + c return output r18 = 17.69 #resistances in ohms r27 = 26.39 rprimary = 1.139 rsecondary = 0.416 err_r18 = 0.08845 err_r27 = 0.13195 err_rprimary = 5.695e-3 err_rsecondary = 2.08e-3 # all in ohms Vr18_array = np.loadtxt("Data/Multimeter.csv", skiprows=2, delimiter=",") #--- start of bit to copy paste ------------------------------------------------------------------------ Vsupply_NC = [] err_Vsupply_NC = [] Vprimary_NC = [] err_Vprimary_NC = [] Vsecondary_NC = [] err_Vsecondary_NC = [] Vr18_NC = [] #this one is the multimetre stuff which is stored in a seperate CSV Iprimary_NC = [] err_Iprimary_NC = [] Isecondary_NC = [] err_Isecondary_NC = [] x_values_NC = [] x_err_NC = [] i=0 num_index_of_core = 1 #index of the measurement number in the column for the Vr18, which was measured by the multimetre. ACTUALLY this is irrelevant ignore this line i dont use it #the code for the subsequent core, and i will use this number to just get the right Vr18 values from each thing #Doing this cuz the osilliscope saves the stats in a new CSV every time. Just change the directory and copy paste everything directory = "Data/NC" for dirpath, dirnames, filenames in os.walk(directory): for filename in filenames: if filename.endswith('.csv'): file = np.loadtxt((directory+"/"+filename), skiprows=21, usecols=(2,4,6), max_rows=2, delimiter=",") while i <= 5: Vr18_NC.append(Vr18_array[i, 1]) #idont think i need this Temp_Iprimary_value, Temp_Iprimary_error = calcurr_and_error(Vr18_array[i, 1], r18, Error_Vr18_multimeter(Vr18_array[i, 1]), err_r18) Iprimary_NC.append(Temp_Iprimary_value) err_Iprimary_NC.append(Temp_Iprimary_error) Temp_x_value, Temp_x_error = calculate_error_on_x_value_AND_calculate_x_value(file[0,1], Temp_Iprimary_value, file[0,2], file[1,1], Temp_Iprimary_error, file[1,2]) x_values_NC.append(Temp_x_value) x_err_NC.append(Temp_x_error) i=i+1 #print(file) # this is the top right one #print("") #print("") Vsupply_NC.append(file[0,0]) err_Vsupply_NC.append(file[1,0]) Vprimary_NC.append(file[0, 1]) err_Vprimary_NC.append(file[1, 1]) Vsecondary_NC.append(file[0,2]) err_Vsecondary_NC.append(file[1,2]) Temp_Isecondary_value, Temp_Isecondary_error = calcurr_and_error(file[0,2], r27, file[1,2], err_r27) Isecondary_NC.append(Temp_Isecondary_value) err_Isecondary_NC.append(Temp_Isecondary_error) #print(x_values_NC) #print("") #print(Isecondary_NC) linear_model_NC = odr.Model(fit_function_linear) Data_For_This_NC = odr.RealData(x_values_NC, Isecondary_NC, sx=x_err_NC, sy=err_Isecondary_NC) odrThingyThatIDontReallyUnderstand_NC = odr.ODR(Data_For_This_NC, linear_model_NC, beta0=[(Temp_Isecondary_value/Temp_x_value), (Temp_Isecondary_value - (Temp_Isecondary_value/Temp_x_value))]) output_Thing_For_Fit_NC = odrThingyThatIDontReallyUnderstand_NC.run() output_Thing_For_Fit_NC.pprint() print("") print(f"fitted values of Gradient and Intercept: {output_Thing_For_Fit_NC.beta}") print("") print(f"error on Gradient and Intercept: {output_Thing_For_Fit_NC.sd_beta}") #fit_eff_plot, cov_eff_plot = np.polyfit(x_values_NC, ) #actually nevermind polyfit doesnt let me weight for both x and y errors #plt.plot(x_values_NC, Isecondary_NC, "o") #plt.show() #once graph is plotted THEN this would be END of copy paste bit --------------------------------

Also, im just gonna attach my data incase its anything in there. I dunno, maybe the numbers get too small and it just doesnt like it. The CSVs for NC/No Core (and one of the readings for steel) are like that because i forgot to save a CSV and was just taking screenshots of the osilliscope screen, had to make those CSVs manually. Data Google Drive

Read Entire Article