Repository: wright-group/WrightTools

Issue:
pcov TypeError in kit._leastsq
In kit._leastsq, if the line 62 if statement is not passed, the consequent else statement makes pcov data type float, triggering"TypeError: 'int' object is not subscriptable" in line 72-73:

72:      try:
73:                error.append(np.absolute(pcov[i][i]) ** 0.5)

Line 74 picks up index out of bound errors, not sure if it was meant to catch the type error.

74:      except IndexError:
75:                 error.append(0.00)

Error is bypassed if I put a 2D array into line 68, but have not spent the time considering what this array should look like.


Discussion:
Yes, so IndexError is thrown when you try to subscript a numpy array or scalar, but not a python float.

`np.inf`is a raw python float, however `np.array(np.inf)` is a numpy scalar, which will raise IndexError here.

So, it really doesn't matter what array you put in there (it doesn't even need to be 2D), just can't be a python float.

Or we can except both IndexError and TypeError

see #753 
Whatever we allow pcov to be set to is eventually used to calculate error in the variables of the fit. My current knowledge is that pcov is set to np.inf  if scipy.optimize sets cov_x to be none type. I think that only occurs if the optimization is poorly constrained. Is the original idea of setting pcov to infinity based on pcov being meaningless due to paramerer variation being so large?
________________________________
From: Kyle Sunden <notifications@github.com>
Sent: Thursday, January 24, 2019 6:00:30 PM
To: wright-group/WrightTools
Cc: David Lafayette; Author
Subject: Re: [wright-group/WrightTools] pcov TypeError in kit._leastsq (#868)


Yes, so IndexError is thrown when you try to subscript a numpy array or scalar, but not a python float.

np.infis a raw python float, however np.array(np.inf) is a numpy scalar, which will raise IndexError here.

So, it really doesn't matter what array you put in there (it doesn't even need to be 2D), just can't be a python float.

Or we can except both IndexError and TypeError

see #753<https://github.com/wright-group/WrightTools/pull/753>

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<https://github.com/wright-group/WrightTools/issues/868#issuecomment-457404446>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AnH_haVXZNCqlOSS-Aqxfu-8mQo_-p8eks5vGkkegaJpZM4aR3BF>.


Resolving patch:
diff --git a/WrightTools/kit/_leastsq.py b/WrightTools/kit/_leastsq.py
--- a/WrightTools/kit/_leastsq.py
+++ b/WrightTools/kit/_leastsq.py
@@ -65,7 +65,7 @@ def errfunc(p, x, y):
             if cov_verbose:
                 print(pcov)
         else:
-            pcov = np.inf
+            pcov = np.array(np.inf)
         # calculate and write errors
         error = []
         for i in range(len(pfit_leastsq)):


Test patch:
diff --git a/tests/kit/leastsqfitter.py b/tests/kit/leastsqfitter.py
new file mode 100644
--- /dev/null
+++ b/tests/kit/leastsqfitter.py
@@ -0,0 +1,19 @@
+import numpy as np
+import WrightTools as wt
+
+
+def test_leastsq():
+    x = np.linspace(0, 10)
+    y = np.linspace(10, 0)
+    fit, cov = wt.kit.leastsqfitter([0, 0], x, y, lambda p, x: p[0] * x + p[1])
+    assert np.allclose(fit, [-1, 10])
+    assert np.allclose(cov, [0, 0])
+
+
+def test_leastsq_no_corr():
+    x = np.linspace(0, 10)
+    y = np.linspace(10, 0)
+    # The third parameter does not determine output, this caused an exception in wt <= 3.2.1
+    fit, cov = wt.kit.leastsqfitter([0, 0, 0], x, y, lambda p, x: p[0] * x + p[1])
+    assert np.allclose(fit, [-1, 10, 0])
+    assert np.allclose(cov, [0, 0, 0])