{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a80529e4",
   "metadata": {},
   "source": [
    "# Analisi dei dati con il sonar\n",
    "Minimo Indice:\n",
    "- Analisi dei dati statici\n",
    "- Analisi dei dati dinamici\n",
    "  - Sonar\n",
    "  - Cronometro"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "32702b8f",
   "metadata": {},
   "source": [
    "## Import delle librerie e set di variabili gloabali"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 232,
   "id": "f34c5b88",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import scipy as sc\n",
    "from scipy.stats import chi2\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib as mpl\n",
    "import statsmodels.api as sm\n",
    "\n",
    "\n",
    "g = 9.807\n",
    "ug = 0.001\n",
    "\n",
    "m_mol = 29.89\n",
    "um_mol = 0.01"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd0b8b1d",
   "metadata": {},
   "source": [
    "## Lettura dei dati e calcolo delle deviazioni standard campionarie\n",
    "- Lettura del CSV\n",
    "- Creazione del data frame\n",
    "- Deviazioni standard\n",
    "\n",
    "ATTENZIONE: Linea cursed ~17"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "id": "08efb2be",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(r'dinamica1.csv')\n",
    "\n",
    "def calcola_stats(df, prefix, err_arbitrario):\n",
    "  cols = [col for col in df.columns if col.startswith(prefix)]\n",
    "\n",
    "  def riga_stats(row):\n",
    "    valori = row[cols].dropna()\n",
    "    n = len(valori)\n",
    "\n",
    "    if n == 0:\n",
    "      return pd.Series({prefix: np.nan, f\"u{prefix}\": np.nan})\n",
    "    elif n == 1:\n",
    "      return pd.Series({prefix: valori.iloc[0], f\"u{prefix}\": err_arbitrario})\n",
    "    else:\n",
    "      media = valori.mean()\n",
    "      sigma = valori.std(ddof=1)\n",
    "      return pd.Series({prefix: media, f\"u{prefix}\": sigma})\n",
    "\n",
    "  stats = df.apply(riga_stats, axis=1)\n",
    "  df[prefix] = stats[prefix]\n",
    "  df[f\"u{prefix}\"] = stats[f\"u{prefix}\"]\n",
    "\n",
    "  return df\n",
    "\n",
    "\n",
    "df = calcola_stats(df, \"w\", err_arbitrario=0.0002)\n",
    "df = calcola_stats(df, \"m\", err_arbitrario=0.0028867513)\n",
    "df = calcola_stats(df, \"c\", err_arbitrario=0.01)\n",
    "df = calcola_stats(df, \"a\", err_arbitrario=0.01)\n",
    "df = calcola_stats(df, \"t\", err_arbitrario=0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 234,
   "id": "5494409f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>m1</th>\n",
       "      <th>a1</th>\n",
       "      <th>ua1</th>\n",
       "      <th>w1</th>\n",
       "      <th>uw1</th>\n",
       "      <th>c1</th>\n",
       "      <th>uc1</th>\n",
       "      <th>a2</th>\n",
       "      <th>ua2</th>\n",
       "      <th>w2</th>\n",
       "      <th>uw2</th>\n",
       "      <th>c2</th>\n",
       "      <th>uc2</th>\n",
       "      <th>w</th>\n",
       "      <th>uw</th>\n",
       "      <th>m</th>\n",
       "      <th>um</th>\n",
       "      <th>c</th>\n",
       "      <th>uc</th>\n",
       "      <th>a</th>\n",
       "      <th>ua</th>\n",
       "      <th>t</th>\n",
       "      <th>ut</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>108.610000</td>\n",
       "      <td>9.210</td>\n",
       "      <td>0.029</td>\n",
       "      <td>14.2459</td>\n",
       "      <td>0.0008</td>\n",
       "      <td>268.151</td>\n",
       "      <td>0.020</td>\n",
       "      <td>10.690</td>\n",
       "      <td>0.040</td>\n",
       "      <td>14.2434</td>\n",
       "      <td>0.0009</td>\n",
       "      <td>268.326</td>\n",
       "      <td>0.026</td>\n",
       "      <td>14.24465</td>\n",
       "      <td>0.001768</td>\n",
       "      <td>108.610000</td>\n",
       "      <td>0.002887</td>\n",
       "      <td>268.2385</td>\n",
       "      <td>0.123744</td>\n",
       "      <td>9.9500</td>\n",
       "      <td>1.046518</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>128.636667</td>\n",
       "      <td>10.037</td>\n",
       "      <td>0.025</td>\n",
       "      <td>13.1939</td>\n",
       "      <td>0.0007</td>\n",
       "      <td>259.605</td>\n",
       "      <td>0.018</td>\n",
       "      <td>9.744</td>\n",
       "      <td>0.027</td>\n",
       "      <td>13.1913</td>\n",
       "      <td>0.0009</td>\n",
       "      <td>259.745</td>\n",
       "      <td>0.020</td>\n",
       "      <td>13.19260</td>\n",
       "      <td>0.001838</td>\n",
       "      <td>128.636667</td>\n",
       "      <td>0.002887</td>\n",
       "      <td>259.6750</td>\n",
       "      <td>0.098995</td>\n",
       "      <td>9.8905</td>\n",
       "      <td>0.207182</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>148.380000</td>\n",
       "      <td>9.930</td>\n",
       "      <td>0.030</td>\n",
       "      <td>12.3469</td>\n",
       "      <td>0.0007</td>\n",
       "      <td>251.525</td>\n",
       "      <td>0.021</td>\n",
       "      <td>11.410</td>\n",
       "      <td>0.030</td>\n",
       "      <td>12.3461</td>\n",
       "      <td>0.0006</td>\n",
       "      <td>251.542</td>\n",
       "      <td>0.023</td>\n",
       "      <td>12.34650</td>\n",
       "      <td>0.000566</td>\n",
       "      <td>148.380000</td>\n",
       "      <td>0.002887</td>\n",
       "      <td>251.5335</td>\n",
       "      <td>0.012021</td>\n",
       "      <td>10.6700</td>\n",
       "      <td>1.046518</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>168.530000</td>\n",
       "      <td>11.340</td>\n",
       "      <td>0.030</td>\n",
       "      <td>11.6345</td>\n",
       "      <td>0.0005</td>\n",
       "      <td>243.211</td>\n",
       "      <td>0.021</td>\n",
       "      <td>11.500</td>\n",
       "      <td>0.030</td>\n",
       "      <td>11.6344</td>\n",
       "      <td>0.0006</td>\n",
       "      <td>243.130</td>\n",
       "      <td>0.021</td>\n",
       "      <td>11.63445</td>\n",
       "      <td>0.000071</td>\n",
       "      <td>168.530000</td>\n",
       "      <td>0.002887</td>\n",
       "      <td>243.1705</td>\n",
       "      <td>0.057276</td>\n",
       "      <td>11.4200</td>\n",
       "      <td>0.113137</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           m1      a1    ua1       w1     uw1       c1    uc1      a2    ua2  \\\n",
       "0  108.610000   9.210  0.029  14.2459  0.0008  268.151  0.020  10.690  0.040   \n",
       "1  128.636667  10.037  0.025  13.1939  0.0007  259.605  0.018   9.744  0.027   \n",
       "2  148.380000   9.930  0.030  12.3469  0.0007  251.525  0.021  11.410  0.030   \n",
       "3  168.530000  11.340  0.030  11.6345  0.0005  243.211  0.021  11.500  0.030   \n",
       "\n",
       "        w2     uw2       c2    uc2         w        uw           m        um  \\\n",
       "0  14.2434  0.0009  268.326  0.026  14.24465  0.001768  108.610000  0.002887   \n",
       "1  13.1913  0.0009  259.745  0.020  13.19260  0.001838  128.636667  0.002887   \n",
       "2  12.3461  0.0006  251.542  0.023  12.34650  0.000566  148.380000  0.002887   \n",
       "3  11.6344  0.0006  243.130  0.021  11.63445  0.000071  168.530000  0.002887   \n",
       "\n",
       "          c        uc        a        ua   t  ut  \n",
       "0  268.2385  0.123744   9.9500  1.046518 NaN NaN  \n",
       "1  259.6750  0.098995   9.8905  0.207182 NaN NaN  \n",
       "2  251.5335  0.012021  10.6700  1.046518 NaN NaN  \n",
       "3  243.1705  0.057276  11.4200  0.113137 NaN NaN  "
      ]
     },
     "execution_count": 234,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.set_option('display.max_columns', None)\n",
    "pd.set_option('display.width', None)\n",
    "\n",
    "df"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b8d8cb4",
   "metadata": {},
   "source": [
    "# Analisi statica"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd1b1164",
   "metadata": {},
   "source": [
    "## Permutazioni"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 235,
   "id": "976d5531",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]\n",
      "6\n",
      "############################################################\n",
      "[ 8.5635 16.705  25.068   8.1415 16.5045  8.363 ]\n",
      "[0.15846924 0.12432618 0.13635615 0.09972211 0.11437001 0.0585235 ]\n",
      "############################################################\n",
      "[-20.02666667 -39.77       -59.92       -19.74333333 -39.89333333\n",
      " -20.15      ]\n",
      "[0.00408248 0.00408248 0.00408248 0.00408248 0.00408248 0.00408248]\n"
     ]
    }
   ],
   "source": [
    "perm = [(x,i) for x in range(0,len(df)) for i in range(x+1,len(df))]\n",
    "\n",
    "este = np.array([df.c[x] - df.c[j] for x,j in perm])\n",
    "ueste = np.array([np.sqrt(df.uc[x]**2 + df.uc[j]**2) for x,j in perm])\n",
    "\n",
    "masse = np.array([df.m[x] - df.m[j] for x,j in perm])\n",
    "umasse = np.array([np.sqrt(df.um[x]**2 + df.um[j]**2) for x,j in perm])\n",
    "\n",
    "\n",
    "print(perm)\n",
    "print(len(perm))\n",
    "\n",
    "print(\"#\"* 60)\n",
    "print(este)\n",
    "print(ueste)\n",
    "\n",
    "print(\"#\"* 60)\n",
    "print(masse)\n",
    "print(umasse)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d37fbd7c",
   "metadata": {},
   "source": [
    "## Calcolo dei K e media pesata\n",
    "- Calcolo del K\n",
    "- Calcolo della media pesata (sui K)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 236,
   "id": "2ad19283",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[22.93472529 23.34776354 23.44165629 23.78221089 23.70468175 23.62920603]\n",
      "[0.42444376 0.17379748 0.12754214 0.29135079 0.16430027 0.16544183]\n"
     ]
    }
   ],
   "source": [
    "F = masse * g\n",
    "uF = np.sqrt((g * umasse)**2 + (masse * ug)**2)\n",
    "\n",
    "K = - F / este\n",
    "uK = np.sqrt((1/este)**2 * uF**2   +   (F / este**2)**2 * ueste**2  )\n",
    "\n",
    "\n",
    "print(K)\n",
    "print(uK)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 237,
   "id": "5f59d6c9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-medio: 23.52082621035826\n",
      "sigmaC:  0.07342397251895814\n"
     ]
    }
   ],
   "source": [
    "def mediaPesata(x, ux, dim = 0):\n",
    "  x_arr = x.to_numpy() if isinstance(x, (pd.Series, pd.DataFrame)) else np.asarray(x)\n",
    "  sigma_arr = ux.to_numpy() if isinstance(ux, (pd.Series, pd.DataFrame)) else np.asarray(ux)\n",
    "\n",
    "  w = 1.0 / (sigma_arr ** 2)\n",
    "\n",
    "  num = np.nansum(w * x_arr, axis=dim)\n",
    "  den = np.nansum(w, axis=dim)\n",
    "\n",
    "  media = num / den\n",
    "  sigma = np.sqrt(1.0 / den)\n",
    "\n",
    "  return media, sigma\n",
    "\n",
    "media, uA = mediaPesata(K, uK)\n",
    "print(\"K-medio:\", media)\n",
    "print(\"sigmaC: \", uA)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21baebb4",
   "metadata": {},
   "source": [
    "## Analisi con regressioni e grafici\n",
    "Ogni blocco ha:\n",
    "- Regressione\n",
    "- grafico\n",
    "- chi^2\n",
    "\n",
    "Nota: Ax + B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 238,
   "id": "1d4c0ffa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "u_strum_m    = 0.004082\n",
      "u_strum_Dx   = 0.081650\n"
     ]
    }
   ],
   "source": [
    "res_b = 0.01\n",
    "res_c = 0.2\n",
    "\n",
    "# Incertezza strumentale su una differenza: res/sqrt(12) * sqrt(2) = res/sqrt(6)\n",
    "u_strum_m  = res_b / np.sqrt(6)\n",
    "u_strum_Dx = res_c / np.sqrt(6)\n",
    "\n",
    "# Massimo tra campionario e strumentale, punto per punto\n",
    "ueste_strum  = u_strum_Dx\n",
    "umasse_strum = u_strum_m\n",
    "\n",
    "# Worst-case scalare: prendi il massimo anche di ueste_strum\n",
    "uF_strum  = np.sqrt( (g * umasse_strum)**2 + (masse * ug)**2 )\n",
    "uDx_strum = ueste_strum\n",
    "\n",
    "# uK_strum  = np.average(np.sqrt( (1/este)**2 * uF_strum**2 + (F/este**2)**2 * uDx_strum**2 ))\n",
    "\n",
    "print(f\"u_strum_m    = {u_strum_m:.6f}\")\n",
    "print(f\"u_strum_Dx   = {u_strum_Dx:.6f}\")\n",
    "# print(f\"uF_strum     = {uF_strum:.6f}\")\n",
    "# print(f\"uK_strum     = {uK_strum:.6f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 239,
   "id": "5be377eb",
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set_theme(style=\"whitegrid\")\n",
    "\n",
    "data = pd.DataFrame({\n",
    "    \"x\": este,\n",
    "    \"ux\": np.sqrt(ueste**2 + uDx_strum**2),\n",
    "    \"y\": - F,\n",
    "    \"uy\": np.sqrt(uF**2 + uF_strum**2)\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ec60a92",
   "metadata": {},
   "source": [
    "### Regressione lineare \"OLS\"\n",
    "\n",
    "Non tiene conto dei nostri errori, un risultato puro e semplice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "id": "aefe7756",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                            OLS Regression Results                            \n",
      "==============================================================================\n",
      "Dep. Variable:                      y   R-squared:                       1.000\n",
      "Model:                            OLS   Adj. R-squared:                  1.000\n",
      "Method:                 Least Squares   F-statistic:                 1.044e+04\n",
      "Date:                Wed, 08 Apr 2026   Prob (F-statistic):           5.50e-08\n",
      "Time:                        09:57:16   Log-Likelihood:                -14.807\n",
      "No. Observations:                   6   AIC:                             33.61\n",
      "Df Residuals:                       4   BIC:                             33.20\n",
      "Df Model:                           1                                         \n",
      "Covariance Type:            nonrobust                                         \n",
      "==============================================================================\n",
      "                 coef    std err          t      P>|t|      [0.025      0.975]\n",
      "------------------------------------------------------------------------------\n",
      "const          0.1355      3.495      0.039      0.971      -9.569       9.840\n",
      "x             23.4652      0.230    102.161      0.000      22.827      24.103\n",
      "==============================================================================\n",
      "Omnibus:                          nan   Durbin-Watson:                   0.555\n",
      "Prob(Omnibus):                    nan   Jarque-Bera (JB):                0.395\n",
      "Skew:                          -0.285   Prob(JB):                        0.821\n",
      "Kurtosis:                       1.880   Cond. No.                         37.4\n",
      "==============================================================================\n",
      "\n",
      "Notes:\n",
      "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
      "\n",
      "RISULTATI REGRESSIONE:\n",
      "Aols  = 23.46517 ± 0.22969\n",
      "Bols  = 0.13548 ± 3.49525\n",
      "R² = 0.99962\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/jack/uni/lab/.venv/lib/python3.13/site-packages/statsmodels/stats/stattools.py:74: ValueWarning: omni_normtest is not valid with less than 8 observations; 6 samples were given.\n",
      "  warn(\"omni_normtest is not valid with less than 8 observations; %i \"\n"
     ]
    }
   ],
   "source": [
    "X = sm.add_constant(data[\"x\"])\n",
    "model = sm.OLS(data[\"y\"], X).fit()\n",
    "\n",
    "print(model.summary())\n",
    "\n",
    "# Estrazione parametri\n",
    "Bols = model.params[\"const\"]\n",
    "Aols = model.params[\"x\"]\n",
    "uBols = model.bse[\"const\"]\n",
    "uAols = model.bse[\"x\"]\n",
    "R2 = model.rsquared\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE:\")\n",
    "print(f\"Aols  = {Aols:.5f} ± {uAols:.5f}\")\n",
    "print(f\"Bols  = {Bols:.5f} ± {uBols:.5f}\")\n",
    "print(f\"R² = {R2:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 241,
   "id": "8d795186",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 49728 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot( data=data,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  data[\"x\"],\n",
    "  data[\"y\"],\n",
    "  xerr=data[\"ux\"],\n",
    "  yerr=data[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, data[\"x\"].max(), 200)\n",
    "yfit = Bols + Aols * xfit\n",
    "\n",
    "plt.plot(\n",
    "  xfit,\n",
    "  yfit,\n",
    "  color=\"crimson\",\n",
    "  linewidth=1,\n",
    "  zorder=10,\n",
    "  label=\"Fit lineare OLS\"\n",
    ")\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Δx (mm)\")\n",
    "plt.ylabel(\"Forza F (mN)\")\n",
    "plt.title(\"Legge di Hooke — punti permutati con errorbar\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 242,
   "id": "1d42b009",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 3.91693\n",
      "GdL       = 4\n",
      "Chi² rid  = 0.97923\n",
      "P(0, chi²)= 0.58263\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0    1.250317\n",
      "1    0.360714\n",
      "2    0.037755\n",
      "3    0.653693\n",
      "4    1.339556\n",
      "5    0.274893\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit = Bols + Aols * data[\"x\"]\n",
    "sigma = np.sqrt(data[\"uy\"]**2 + (Aols * data[\"ux\"])**2)\n",
    "\n",
    "chi2_val = np.sum( ((data[\"y\"] - F_fit) / sigma)**2 )\n",
    "\n",
    "N = len(data)\n",
    "nu = N - 2\n",
    "\n",
    "chi2_red = chi2_val / nu\n",
    "Pols = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nu}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {Pols:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((data[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f26f65e",
   "metadata": {},
   "source": [
    "### Regressione lineare Carpi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 243,
   "id": "6a910226",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ax + B : \n",
      "AC      = 23.4106 +- 0.2224\n",
      "BC      = 1.4233 +- 3.1272\n",
      "cov_ABC = -0.632350\n",
      "P(0, chi²)= 0.5436\n"
     ]
    }
   ],
   "source": [
    "def sigma_y_equiv(x, y, sigma_x, sigma_y):\n",
    "  # Stima iniziale di A con sola sigma_y\n",
    "  sy2 = sigma_y**2\n",
    "  Sw   = np.sum(1 / sy2)\n",
    "  Sx   = np.sum(x / sy2)\n",
    "  Sxx  = np.sum(x**2 / sy2)\n",
    "  Sy   = np.sum(y / sy2)\n",
    "  Sxy  = np.sum(x * y / sy2)\n",
    "  delta = Sxx * Sw - Sx**2\n",
    "  A_est = (Sxy * Sw - Sx * Sy) / delta\n",
    "\n",
    "  # Propagazione\n",
    "  sigma_eq = np.sqrt(sigma_y**2 + A_est**2 * sigma_x**2)\n",
    "  return sigma_eq\n",
    "\n",
    "\n",
    "def reg_lin(x, y, sigma_x, sigma_y):\n",
    "  x = np.asarray(x, dtype=float)\n",
    "  y = np.asarray(y, dtype=float)\n",
    "  sigma_x = np.asarray(sigma_x, dtype=float)\n",
    "  sigma_y = np.asarray(sigma_y, dtype=float)\n",
    "\n",
    "  # Propagazione errore x → y\n",
    "  sigma_y_eq = sigma_y_equiv(x, y, sigma_x, sigma_y)\n",
    "\n",
    "  # Somme pesate\n",
    "  w    = 1.0 / sigma_y_eq**2\n",
    "  Sw   = np.sum(w)\n",
    "  Sx   = np.sum(w * x)\n",
    "  Sxx  = np.sum(w * x**2)\n",
    "  Sy   = np.sum(w * y)\n",
    "  Sxy  = np.sum(w * x * y)\n",
    "  delta = Sxx * Sw - Sx**2\n",
    "\n",
    "  # Parametri\n",
    "  A      = (Sxy * Sw - Sx * Sy)  / delta\n",
    "  B      = (Sxx * Sy - Sxy * Sx) / delta\n",
    "  sigma_A = np.sqrt(Sw  / delta)\n",
    "  sigma_B = np.sqrt(Sxx / delta)\n",
    "  cov_AB  = -Sx / delta\n",
    "\n",
    "  # Chi quadro\n",
    "  x2  = np.sum((y - A * x - B)**2 / sigma_y_eq**2)\n",
    "  dof = len(x) - 2\n",
    "  chi = sc.stats.chi2.cdf(x2, dof)  # P(X² > x2)\n",
    "\n",
    "  return A, B, sigma_A, sigma_B, cov_AB, chi\n",
    "\n",
    "\n",
    "AC, BC, uAC, uBC, covABC, chiC = reg_lin(data[\"x\"], data[\"y\"], data[\"ux\"], data[\"uy\"])\n",
    "print(\"Ax + B : \")\n",
    "print(f\"AC      = {AC:.4f} +- {uAC:.4f}\")\n",
    "print(f\"BC      = {BC:.4f} +- {uBC:.4f}\")\n",
    "print(f\"cov_ABC = {covABC:.6f}\")\n",
    "print(f\"P(0, chi²)= {chiC:.4f}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 244,
   "id": "b49ec5a3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 56628 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot(\n",
    "  data=data,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  data[\"x\"],\n",
    "  data[\"y\"],\n",
    "  xerr=data[\"ux\"],\n",
    "  yerr=data[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, data[\"x\"].max(), 200)\n",
    "yfit = BC + AC * xfit\n",
    "\n",
    "\n",
    "plt.plot(\n",
    "  xfit,\n",
    "  yfit,\n",
    "  color=\"crimson\",\n",
    "  linewidth=1,\n",
    "  zorder=10,\n",
    "  label=\"Fit lineare Carpi\"\n",
    ")\n",
    "\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Δx (mm)\")\n",
    "plt.ylabel(\"Forza F (mN)\")\n",
    "plt.title(\"Legge di Hooke — punti permutati con errorbar\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 245,
   "id": "538ddb98",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 3.66772\n",
      "GdL       = 4\n",
      "Chi² rid  = 0.91693\n",
      "P(0, chi²)= 0.54716\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0    1.735332\n",
      "1    0.503968\n",
      "2    0.029958\n",
      "3    0.281908\n",
      "4    1.086900\n",
      "5    0.029650\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit = BC + AC * data[\"x\"]\n",
    "sigma = np.sqrt(data[\"uy\"]**2 + (AC * data[\"ux\"])**2)\n",
    "\n",
    "\n",
    "chi2_val = np.sum( ((data[\"y\"] - F_fit) / sigma)**2 )\n",
    "\n",
    "N = len(data)\n",
    "nu = N - 2\n",
    "\n",
    "chi2_red = chi2_val / nu\n",
    "PC = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nu}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {PC:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((data[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ec42f61",
   "metadata": {},
   "source": [
    "### Regressione lineare pesata Yorkfit "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 246,
   "id": "c7f54cf3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AY        = 23.4182722 ± 0.2217067\n",
      "BY        = 1.3248937 ± 3.1178836\n",
      "cov_ABY   = -0.628605644189924\n",
      "chi²      = 3.66651\n",
      "chi² rid  = 0.91663\n",
      "P(0, chi²)= 0.54698\n"
     ]
    }
   ],
   "source": [
    "def york_fit(x, y, sx, sy, max_iter=50, tol=1e-15):\n",
    "  # Pesi iniziali\n",
    "  wx = 1 / sx**2\n",
    "  wy = 1 / sy**2\n",
    "\n",
    "  # Stima iniziale della pendenza (OLS y|x)\n",
    "  A = np.cov(x, y, aweights=wy)[0,1] / np.cov(x, x, aweights=wy)[0,1]\n",
    "\n",
    "  for _ in range(max_iter):\n",
    "    A_old = A\n",
    "\n",
    "    # 1) Pesi combinati\n",
    "    Wi = (wx * wy) / (A**2 * wy + wx)\n",
    "\n",
    "    # 2) x e y pesati (eq. 10)\n",
    "    X_bar = np.sum(Wi * x) / np.sum(Wi)\n",
    "    Y_bar = np.sum(Wi * y) / np.sum(Wi)\n",
    "\n",
    "    # 3) Variabili centrate\n",
    "    Ui = x - X_bar\n",
    "    Vi = y - Y_bar\n",
    "\n",
    "    # 4) beta\n",
    "    beta_i = Wi * (Ui / wy + A * Vi / wx)\n",
    "\n",
    "    # 5) Aggiornamento pendenza\n",
    "    A = np.sum(Wi * beta_i * Vi) / np.sum(Wi * beta_i * Ui)\n",
    "\n",
    "    # Convergenza\n",
    "    if abs(A - A_old) < tol:\n",
    "      break\n",
    "\n",
    "  # 6) Intercetta\n",
    "  B = Y_bar - A * X_bar\n",
    "\n",
    "  # S = somma Wi (xi - x)**2\n",
    "  S = np.sum(Wi * Ui**2)\n",
    "\n",
    "  sA = np.sqrt(1 / S)\n",
    "  sB = np.sqrt(1 / np.sum(Wi) + X_bar**2 * sA**2)\n",
    "\n",
    "  # cov(A,B)\n",
    "  cov_AB = -X_bar * sA**2\n",
    "\n",
    "  # CHI QUADRATO\n",
    "  chi2 = np.sum(Wi * (Vi - A * Ui)**2)\n",
    "  dof = len(x) - 2\n",
    "  chi2_red = chi2 / dof\n",
    "\n",
    "  return A, B, sA, sB, cov_AB, chi2, chi2_red\n",
    "\n",
    "AY, BY, uAY, uBY, cov_ABY, chi2_val, chi2_red = york_fit(data.x, data.y, data.ux, data.uy)\n",
    "PY = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "\n",
    "print(f\"AY        = {AY:.7f} ± {uAY:.7f}\")\n",
    "print(f\"BY        = {BY:.7f} ± {uBY:.7f}\")\n",
    "print(f\"cov_ABY   = {cov_ABY}\")\n",
    "print(f\"chi²      = {chi2_val:.5f}\")\n",
    "print(f\"chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {PY:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 247,
   "id": "fc824066",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 56280 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot( data=data,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  data[\"x\"],\n",
    "  data[\"y\"],\n",
    "  xerr=data[\"ux\"],\n",
    "  yerr=data[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, data[\"x\"].max(), 200)\n",
    "yfit = BY + AY * xfit\n",
    "\n",
    "plt.plot(\n",
    "  xfit,\n",
    "  yfit,\n",
    "  color=\"crimson\",\n",
    "  linewidth=1,\n",
    "  zorder=10,\n",
    "  label=\"Fit lineare York\"\n",
    ")\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Δx (mm)\")\n",
    "plt.ylabel(\"Forza F (mN)\")\n",
    "plt.title(\"Legge di Hooke — punti permutati con errorbar\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15a6fec5",
   "metadata": {},
   "source": [
    "## Raccolta finale dei dati caso statico"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 248,
   "id": "1203e1a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RISULTATI senza ERRORE STRUMENTALE INCLUSO:\n",
      "Media pesata K  = 23.52083 ± 0.07342\n",
      "\n",
      "RISULTATI REGRESSIONE OLS:\n",
      "Aols  = 23.46517 ± 0.22969\n",
      "Bols  = 0.13548 ± 3.49525\n",
      "P(0, chi²)= 0.58263\n",
      "\n",
      "RISULTATI REGRESSIONE Carpi:\n",
      "Ac  = 23.41058 ± 0.22237\n",
      "Bc  = 1.42328 ± 3.12716\n",
      "P(0, chi²)= 0.54716\n",
      "\n",
      "RISULTATI REGRESSIONE York:\n",
      "Ay  = 23.41827 ± 0.22171\n",
      "By  = 1.32489 ± 3.11788\n",
      "P(0, chi²)= 0.54698\n"
     ]
    }
   ],
   "source": [
    "print(\"RISULTATI senza ERRORE STRUMENTALE INCLUSO:\")\n",
    "print(f\"Media pesata K  = {media:.5f} ± {uA:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE OLS:\")\n",
    "print(f\"Aols  = {Aols:.5f} ± {uAols:.5f}\")\n",
    "print(f\"Bols  = {Bols:.5f} ± {uBols:.5f}\")\n",
    "print(f\"P(0, chi²)= {Pols:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE Carpi:\")\n",
    "print(f\"Ac  = {AC:.5f} ± {uAC:.5f}\")\n",
    "print(f\"Bc  = {BC:.5f} ± {uBC:.5f}\")\n",
    "print(f\"P(0, chi²)= {PC:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE York:\")\n",
    "print(f\"Ay  = {AY:.5f} ± {uAY:.5f}\")\n",
    "print(f\"By  = {BY:.5f} ± {uBY:.5f}\")\n",
    "print(f\"P(0, chi²)= {PY:.5f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb210b61",
   "metadata": {},
   "source": [
    "# Dinamica Sonar\n",
    "Qui specifico la formula perché non è così ovvia:\n",
    "- $M_{eq} = M + \\frac m 3$\n",
    "- $\\omega = \\frac{2\\pi}{T} \\quad \\Rightarrow \\quad T = \\frac{2\\pi}{\\omega}$\n",
    "- A: coefficiente della regressione lineare $A = \\frac{T^2}{M_{eq}}$\n",
    "- $K = \\frac{4 \\pi^2}{A}$\n",
    "\n",
    "Nota: nelle formule comparirà un $/1000$, questo serve a riportare il valore in unità di misura standard: N/m"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 249,
   "id": "95dde99f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "res_T    = 0.000800\n",
      "0    0.194561\n",
      "1    0.226829\n",
      "2    0.258983\n",
      "3    0.291654\n",
      "Name: w, dtype: float64\n",
      "0    0.000707\n",
      "1    0.000765\n",
      "2    0.000815\n",
      "3    0.000864\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "Meq = df.m + ( m_mol * 0.3333 )\n",
    "uMeq = np.sqrt( df.um**2 + um_mol**2 / 9 )\n",
    "\n",
    "T2 = ( 2 * np.pi / df.w )**2\n",
    "uT2 = np.sqrt( (8*np.pi**2 / df.w**3)**2 * df.uw**2 )\n",
    "\n",
    "res_b = 0.01 / np.sqrt(6) # riso bilancia\n",
    "res_T = 0.0008             # riso T\n",
    "\n",
    "T = 2 * np.pi / df.w\n",
    "res_T2 = 2 * T * res_T\n",
    "\n",
    "res_uAd = np.sqrt(  (1 / Meq)**2 * res_T2**2 + (T2 / Meq**2)**2 * res_b**2)\n",
    "\n",
    "\n",
    "print(f\"res_T    = {res_T:.6f}\")\n",
    "# print(f\"res_T2   = {res_T2:.6f}\")\n",
    "# print(f\"res_b    = {res_b:.6f}\")\n",
    "# print(f\"res_uAd  = {res_uAd:.6f}\")\n",
    "\n",
    "uT2 = np.sqrt(uT2**2 + res_T2**2)\n",
    "uMeq = np.sqrt(uMeq**2 + res_b**2)\n",
    "\n",
    "\n",
    "print(T2)\n",
    "print(uT2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bd743d4",
   "metadata": {},
   "source": [
    "## Calcolo dei K e media pesata\n",
    "- Calcolo della Meq (massa equivalente)\n",
    "- Calcolo della media pesata sui K"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 250,
   "id": "8c9f5b44",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    24.059519\n",
      "1    24.122421\n",
      "2    24.137082\n",
      "3    24.160799\n",
      "dtype: float64\n",
      "0    0.087485\n",
      "1    0.081324\n",
      "2    0.075925\n",
      "3    0.071586\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "Ad = T2 / Meq\n",
    "uAd = np.sqrt( (1/Meq)**2 * uT2**2 + (T2/Meq**2)**2 * uMeq**2 )\n",
    "\n",
    "Kd = 4 * np.pi**2 / Ad\n",
    "uKd = np.sqrt( (4 * np.pi**2 / Ad**2)**2 * uAd**2 )\n",
    "\n",
    "Kd /= 1000\n",
    "uKd /= 1000\n",
    "\n",
    "print(Kd)\n",
    "print(uKd)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "id": "0d899f17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-medio: 24.125209570730643\n",
      "sigmaC:  0.0392090048263168\n"
     ]
    }
   ],
   "source": [
    "def mediaPesata(x, ux, dim = 0):\n",
    "  x_arr = x.to_numpy() if isinstance(x, (pd.Series, pd.DataFrame)) else np.asarray(x)\n",
    "  sigma_arr = ux.to_numpy() if isinstance(ux, (pd.Series, pd.DataFrame)) else np.asarray(ux)\n",
    "\n",
    "  w = 1.0 / (sigma_arr ** 2)\n",
    "\n",
    "  num = np.nansum(w * x_arr, axis=dim)\n",
    "  den = np.nansum(w, axis=dim)\n",
    "\n",
    "  media = num / den\n",
    "  sigma = np.sqrt(1.0 / den)\n",
    "\n",
    "  return media, sigma\n",
    "\n",
    "KdM, uKdM = mediaPesata(Kd, uKd)\n",
    "print(\"K-medio:\", KdM)\n",
    "print(\"sigmaC: \", uKdM)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6741544e",
   "metadata": {},
   "source": [
    "## Analisi con regressioni e grafici\n",
    "Ogni blocco ha:\n",
    "- Regressione\n",
    "- grafico\n",
    "- chi^2\n",
    "\n",
    "Nota: Ax + B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 252,
   "id": "4b4c2682",
   "metadata": {},
   "outputs": [],
   "source": [
    "sns.set_theme(style=\"whitegrid\")\n",
    "\n",
    "datad = pd.DataFrame({\n",
    "    \"x\": Meq,\n",
    "    \"ux\": uMeq,\n",
    "    \"y\": T2,\n",
    "    \"uy\": uT2\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad203fbd",
   "metadata": {},
   "source": [
    "### Regressione lineare \"OLS\"\n",
    "\n",
    "Non tiene conto dei nostri errori, un risultato puro e semplice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 253,
   "id": "90d191d5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                            OLS Regression Results                            \n",
      "==============================================================================\n",
      "Dep. Variable:                      y   R-squared:                       1.000\n",
      "Model:                            OLS   Adj. R-squared:                  1.000\n",
      "Method:                 Least Squares   F-statistic:                 4.713e+05\n",
      "Date:                Wed, 08 Apr 2026   Prob (F-statistic):           2.12e-06\n",
      "Time:                        09:57:17   Log-Likelihood:                 32.343\n",
      "No. Observations:                   4   AIC:                            -60.69\n",
      "Df Residuals:                       2   BIC:                            -61.91\n",
      "Df Model:                           1                                         \n",
      "Covariance Type:            nonrobust                                         \n",
      "==============================================================================\n",
      "                 coef    std err          t      P>|t|      [0.025      0.975]\n",
      "------------------------------------------------------------------------------\n",
      "const          0.0023      0.000      6.369      0.024       0.001       0.004\n",
      "x              0.0016   2.36e-06    686.488      0.000       0.002       0.002\n",
      "==============================================================================\n",
      "Omnibus:                          nan   Durbin-Watson:                   2.752\n",
      "Prob(Omnibus):                    nan   Jarque-Bera (JB):                0.628\n",
      "Skew:                          -0.880   Prob(JB):                        0.730\n",
      "Kurtosis:                       2.180   Cond. No.                     1.01e+03\n",
      "==============================================================================\n",
      "\n",
      "Notes:\n",
      "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
      "[2] The condition number is large, 1.01e+03. This might indicate that there are\n",
      "strong multicollinearity or other numerical problems.\n",
      "\n",
      "RISULTATI REGRESSIONE:\n",
      "Adols  = 0.00162 ± 0.00000\n",
      "Bdols  = 0.00226 ± 0.00035\n",
      "R²     = 1.00000\n",
      "Kdols  = 24.35158 ± 0.03547\n",
      "KBdols = 17.47973 ± 2.74463\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/jack/uni/lab/.venv/lib/python3.13/site-packages/statsmodels/stats/stattools.py:74: ValueWarning: omni_normtest is not valid with less than 8 observations; 4 samples were given.\n",
      "  warn(\"omni_normtest is not valid with less than 8 observations; %i \"\n"
     ]
    }
   ],
   "source": [
    "X = sm.add_constant(datad[\"x\"])\n",
    "model = sm.OLS(datad[\"y\"], X).fit()\n",
    "\n",
    "print(model.summary())\n",
    "\n",
    "# Estrazione parametri\n",
    "Bdols = model.params[\"const\"]\n",
    "Adols = model.params[\"x\"]\n",
    "uBdols = model.bse[\"const\"]\n",
    "uAdols = model.bse[\"x\"]\n",
    "R2 = model.rsquared\n",
    "\n",
    "# Calcolo del K dai parametri\n",
    "Kdols = (2*np.pi)**2 / Adols / 1000\n",
    "uKdols = np.sqrt( (4*np.pi**2 / Adols**2)**2 * uAdols**2 ) / 1000\n",
    "KBdols = (2*np.pi)**2 / Bdols / 1000\n",
    "uKBdols = np.sqrt( (4*np.pi**2 / Bdols**2)**2 * uBdols**2 ) / 1000\n",
    "\n",
    "\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE:\")\n",
    "print(f\"Adols  = {Adols:.5f} ± {uAdols:.5f}\")\n",
    "print(f\"Bdols  = {Bdols:.5f} ± {uBdols:.5f}\")\n",
    "print(f\"R²     = {R2:.5f}\")\n",
    "print(f\"Kdols  = {Kdols:.5f} ± {uKdols:.5f}\")\n",
    "print(f\"KBdols = {KBdols:.5f} ± {uKBdols:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 254,
   "id": "a0ba5c8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54280 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot( data=datad,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  datad[\"x\"],\n",
    "  datad[\"y\"],\n",
    "  xerr=datad[\"ux\"],\n",
    "  yerr=datad[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, datad[\"x\"].max(), 200)\n",
    "yfit = Bdols + Adols * xfit\n",
    "\n",
    "plt.plot(\n",
    "  xfit, yfit,\n",
    "  color=\"crimson\", linewidth=1, zorder=10, label=\"Fit lineare OLS\"\n",
    ")\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T^2 (s^2)\")\n",
    "plt.title(\"Legge di ??\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 255,
   "id": "3c7c05e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 0.03921\n",
      "GdL       = 2\n",
      "Chi² rid  = 0.01961\n",
      "P(0, chi²)= 0.01942\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0    0.011216\n",
      "1    0.026289\n",
      "2    0.000774\n",
      "3    0.000933\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit = Bdols + Adols * datad[\"x\"]\n",
    "sigma = np.sqrt(datad[\"uy\"]**2 + (Adols * datad[\"ux\"])**2)\n",
    "\n",
    "chi2_val = np.sum( ((datad[\"y\"] - F_fit) / sigma)**2 )\n",
    "\n",
    "N = len(datad)\n",
    "nu = N - 2\n",
    "\n",
    "chi2_red = chi2_val / nu\n",
    "Pdols = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nu}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {Pdols:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((datad[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1296a66",
   "metadata": {},
   "source": [
    "### Regressione lineare Carpi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 256,
   "id": "698e3c48",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ax + B : \n",
      "AdC      = 0.00162 ± 0.00002\n",
      "BdC      = 0.00230 ± 0.00258\n",
      "cov_ABdC = -0.000000\n",
      "P(0,chi²)= 0.01927\n",
      "KdC      = 24.35604 ± 0.26416\n",
      "KBdC     = 17.14417 ± 19.22366\n"
     ]
    }
   ],
   "source": [
    "def sigma_y_equiv(x, y, sigma_x, sigma_y):\n",
    "  # Stima iniziale di A con sola sigma_y\n",
    "  sy2 = sigma_y**2\n",
    "  Sw   = np.sum(1 / sy2)\n",
    "  Sx   = np.sum(x / sy2)\n",
    "  Sxx  = np.sum(x**2 / sy2)\n",
    "  Sy   = np.sum(y / sy2)\n",
    "  Sxy  = np.sum(x * y / sy2)\n",
    "  delta = Sxx * Sw - Sx**2\n",
    "  A_est = (Sxy * Sw - Sx * Sy) / delta\n",
    "\n",
    "  # Propagazione\n",
    "  sigma_eq = np.sqrt(sigma_y**2 + A_est**2 * sigma_x**2)\n",
    "  return sigma_eq\n",
    "\n",
    "\n",
    "def reg_lin(x, y, sigma_x, sigma_y):\n",
    "  x = np.asarray(x, dtype=float)\n",
    "  y = np.asarray(y, dtype=float)\n",
    "  sigma_x = np.asarray(sigma_x, dtype=float)\n",
    "  sigma_y = np.asarray(sigma_y, dtype=float)\n",
    "\n",
    "  # Propagazione errore x → y\n",
    "  sigma_y_eq = sigma_y_equiv(x, y, sigma_x, sigma_y)\n",
    "\n",
    "  # Somme pesate\n",
    "  w    = 1.0 / sigma_y_eq**2\n",
    "  Sw   = np.sum(w)\n",
    "  Sx   = np.sum(w * x)\n",
    "  Sxx  = np.sum(w * x**2)\n",
    "  Sy   = np.sum(w * y)\n",
    "  Sxy  = np.sum(w * x * y)\n",
    "  delta = Sxx * Sw - Sx**2\n",
    "\n",
    "  # Parametri\n",
    "  A      = (Sxy * Sw - Sx * Sy)  / delta\n",
    "  B      = (Sxx * Sy - Sxy * Sx) / delta\n",
    "  sigma_A = np.sqrt(Sw  / delta)\n",
    "  sigma_B = np.sqrt(Sxx / delta)\n",
    "  cov_AB  = -Sx / delta\n",
    "\n",
    "  # Chi quadro\n",
    "  x2  = np.sum((y - A * x - B)**2 / sigma_y_eq**2)\n",
    "  dof = len(x) - 2\n",
    "  chi = sc.stats.chi2.cdf(x2, dof)  # P(X² > x2)\n",
    "\n",
    "  return A, B, sigma_A, sigma_B, cov_AB, chi\n",
    "\n",
    "\n",
    "AdC, BdC, uAdC, uBdC, covABdC, chidC = reg_lin(datad[\"x\"], datad[\"y\"], datad[\"ux\"], datad[\"uy\"])\n",
    "\n",
    "# Calcolo del K dai parametri\n",
    "KdC = (2*np.pi)**2 / AdC / 1000\n",
    "uKdC = np.sqrt( (4*np.pi**2 / AdC**2)**2 * uAdC**2 ) / 1000\n",
    "KBdC = (2*np.pi)**2 / BdC / 1000\n",
    "uKBdC = np.sqrt( (4*np.pi**2 / BdC**2)**2 * uBdC**2 ) / 1000\n",
    "\n",
    "print(\"Ax + B : \")\n",
    "print(f\"AdC      = {AdC:.5f} ± {uAdC:.5f}\")\n",
    "print(f\"BdC      = {BdC:.5f} ± {uBdC:.5f}\")\n",
    "print(f\"cov_ABdC = {covABdC:.6f}\")\n",
    "print(f\"P(0,chi²)= {chidC:.5f}\")\n",
    "print(f\"KdC      = {KdC:.5f} ± {uKdC:.5f}\")\n",
    "print(f\"KBdC     = {KBdC:.5f} ± {uKBdC:.5f}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 257,
   "id": "a0ab8534",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54452 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot(\n",
    "  data=datad,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  datad[\"x\"],\n",
    "  datad[\"y\"],\n",
    "  xerr=datad[\"ux\"],\n",
    "  yerr=datad[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, datad[\"x\"].max(), 200)\n",
    "yfit = BdC + AdC * xfit\n",
    "\n",
    "\n",
    "plt.plot(\n",
    "  xfit,\n",
    "  yfit,\n",
    "  color=\"crimson\",\n",
    "  linewidth=1,\n",
    "  zorder=10,\n",
    "  label=\"Fit lineare Carpi\"\n",
    ")\n",
    "\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T^2 (s^2)\")\n",
    "plt.title(\"Legge di ??\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 258,
   "id": "12bb0479",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 0.03892\n",
      "GdL       = 2\n",
      "Chi² rid  = 0.01946\n",
      "P(0, chi²)= 0.01927\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0    0.008684\n",
      "1    0.027599\n",
      "2    0.000978\n",
      "3    0.001658\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit = BdC + AdC * datad[\"x\"]\n",
    "sigma = np.sqrt(datad[\"uy\"]**2 + (AdC * datad[\"ux\"])**2)\n",
    "\n",
    "\n",
    "chi2_val = np.sum( ((datad[\"y\"] - F_fit) / sigma)**2 )\n",
    "\n",
    "N = len(datad)\n",
    "nu = N - 2\n",
    "\n",
    "chi2_red = chi2_val / nu\n",
    "PdC = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nu}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {PdC:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((datad[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3bf75d6",
   "metadata": {},
   "source": [
    "### Regressione lineare pesata Yorkfit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 259,
   "id": "385db415",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AdY       = 0.0016209 ± 0.0000176\n",
      "BdY       = 0.0023027 ± 0.0025820\n",
      "cov_ABdY  = -4.486957037705209e-08\n",
      "chi²      = 0.03892\n",
      "chi² rid  = 0.01946\n",
      "P(0, chi²)= 0.01927\n",
      "KdY       = 24.35604 ± 0.26416\n",
      "KBdY      = 17.14417 ± 19.22366\n"
     ]
    }
   ],
   "source": [
    "def york_fit(x, y, sx, sy, max_iter=50, tol=1e-15):\n",
    "  # Pesi iniziali\n",
    "  wx = 1 / sx**2\n",
    "  wy = 1 / sy**2\n",
    "\n",
    "  # Stima iniziale della pendenza (OLS y|x)\n",
    "  A = np.cov(x, y, aweights=wy)[0,1] / np.cov(x, x, aweights=wy)[0,1]\n",
    "\n",
    "  for _ in range(max_iter):\n",
    "    A_old = A\n",
    "\n",
    "    # 1) Pesi combinati\n",
    "    Wi = (wx * wy) / (A**2 * wy + wx)\n",
    "\n",
    "    # 2) x e y pesati (eq. 10)\n",
    "    X_bar = np.sum(Wi * x) / np.sum(Wi)\n",
    "    Y_bar = np.sum(Wi * y) / np.sum(Wi)\n",
    "\n",
    "    # 3) Variabili centrate\n",
    "    Ui = x - X_bar\n",
    "    Vi = y - Y_bar\n",
    "\n",
    "    # 4) beta\n",
    "    beta_i = Wi * (Ui / wy + A * Vi / wx)\n",
    "\n",
    "    # 5) Aggiornamento pendenza\n",
    "    A = np.sum(Wi * beta_i * Vi) / np.sum(Wi * beta_i * Ui)\n",
    "\n",
    "    # Convergenza\n",
    "    if abs(A - A_old) < tol:\n",
    "      break\n",
    "\n",
    "  # 6) Intercetta\n",
    "  B = Y_bar - A * X_bar\n",
    "\n",
    "  # S = somma Wi (xi - x)**2\n",
    "  S = np.sum(Wi * Ui**2)\n",
    "\n",
    "  sA = np.sqrt(1 / S)\n",
    "  sB = np.sqrt(1 / np.sum(Wi) + X_bar**2 * sA**2)\n",
    "\n",
    "  # cov(A,B)\n",
    "  cov_AB = -X_bar * sA**2\n",
    "\n",
    "  # CHI QUADRATO\n",
    "  chi2 = np.sum(Wi * (Vi - A * Ui)**2)\n",
    "  dof = len(x) - 2\n",
    "  chi2_red = chi2 / dof\n",
    "\n",
    "  return A, B, sA, sB, cov_AB, chi2, chi2_red\n",
    "\n",
    "AdY, BdY, uAdY, uBdY, cov_ABdY, chi2_val, chi2_red = york_fit(datad.x, datad.y, datad.ux, datad.uy)\n",
    "PdY = chi2.cdf(chi2_val, df=nu)\n",
    "\n",
    "# Calcolo del K dai parametri\n",
    "KdY = (2*np.pi)**2 / AdY / 1000\n",
    "uKdY = np.sqrt( (4*np.pi**2 / AdY**2)**2 * uAdY**2 ) / 1000\n",
    "KBdY = (2*np.pi)**2 / BdY / 1000\n",
    "uKBdY = np.sqrt( (4*np.pi**2 / BdY**2)**2 * uBdY**2 ) / 1000\n",
    "\n",
    "\n",
    "print(f\"AdY       = {AdY:.7f} ± {uAdY:.7f}\")\n",
    "print(f\"BdY       = {BdY:.7f} ± {uBdY:.7f}\")\n",
    "print(f\"cov_ABdY  = {cov_ABdY}\")\n",
    "print(f\"chi²      = {chi2_val:.5f}\")\n",
    "print(f\"chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {PdY:.5f}\")\n",
    "print(f\"KdY       = {KdY:.5f} ± {uKdY:.5f}\")\n",
    "print(f\"KBdY      = {KBdY:.5f} ± {uKBdY:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 260,
   "id": "698bc57c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 54164 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "# Seaborn scatter\n",
    "sns.scatterplot(\n",
    "  data=datad,\n",
    "  x=\"x\",\n",
    "  y=\"y\",\n",
    "  s=7\n",
    ")\n",
    "\n",
    "# Barre d’errore\n",
    "plt.errorbar(\n",
    "  datad[\"x\"],\n",
    "  datad[\"y\"],\n",
    "  xerr=datad[\"ux\"],\n",
    "  yerr=datad[\"uy\"],\n",
    "  fmt=\"none\",\n",
    "  ecolor=\"gray\",\n",
    "  elinewidth=1,\n",
    "  capsize=3,\n",
    "  alpha=0.7\n",
    ")\n",
    "\n",
    "# Linea di regressione\n",
    "xfit = np.linspace(0, datad[\"x\"].max(), 200)\n",
    "yfit = BdY + AdY * xfit\n",
    "\n",
    "\n",
    "plt.plot(\n",
    "  xfit,\n",
    "  yfit,\n",
    "  color=\"crimson\",\n",
    "  linewidth=1,\n",
    "  zorder=10,\n",
    "  label=\"Fit lineare York\"\n",
    ")\n",
    "\n",
    "\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "\n",
    "\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T^2 (s^2)\")\n",
    "plt.title(\"Legge di ??\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2e612bc6",
   "metadata": {},
   "source": [
    "## Raccolta finale di dati dinamici"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 261,
   "id": "fc32f9e6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RISULTATI senza ERRORE STRUMENTALE INCLUSO:\n",
      "Media pesata K  = 24.12521 ± 0.03921\n",
      "\n",
      "RISULTATI REGRESSIONE OLS:\n",
      "Adols    = 0.0016212 ± 0.00000\n",
      "Bdols    = 0.0022585 ± 0.00035\n",
      "P(0,chi²)= 0.0194154\n",
      "Kdols    = 24.3515777 ± 0.03547\n",
      "KBdols   = 17.4797252 ± 2.74463\n",
      "\n",
      "RISULTATI REGRESSIONE Carpi:\n",
      "AdC      = 0.0016209 ± 0.00002\n",
      "BdC      = 0.0023027 ± 0.00258\n",
      "P(0,chi²)= 0.0192717\n",
      "KdC      = 24.3560387 ± 0.26416\n",
      "KBdC     = 17.14417 ± 19.22366\n",
      "\n",
      "RISULTATI REGRESSIONE York:\n",
      "Ady      = 0.00162 ± 0.00002\n",
      "Bdy      = 0.00230 ± 0.00258\n",
      "P(0,chi²)= 0.01927\n",
      "KdY      = 24.35604 ± 0.26416\n",
      "KBdY     = 17.14417 ± 19.22366\n"
     ]
    }
   ],
   "source": [
    "print(\"RISULTATI senza ERRORE STRUMENTALE INCLUSO:\")\n",
    "print(f\"Media pesata K  = {KdM:.5f} ± {uKdM:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE OLS:\")\n",
    "print(f\"Adols    = {Adols:.7f} ± {uAdols:.5f}\")\n",
    "print(f\"Bdols    = {Bdols:.7f} ± {uBdols:.5f}\")\n",
    "print(f\"P(0,chi²)= {Pdols:.7f}\")\n",
    "print(f\"Kdols    = {Kdols:.7f} ± {uKdols:.5f}\")\n",
    "print(f\"KBdols   = {KBdols:.7f} ± {uKBdols:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE Carpi:\")\n",
    "print(f\"AdC      = {AdC:.7f} ± {uAdC:.5f}\")\n",
    "print(f\"BdC      = {BdC:.7f} ± {uBdC:.5f}\")\n",
    "print(f\"P(0,chi²)= {PdC:.7f}\")\n",
    "print(f\"KdC      = {KdC:.7f} ± {uKdC:.5f}\")\n",
    "print(f\"KBdC     = {KBdC:.5f} ± {uKBdC:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE York:\")\n",
    "print(f\"Ady      = {AdY:.5f} ± {uAdY:.5f}\")\n",
    "print(f\"Bdy      = {BdY:.5f} ± {uBdY:.5f}\")\n",
    "print(f\"P(0,chi²)= {PdY:.5f}\")\n",
    "print(f\"KdY      = {KdY:.5f} ± {uKdY:.5f}\")\n",
    "print(f\"KBdY     = {KBdY:.5f} ± {uKBdY:.5f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f4edfa1",
   "metadata": {},
   "source": [
    "# Dinamica Cronometro"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 262,
   "id": "0f407f81",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "Name: t, dtype: float64\n",
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "T2t  = (df.t / 20)**2\n",
    "uT2t = 2 * (df.t / 20) * (df.ut / 20)\n",
    "\n",
    "print(T2t)\n",
    "print(uT2t)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d097869",
   "metadata": {},
   "source": [
    "## Calcolo dei K e media pesata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 263,
   "id": "99bc83a7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "dtype: float64\n",
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "Adt  = T2t / Meq\n",
    "uAdt = np.sqrt( (1/Meq)**2 * uT2t**2 + (T2t/Meq**2)**2 * uMeq**2 )\n",
    "\n",
    "Kdt  = 4 * np.pi**2 / Adt\n",
    "uKdt = (4 * np.pi**2 / Adt**2) * uAdt\n",
    "\n",
    "Kdt\n",
    "uKdt\n",
    "\n",
    "print(Kdt)\n",
    "print(uKdt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 264,
   "id": "ae55d12a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "K-medio (t): nan\n",
      "sigmaC  (t): inf\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_87397/2995330097.py:10: RuntimeWarning: invalid value encountered in scalar divide\n",
      "  media = num / den\n",
      "/tmp/ipykernel_87397/2995330097.py:11: RuntimeWarning: divide by zero encountered in scalar divide\n",
      "  sigma = np.sqrt(1.0 / den)\n"
     ]
    }
   ],
   "source": [
    "KdtM, uKdtM = mediaPesata(Kdt, uKdt)\n",
    "KdtM /= 1e3\n",
    "uKdtM /= 1e3\n",
    "print(\"K-medio (t):\", KdtM)\n",
    "print(\"sigmaC  (t):\", uKdtM)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "634a06e9",
   "metadata": {},
   "source": [
    "## Analisi con regressioni e grafici"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 265,
   "id": "75e94b0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "datat = pd.DataFrame({\n",
    "    \"x\":  Meq,\n",
    "    \"ux\": uMeq,\n",
    "    \"y\":  T2t,\n",
    "    \"uy\": uT2t\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7761130",
   "metadata": {},
   "source": [
    "### Regressione lineare \"OLS\"\n",
    "Non tiene conto dei nostri errori, un risultato puro e semplice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 266,
   "id": "896388e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                            OLS Regression Results                            \n",
      "==============================================================================\n",
      "Dep. Variable:                      y   R-squared:                         nan\n",
      "Model:                            OLS   Adj. R-squared:                    nan\n",
      "Method:                 Least Squares   F-statistic:                       nan\n",
      "Date:                Wed, 08 Apr 2026   Prob (F-statistic):                nan\n",
      "Time:                        09:57:18   Log-Likelihood:                    nan\n",
      "No. Observations:                   4   AIC:                               nan\n",
      "Df Residuals:                       2   BIC:                               nan\n",
      "Df Model:                           1                                         \n",
      "Covariance Type:            nonrobust                                         \n",
      "==============================================================================\n",
      "                 coef    std err          t      P>|t|      [0.025      0.975]\n",
      "------------------------------------------------------------------------------\n",
      "const             nan        nan        nan        nan         nan         nan\n",
      "x                 nan        nan        nan        nan         nan         nan\n",
      "==============================================================================\n",
      "Omnibus:                          nan   Durbin-Watson:                     nan\n",
      "Prob(Omnibus):                    nan   Jarque-Bera (JB):                  nan\n",
      "Skew:                             nan   Prob(JB):                          nan\n",
      "Kurtosis:                         nan   Cond. No.                     1.01e+03\n",
      "==============================================================================\n",
      "\n",
      "Notes:\n",
      "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
      "[2] The condition number is large, 1.01e+03. This might indicate that there are\n",
      "strong multicollinearity or other numerical problems.\n",
      "\n",
      "RISULTATI REGRESSIONE OLS (t):\n",
      "Atols   = nan ± nan\n",
      "Btols   = nan ± nan\n",
      "R²      = nan\n",
      "Kdtols  = nan ± nan\n",
      "KBdtols = nan ± nan\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/jack/uni/lab/.venv/lib/python3.13/site-packages/statsmodels/stats/stattools.py:74: ValueWarning: omni_normtest is not valid with less than 8 observations; 4 samples were given.\n",
      "  warn(\"omni_normtest is not valid with less than 8 observations; %i \"\n"
     ]
    }
   ],
   "source": [
    "X = sm.add_constant(datat[\"x\"])\n",
    "model = sm.OLS(datat[\"y\"], X).fit()\n",
    "\n",
    "print(model.summary())\n",
    "\n",
    "Btols  = model.params[\"const\"]\n",
    "Atols  = model.params[\"x\"]\n",
    "uBtols = model.bse[\"const\"]\n",
    "uAtols = model.bse[\"x\"]\n",
    "R2t    = model.rsquared\n",
    "\n",
    "Kdtols  = 4 * np.pi**2 / Atols  / 1000\n",
    "uKdtols = (4 * np.pi**2 / Atols**2)  * uAtols  / 1000\n",
    "KBdtols  = 4 * np.pi**2 / Btols  / 1000\n",
    "uKBdtols = (4 * np.pi**2 / Btols**2) * uBtols  / 1000\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE OLS (t):\")\n",
    "print(f\"Atols   = {Atols:.5f} ± {uAtols:.5f}\")\n",
    "print(f\"Btols   = {Btols:.5f} ± {uBtols:.5f}\")\n",
    "print(f\"R²      = {R2t:.5f}\")\n",
    "print(f\"Kdtols  = {Kdtols:.5f} ± {uKdtols:.5f}\")\n",
    "print(f\"KBdtols = {KBdtols:.5f} ± {uKBdtols:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 267,
   "id": "61e40e4c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 34660 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "sns.scatterplot(data=datat, x=\"x\", y=\"y\", s=7)\n",
    "\n",
    "plt.errorbar(\n",
    "    datat[\"x\"], datat[\"y\"],\n",
    "    xerr=datat[\"ux\"], yerr=datat[\"uy\"],\n",
    "    fmt=\"none\", ecolor=\"gray\", elinewidth=1, capsize=3, alpha=0.7\n",
    ")\n",
    "\n",
    "xfit = np.linspace(0, datat[\"x\"].max(), 200)\n",
    "yfit = Btols + Atols * xfit\n",
    "\n",
    "plt.plot(xfit, yfit, color=\"crimson\", linewidth=1, zorder=10, label=\"Fit OLS t\")\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T² (s²)\")\n",
    "plt.title(\"Legge di ?? — cronometro\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 268,
   "id": "354687ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 0.00000\n",
      "GdL       = 2\n",
      "Chi² rid  = 0.00000\n",
      "P(0, chi²)= 0.00000\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit  = Btols + Atols * datat[\"x\"]\n",
    "sigma  = np.sqrt(datat[\"uy\"]**2 + (Atols * datat[\"ux\"])**2)\n",
    "\n",
    "chi2_val = np.sum(((datat[\"y\"] - F_fit) / sigma)**2)\n",
    "\n",
    "N   = len(datat)\n",
    "nut = N - 2\n",
    "\n",
    "chi2_red = chi2_val / nut\n",
    "Ptols = chi2.cdf(chi2_val, df=nut)\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nut}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {Ptols:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((datat[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c28f2d34",
   "metadata": {},
   "source": [
    "### Regressione lineare Carpi"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 269,
   "id": "8d6cd1df",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ax + B (Carpi, t):\n",
      "AtC      = nan ± nan\n",
      "BtC      = nan ± nan\n",
      "cov_ABtC = nan\n",
      "P(0,chi²)= nan\n",
      "KdtC     = nan ± nan\n",
      "KBdtC    = nan ± nan\n"
     ]
    }
   ],
   "source": [
    "AtC, BtC, uAtC, uBtC, covABtC, chitC = reg_lin(datat[\"x\"], datat[\"y\"], datat[\"ux\"], datat[\"uy\"])\n",
    "\n",
    "KdtC  = 4 * np.pi**2 / AtC  / 1000\n",
    "uKdtC = (4 * np.pi**2 / AtC**2)  * uAtC  / 1000\n",
    "KBdtC  = 4 * np.pi**2 / BtC  / 1000\n",
    "uKBdtC = (4 * np.pi**2 / BtC**2) * uBtC  / 1000\n",
    "\n",
    "print(\"Ax + B (Carpi, t):\")\n",
    "print(f\"AtC      = {AtC:.5f} ± {uAtC:.5f}\")\n",
    "print(f\"BtC      = {BtC:.5f} ± {uBtC:.5f}\")\n",
    "print(f\"cov_ABtC = {covABtC:.6f}\")\n",
    "print(f\"P(0,chi²)= {chitC:.5f}\")\n",
    "print(f\"KdtC     = {KdtC:.5f} ± {uKdtC:.5f}\")\n",
    "print(f\"KBdtC    = {KBdtC:.5f} ± {uKBdtC:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 270,
   "id": "592c257c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37296 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "sns.scatterplot(data=datat, x=\"x\", y=\"y\", s=7)\n",
    "\n",
    "plt.errorbar(\n",
    "    datat[\"x\"], datat[\"y\"],\n",
    "    xerr=datat[\"ux\"], yerr=datat[\"uy\"],\n",
    "    fmt=\"none\", ecolor=\"gray\", elinewidth=1, capsize=3, alpha=0.7\n",
    ")\n",
    "\n",
    "xfit = np.linspace(0, datat[\"x\"].max(), 200)\n",
    "yfit = BtC + AtC * xfit\n",
    "\n",
    "plt.plot(xfit, yfit, color=\"crimson\", linewidth=1, zorder=10, label=\"Fit Carpi (t)\")\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T² (s²)\")\n",
    "plt.title(\"Legge di Hooke dinamica — cronometro\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 271,
   "id": "12f276cc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Chi²      = 0.00000\n",
      "GdL       = 2\n",
      "Chi² rid  = 0.00000\n",
      "P(0, chi²)= 0.00000\n",
      "\n",
      "\n",
      "############################################################\n",
      "capiamo quale dato sta contribuendo maggiormente\n",
      "0   NaN\n",
      "1   NaN\n",
      "2   NaN\n",
      "3   NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "F_fit  = BtC + AtC * datat[\"x\"]\n",
    "sigma  = np.sqrt(datat[\"uy\"]**2 + (AtC * datat[\"ux\"])**2)\n",
    "chi2_val = np.sum(((datat[\"y\"] - F_fit) / sigma)**2)\n",
    "chi2_red = chi2_val / nut\n",
    "PtC = chi2.cdf(chi2_val, df=nut)\n",
    "\n",
    "print(f\"Chi²      = {chi2_val:.5f}\")\n",
    "print(f\"GdL       = {nut}\")\n",
    "print(f\"Chi² rid  = {chi2_red:.5f}\")\n",
    "print(f\"P(0, chi²)= {PtC:.5f}\")\n",
    "print(\"\\n\\n\" + \"#\"*60)\n",
    "print(\"capiamo quale dato sta contribuendo maggiormente\")\n",
    "print(((datat[\"y\"] - F_fit) / sigma)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0823cca1",
   "metadata": {},
   "source": [
    "### Regressione lineare pesata Yorkfit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 272,
   "id": "d04ee20e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AtY       = nan ± inf\n",
      "BtY       = nan ± nan\n",
      "cov_ABtY  = nan\n",
      "chi²      = 0.00000\n",
      "chi² rid  = 0.00000\n",
      "P(0, chi²)= 0.00000\n",
      "KdtY      = nan ± nan\n",
      "KBdtY     = nan ± nan\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_87397/788188722.py:16: RuntimeWarning: invalid value encountered in scalar divide\n",
      "  X_bar = np.sum(Wi * x) / np.sum(Wi)\n",
      "/tmp/ipykernel_87397/788188722.py:17: RuntimeWarning: invalid value encountered in scalar divide\n",
      "  Y_bar = np.sum(Wi * y) / np.sum(Wi)\n",
      "/tmp/ipykernel_87397/788188722.py:27: RuntimeWarning: invalid value encountered in scalar divide\n",
      "  A = np.sum(Wi * beta_i * Vi) / np.sum(Wi * beta_i * Ui)\n",
      "/tmp/ipykernel_87397/788188722.py:39: RuntimeWarning: divide by zero encountered in scalar divide\n",
      "  sA = np.sqrt(1 / S)\n",
      "/tmp/ipykernel_87397/788188722.py:40: RuntimeWarning: divide by zero encountered in scalar divide\n",
      "  sB = np.sqrt(1 / np.sum(Wi) + X_bar**2 * sA**2)\n"
     ]
    }
   ],
   "source": [
    "AtY, BtY, uAtY, uBtY, cov_ABtY, chi2_val_t, chi2_red_t = york_fit(datat.x, datat.y, datat.ux, datat.uy)\n",
    "PtY = chi2.cdf(chi2_val_t, df=nut)\n",
    "\n",
    "KdtY  = 4 * np.pi**2 / AtY  / 1000\n",
    "uKdtY = (4 * np.pi**2 / AtY**2)  * uAtY  / 1000\n",
    "KBdtY  = 4 * np.pi**2 / BtY  / 1000\n",
    "uKBdtY = (4 * np.pi**2 / BtY**2) * uBtY  / 1000\n",
    "\n",
    "print(f\"AtY       = {AtY:.7f} ± {uAtY:.7f}\")\n",
    "print(f\"BtY       = {BtY:.7f} ± {uBtY:.7f}\")\n",
    "print(f\"cov_ABtY  = {cov_ABtY}\")\n",
    "print(f\"chi²      = {chi2_val_t:.5f}\")\n",
    "print(f\"chi² rid  = {chi2_red_t:.5f}\")\n",
    "print(f\"P(0, chi²)= {PtY:.5f}\")\n",
    "print(f\"KdtY      = {KdtY:.5f} ± {uKdtY:.5f}\")\n",
    "print(f\"KBdtY     = {KBdtY:.5f} ± {uKBdtY:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 273,
   "id": "e795e732",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 37264 characters]",
      "text/plain": [
       "<Figure size 1000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10,6))\n",
    "\n",
    "sns.scatterplot(data=datat, x=\"x\", y=\"y\", s=7)\n",
    "\n",
    "plt.errorbar(\n",
    "    datat[\"x\"], datat[\"y\"],\n",
    "    xerr=datat[\"ux\"], yerr=datat[\"uy\"],\n",
    "    fmt=\"none\", ecolor=\"gray\", elinewidth=1, capsize=3, alpha=0.7\n",
    ")\n",
    "\n",
    "xfit = np.linspace(0, datat[\"x\"].max(), 200)\n",
    "yfit = BtY + AtY * xfit\n",
    "\n",
    "plt.plot(xfit, yfit, color=\"crimson\", linewidth=1, zorder=10, label=\"Fit York (t)\")\n",
    "plt.xlim(left=0)\n",
    "plt.ylim(bottom=0)\n",
    "plt.xlabel(\"Meq (g)\")\n",
    "plt.ylabel(\"T² (s²)\")\n",
    "plt.title(\"Legge di Hooke dinamica — cronometro\")\n",
    "plt.legend()\n",
    "plt.grid(True, linestyle=\"--\", alpha=0.1)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "038b2684",
   "metadata": {},
   "source": [
    "## Raccolta finale di dati dinamici col cronometro"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 274,
   "id": "46ef07bd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RISULTATI senza ERRORE STRUMENTALE (cronometro):\n",
      "Media pesata K  = nan ± inf\n",
      "\n",
      "RISULTATI REGRESSIONE OLS:\n",
      "Atols    = nan ± nan\n",
      "Btols    = nan ± nan\n",
      "P(0,chi²)= 0.00000\n",
      "Kdtols   = nan ± nan\n",
      "KBdtols  = nan ± nan\n",
      "\n",
      "RISULTATI REGRESSIONE Carpi:\n",
      "AtC      = nan ± nan\n",
      "BtC      = nan ± nan\n",
      "P(0,chi²)= 0.00000\n",
      "KdtC     = nan ± nan\n",
      "KBdtC    = nan ± nan\n",
      "\n",
      "RISULTATI REGRESSIONE York:\n",
      "AtY      = nan ± inf\n",
      "BtY      = nan ± nan\n",
      "P(0,chi²)= 0.00000\n",
      "KdtY     = nan ± nan\n",
      "KBdtY    = nan ± nan\n"
     ]
    }
   ],
   "source": [
    "print(\"RISULTATI senza ERRORE STRUMENTALE (cronometro):\")\n",
    "print(f\"Media pesata K  = {KdtM:.5f} ± {uKdtM:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE OLS:\")\n",
    "print(f\"Atols    = {Atols:.5f} ± {uAtols:.5f}\")\n",
    "print(f\"Btols    = {Btols:.5f} ± {uBtols:.5f}\")\n",
    "print(f\"P(0,chi²)= {Ptols:.5f}\")\n",
    "print(f\"Kdtols   = {Kdtols:.5f} ± {uKdtols:.5f}\")\n",
    "print(f\"KBdtols  = {KBdtols:.5f} ± {uKBdtols:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE Carpi:\")\n",
    "print(f\"AtC      = {AtC:.5f} ± {uAtC:.5f}\")\n",
    "print(f\"BtC      = {BtC:.5f} ± {uBtC:.5f}\")\n",
    "print(f\"P(0,chi²)= {PtC:.5f}\")\n",
    "print(f\"KdtC     = {KdtC:.5f} ± {uKdtC:.5f}\")\n",
    "print(f\"KBdtC    = {KBdtC:.5f} ± {uKBdtC:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI REGRESSIONE York:\")\n",
    "print(f\"AtY      = {AtY:.5f} ± {uAtY:.5f}\")\n",
    "print(f\"BtY      = {BtY:.5f} ± {uBtY:.5f}\")\n",
    "print(f\"P(0,chi²)= {PtY:.5f}\")\n",
    "print(f\"KdtY     = {KdtY:.5f} ± {uKdtY:.5f}\")\n",
    "print(f\"KBdtY    = {KBdtY:.5f} ± {uKBdtY:.5f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "70201336",
   "metadata": {},
   "source": [
    "## Aggiungi gli errori strumentali"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 275,
   "id": "dfcd391e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "res_t     = 0.000500\n",
      "res_t2   = nan\n",
      "res_uAdt      = nan\n",
      "uKdt_strum    = nan\n"
     ]
    }
   ],
   "source": [
    "res_t  = 0.01 / 20  # risoluzione cronometro\n",
    "res_t2 = np.max(2 * df.t * res_t)\n",
    "\n",
    "res_uAdt = np.max(np.sqrt( (1 / Meq)**2* res_t2**2 +(T2t / Meq**2)**2  * res_b**2))\n",
    "uKdt_strum = np.max(np.abs(4 * np.pi**2 / Adt**2) * res_uAdt) / 1000\n",
    "\n",
    "print(f\"res_t     = {res_t:.6f}\")\n",
    "print(f\"res_t2   = {res_t2:.6f}\")\n",
    "print(f\"res_uAdt      = {res_uAdt:.6f}\")\n",
    "print(f\"uKdt_strum    = {uKdt_strum:.6f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 276,
   "id": "b52fea3d",
   "metadata": {},
   "outputs": [],
   "source": [
    "uKdtM_fin   = np.sqrt(uKdtM**2   + uKdt_strum**2)\n",
    "\n",
    "uAtols_fin  = np.sqrt(uAtols**2  + res_uAdt**2)\n",
    "uBtols_fin  = np.sqrt(uBtols**2  + res_uAdt**2)\n",
    "uKdtols_fin = np.sqrt(uKdtols**2 + uKdt_strum**2)\n",
    "\n",
    "uAtC_fin    = np.sqrt(uAtC**2    + res_uAdt**2)\n",
    "uBtC_fin    = np.sqrt(uBtC**2    + res_uAdt**2)\n",
    "uKdtC_fin   = np.sqrt(uKdtC**2  + uKdt_strum**2)\n",
    "\n",
    "uAtY_fin    = np.sqrt(uAtY**2    + res_uAdt**2)\n",
    "uBtY_fin    = np.sqrt(uBtY**2    + res_uAdt**2)\n",
    "uKdtY_fin   = np.sqrt(uKdtY**2  + uKdt_strum**2)\n",
    "\n",
    "uy_fin_t = np.sqrt(datat[\"uy\"]**2 + res_t2**2)\n",
    "ux_fin_t = np.sqrt(datat[\"ux\"]**2 + res_b**2)\n",
    "\n",
    "GdLt = len(datat) - 2\n",
    "\n",
    "F_fit_tols = Btols + Atols * datat[\"x\"]\n",
    "sigma_tols  = np.sqrt(uy_fin_t**2 + (Atols * ux_fin_t)**2)\n",
    "chi2_tols   = np.sum(((datat[\"y\"] - F_fit_tols) / sigma_tols)**2)\n",
    "\n",
    "F_fit_tC   = BtC + AtC * datat[\"x\"]\n",
    "sigma_tC    = np.sqrt(uy_fin_t**2 + (AtC * ux_fin_t)**2)\n",
    "chi2_tC     = np.sum(((datat[\"y\"] - F_fit_tC) / sigma_tC)**2)\n",
    "\n",
    "F_fit_tY   = BtY + AtY * datat[\"x\"]\n",
    "sigma_tY    = np.sqrt(uy_fin_t**2 + (AtY * ux_fin_t)**2)\n",
    "chi2_tY     = np.sum(((datat[\"y\"] - F_fit_tY) / sigma_tY)**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "858bbff7",
   "metadata": {},
   "source": [
    "## Risultati della propagazione dell'errore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 277,
   "id": "0b1e4a1d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "RISULTATI CON ERRORE STRUMENTALE (cronometro):\n",
      "Media pesata K  = nan ± nan\n",
      "\n",
      "RISULTATI OLS:\n",
      "Atols  = nan ± nan\n",
      "Btols  = nan ± nan\n",
      "Kdtols = nan ± nan\n",
      "Chi²   = 0.00000 | rid = 0.00000 | P = 0.00000\n",
      "\n",
      "RISULTATI Carpi:\n",
      "AtC    = nan ± nan\n",
      "BtC    = nan ± nan\n",
      "KdtC   = nan ± nan\n",
      "Chi²   = 0.00000 | rid = 0.00000 | P = 0.00000\n",
      "\n",
      "RISULTATI York:\n",
      "AtY    = nan ± nan\n",
      "BtY    = nan ± nan\n",
      "KdtY   = nan ± nan\n",
      "Chi²   = 0.00000 | rid = 0.00000 | P = 0.00000\n"
     ]
    }
   ],
   "source": [
    "print(\"RISULTATI CON ERRORE STRUMENTALE (cronometro):\")\n",
    "print(f\"Media pesata K  = {KdtM:.5f} ± {uKdtM_fin:.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI OLS:\")\n",
    "print(f\"Atols  = {Atols:.5f} ± {uAtols_fin:.5f}\")\n",
    "print(f\"Btols  = {Btols:.5f} ± {uBtols_fin:.5f}\")\n",
    "print(f\"Kdtols = {Kdtols:.5f} ± {uKdtols_fin:.5f}\")\n",
    "print(f\"Chi²   = {chi2_tols:.5f} | rid = {chi2_tols/GdLt:.5f} | P = {chi2.cdf(chi2_tols, GdLt):.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI Carpi:\")\n",
    "print(f\"AtC    = {AtC:.5f} ± {uAtC_fin:.5f}\")\n",
    "print(f\"BtC    = {BtC:.5f} ± {uBtC_fin:.5f}\")\n",
    "print(f\"KdtC   = {KdtC:.5f} ± {uKdtC_fin:.5f}\")\n",
    "print(f\"Chi²   = {chi2_tC:.5f} | rid = {chi2_tC/GdLt:.5f} | P = {chi2.cdf(chi2_tC, GdLt):.5f}\")\n",
    "\n",
    "print(\"\\nRISULTATI York:\")\n",
    "print(f\"AtY    = {AtY:.5f} ± {uAtY_fin:.5f}\")\n",
    "print(f\"BtY    = {BtY:.5f} ± {uBtY_fin:.5f}\")\n",
    "print(f\"KdtY   = {KdtY:.5f} ± {uKdtY_fin:.5f}\")\n",
    "print(f\"Chi²   = {chi2_tY:.5f} | rid = {chi2_tY/GdLt:.5f} | P = {chi2.cdf(chi2_tY, GdLt):.5f}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
