\documentclass[12pt]{book} 
\usepackage[strings]{underscore}
\usepackage{adjustbox}
\usepackage{amsfonts}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage[italian]{babel}
\usepackage{caption}
\usepackage{fancyhdr}
\usepackage{float}
\usepackage{subfig}
\usepackage{geometry} 
\usepackage{graphicx} 
\usepackage{hyperref} 
\usepackage{mathtools}
\usepackage{minted}
\usepackage{url}
\usepackage{xcolor} 
\usepackage{yhmath}
\usepackage[section]{placeins}
\usepackage{xurl}
 



\theoremstyle{definition}
\newtheorem{definizione}{Definizione}[chapter]
\newtheorem{osservazione}{Osservazione}[chapter]
\newtheorem{esempio}{Esempio}[chapter]
\theoremstyle{plain}
\newtheorem{teorema}{Teorema}[chapter]
\newtheorem*{teorema*}{Teorema}
\newtheorem{proposizione}{Proposizione}[chapter]
\newtheorem{lemma}{Lemma}[chapter]
\newtheorem{nota}{Nota}[chapter]

\DeclareMathOperator{\N}{\mathbb{N}}
\DeclareMathOperator{\R}{\mathbb{R}}
\DeclareMathOperator{\C}{\mathbb{C}}
\DeclareMathOperator{\U}{\mathbb{U}}
\DeclareMathOperator{\V}{\mathbb{V}}

\DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
\DeclarePairedDelimiter{\norma}{\lVert}{\rVert}
\DeclarePairedDelimiter{\SPH}{\langle}{\rangle_{\HS}}
\DeclarePairedDelimiter{\Kn}{K_{n}(}{)}
\DeclarePairedDelimiter{\Km}{K_{m}(}{)}

\pagestyle{plain}

\begin{document}
%QUESTO SERVE PER LA NUMERAZIONE DELLE EQUAZIONI
\renewcommand{\theequation}{\arabic{equation}}

\thispagestyle{empty}

\vskip-2cm 
\centerline{ \includegraphics[width=5cm]{LOGO_Ufficiale_Unipd_2023.png} }

{\bf 
\vskip0.5cm

\centerline{\Large{Universit\`a degli Studi di Padova}}

\centerline{\rule{4cm}{0.4pt} }
	
\vskip1cm
\uppercase{
\centerline{\large{Dipartimento di Matematica ``Tullio Levi-Civita''}}
\vskip0.5cm
}


\vskip0.5cm
\centerline{\large{Corso di Laurea Triennale in Matematica }}


\vskip1.5cm

\centerline{{\textbf  Tesi di Laurea}}
\vskip1cm
\centerline{\large{\textbf Implementazione in Python di un algoritmo per la cubatura}}



\centerline{\large{\textbf numerica su elementi poligonali con un lato curvo}}}

\bigskip 

\vskip1.5cm
\noindent
\large{Relatore: } \hfill\large{Laureando: Giovanni Traversin   }\\
\large{Prof.  
Alvise Sommariva}  \hfill\large{Matricola: 2002232 }\\

\vskip0.3cm
\noindent \large{Correlatrice: } \\
\large{Dott.ssa Laura Rinaldi}

%\vskip1cm

  \vskip0.6cm
\noindent

\centerline{\rule{12cm}{0.4pt} }
\centerline{ Anno Accademico 2024/2025}

\vskip0.1cm
\centerline{19/09/2025}

%\centerline{ {data XX/XX/202X}}


\newpage
\thispagestyle{empty}
\mbox{}
\newpage

\tableofcontents

\newpage
\thispagestyle{empty}
\mbox{}
\newpage


\chapter*{Introduzione}
\addcontentsline{toc}{chapter}{Introduzione}  
\thispagestyle{empty}

In questa tesi consideriamo il problema di implementare in {\sc{Python}} alcune formule di quadratura algebriche su elementi poligonali con un lato curvo.

Questo problema \`e stato discusso da E. Artioli, A. Sommariva, M. Vianello in {\it{Algebraic cubature on polygonal elements with a circular edge}}, dove gli autori hanno introdotto un algoritmo che determina una formula algebrica con grado di esattezza prefissato, nodi nel dominio e pesi positivi. Gli ingredienti utilizzati sono formule, determinate via {\it linear blending}, applicate su domini poligonali e di tipo circolare. Le formule di quadratura sono state poi utilizzate all'interno di un codice per {\it{virtual elements}} al fine di risolvere certi problemi alle derivate parziali.

I codici presenti nella sopracitata pubblicazione sono stati scritti in {\sc{Matlab}}. Lo sforzo di questa tesi \`e di tradurli in {\sc{Python}}, facendo attenzione che i risultati ottenuti nei due linguaggi siano numericamente equivalenti, nonostante in alcune parti si utilizzino routines diverse.

Nel primo capitolo, di natura introduttiva, vengono specificati i dettagli principali sviluppati in {\cite{ASV}}, il {\it{linear blending}} e la tecnica di {\it{compressione}} di formule di quadratura.

Nel secondo capitolo descriviamo i codici utilizzati, come pure le difficolt\`a incontrate nella traduzione.

Nel capitolo finale paragoniamo i codici open-source {\sc{Matlab}} con quelli {\sc{Python}}, al fine di mostrare che sono numericamente equivalenti, mediante tests sia su nodi e pesi ottenuti, sia sulla qualit\`a di queste formule in ambienti diversi.

La conclusione \`e che, numericamente, i codici sono effettivamente equivalenti e i tempi di calcolo sono in genere paragonabili. Nel caso compresso, le formule possono essere diverse, ma sempre con il grado di esattezza prefissato.


\chapter{Costruzione della formula di cubatura}
    {In questo capitolo verranno descritti i processi e i teoremi mediante i quali \`e possibile sviluppare una formula di cubatura algebrica per una funzione definita su un elemento poligonale circolare. Questa parte si basa sul lavoro {\cite{ASV}} e ne descriviamo per completezza i dettagli.}

\section {Definizione e costruzione di un elemento poligonale circolare}
Poich\'e il dominio di integrazione \`e un elemento poligonale circolare, altres\`i detto {\it "poligono circolare"}, si procede innanzitutto col descrivere la sua costruzione.

Una tale figura piana si ottiene partendo da un poligono convesso $\mathcal{P}$ qualsiasi avente $P_1, \dots, P_\ell$ come vertici ordinati in senso antiorario. Il poligono circolare viene costruito sostituendo il segmento $\overline{P_\ell P_1}$ di $\mathcal{P}$ con l'arco di circonferenza $\wideparen{P_\ell P_1}$ che interseca il poligono unicamente in $P_1$ e $P_\ell$. Denominiamo in seguito con $\mathcal{C}$ il centro della circonferenza di raggio $\textit{r}$ di cui il segmento $\wideparen{P_\ell P_1}$ \`e arco.

Un dominio $\Omega$ con queste caratteristiche viene solitamente ottenuto in seguito all’unione o alla differenza tra un poligono convesso e un disco ad esso sovrapposto. Nel primo caso, in cui l'arco \`e esterno al poligono, il poligono circolare risulta convesso, mentre nel secondo caso, in cui l'arco \`e interno al poligono, concavo.


{Siccome per $\ell \in \{2,3\}$ il dominio di integrazione coincide rispettivamente con un generico  segmento o settore circolare (cf. \cite{FSV}), si considerer\`a senza perdita di generalit\`a $\ell \geq 4$.}

\begin{figure}[h!]
    \centering
    \includegraphics[width=6cm]{PC1.png}
    \qquad
    \includegraphics[width=7cm]{PC2.PNG.png} 
    \caption{Esempi di poligono circolare rispettivamente convesso e concavo}%
    \label{fig:P_C_1_2 }%
\end{figure}




\section {Suddivisione del dominio}
{Per semplificare la costruzione della formula di cubatura, vedremo in seguito che \`e conveniente suddividere il dominio $\Omega$ in pi\`u sottodomini disgiunti. In questa sezione si descriver\`a la suddivisione adottata nei programmi in calce, la quale ripercorre a sua volta i codici implementati in \cite{SC}.

Innanzitutto si nota che, qualora il poligono circolare sia convesso, \`e immediata la suddivisione di $\Omega$ nel poligono $\mathcal{P}$ di $\ell$ lati e nel relativo segmento circolare associato.

Differentemente, nei casi in cui la parte circolare $\wideparen{P_{\ell}P_1}$ risulta concava rispetto al poligono convesso $\mathcal{P}$, la suddivisione non \`e altrettanto banale.}

{Siano ($ r_k , \theta_k$) le coordinate polari dei punti $P_k$ per $k \in \{1,\dots,\ell\}$, dove $r_k$ \`e la distanza tra $P_k$ e $\mathcal{C}$ e  $[\theta_1, \theta_\ell] \subset [0, 2\pi)$. Da tale costruzione risulta necessariamente che $r_1 = r_\ell = r$. Senza perdere di generalit\`a, si considerer\`a $\theta_1 \leq \theta_\ell$.}

{Si formino innanzitutto due insiemi in cui raggruppare tutti i vertici consecutivi di $\mathcal{P}$ che non ricadono all'interno di $(\theta_1, \theta_\ell)$.
I vertici raccolti a partire da $P_1$ andranno a formare l'insieme $\{P_1,..., P_{\ell_1} \}$, mentre quelli consecutivi rispetto a $P_{\ell}$ daranno origine all'insieme $\{ P_{\ell_2},..., P_\ell \}$ con ${\ell_1}<{\ell_2}$. Poich\'e $\mathcal{P}$ \`e convesso, questi due insiemi raggruppano tutti i vertici esterni all'angolo $(\theta_1, \theta_\ell)$.

Si raccolgano poi all'interno dell'insieme $\{ P_{\ell_1 + 1} ,..., P_{\ell_2 - 1} \}$ tutti i vertici rimanenti, ovvero quelli che si trovano all'interno dell'area tra $\theta_1$ e $\theta_\ell$.}

\begin{figure}[t]
    \centering
    \includegraphics[width=0.6\linewidth]{dhdhfh.PNG}
    \caption{Un poligono curvilineo e la suddivisione in sottodomini semplici da trattare per quanto riguarda la cubatura numerica.}
    \label{fig:enter-label}
\end{figure}


{A partire dai vertici in $\{ P_{\ell_1 + 1} ,..., P_{\ell_2 - 1} \}$ \`e possibile definire una successione di quadrilateri circolari $Q_i$ con $i \in \{ \ell_1 + 1 ,..., \ell_2 - 2 \}$, la cui frontiera \`e determinata dai segmenti $\overline{P_k^*P_k}$, $\overline{P_kP_{k+1}}$, $\overline{P_{k+1}P_{k+1}^*}$ e dall'arco $\wideparen{P_k^*P_k}$. Di questi, va riservata particolare attenzione agli elementi $Q_{\ell_1}$ e $Q_{\ell_2}$ (delimitati rispettivamente il primo da 
$\overline{P_1P_{\ell_1}}$, $\overline{P_{\ell_1}P_{\ell_1+1}}$, $\overline{P_{\ell_1+1}P_{\ell_1+1}^*}$ e $\wideparen{P_{\ell_1+1}^*P_1}$ e il secondo da 
$\overline{P_{\ell_2-1}^*P_{\ell_2-1}}$, $\overline{P_{\ell_2-1}P_{\ell_2}}$, $\overline{P_{\ell_2}P_\ell}$ e $\wideparen{P_{\ell}P_{\ell_2-1}^*}$)
i quali \`e preferibile siano ridotti a dei settori circolari o ancora meglio, quando possibile, a dei segmenti.

Dalla suddivisione compiuta \`e immediato che la chiusura dell'insieme $\Omega \ \setminus  \ \bigcup^{\ell_2}_{k = \ell_1} \mathcal{Q}_k$ coincida al pi\`u con due poligoni convessi.}







\subsection{Casi convessi particolari}
{\`E interessante notare come la suddivisione di $\Omega$ appena descritta possa portare a diverse forme di casi peculiari a seconda del numero di elementi all'interno di ciascun insieme di vertici.

Si supponga ad esempio che uno o entrambi tra $\{ P_1,\dots, P_{\ell_1} \}$ e $\{ P_{\ell_2},\dots, P_\ell \}$ sia formato da un singolo punto o al pi\`u da una coppia di punti. In tal caso la chiusura di $\Omega \ \setminus  \ \bigcup^{\ell_2}_{k = \ell_1} \mathcal{Q}_k$, a seconda che l'insieme con al pi\`u due punti sia uno solo o entrambi, risulterebbe vuota o coinciderebbe con un solo poligono convesso. Oppure si supponga che $\{ P_{\ell_1 + 1} ,\dots, P_{\ell_2 - 1} \}$ risulti vuoto. O ancora che il poligono circolare in questione non sia altro che un segmento circolare, ovvero un poligono circolare in cui i vertici $P_2,\dots,P_{\ell-1}$ sono collassati sul segmento congiungente $P_1 $ e $ P_\ell$.
Nonostante ci\`o, comunque la suddivisione operata \`e valida ed \`e sempre in grado di restituire al pi\`u due poligoni convessi.}

{\`E inoltre interessante osservare come l'intera struttura della suddivisione si basi sulla convessit\`a di $\mathcal{P}$. Questo perch\'e, qualora all'interno di un poligono circolare $\mathcal{P}$ fosse non convesso, basterebbe suddividere preliminarmente questo in due poligoni convessi disgiunti per essere poi in grado di applicare ugualmente la formula di divisione del dominio scelta.}



\section{Cubatura algebrica tramite unione ad arco}
{Dopo aver definito la suddivisione da applicare al dominio $\Omega$, proseguiamo allo sviluppo di una formula di cubatura sullo stesso. In particolare si richiede che tale formula abbia grado di esattezza algebrica (ADE) pari ad $n$ e sia nella forma}
\begin{equation} \label{eq:arcblendcub}
 \int \int_\Omega p(x,y) \ dxdy = \sum_{i=1}^{M_n} \ \omega_i \ p(x_i,y_i), \ \forall \ p \in \mathbb{P}_n ^2 \ , 
\end{equation}
{dove $\mathbb{P}_n ^2$ si riferisce allo spazio dei polinomi algebrici in due variabili di grado al pi\`u $n$.

Grazie alla propriet\`a additiva degli integrali, per definire una formula con queste propriet\`a \`e sufficiente fornirne una equivalente ristretta alle componenti distinte in cui si \`e diviso $\Omega$.



\subsection {Costruzione della formula di cubatura sulle singole componenti}
{\vspace{0.1cm}}
{Per quanto riguarda la chiusura di $\Omega \ \setminus  \ \bigcup^{\ell_2}_{k = \ell_1} \mathcal{Q}_k$, nei casi in cui $\wideparen{P_\ell P_1}$ \`e convesso, la formula di quadratura \`e immediata. Nei poligoni convessi infatti, dopo aver suddiviso ciascun poligono in $m-2$ triangoli, dove $m$ indica il numero di lati del poligono, una qualsiasi formula di cubatura del simplesso con le coordinate baricentriche ha le caratteristiche richieste. Per citarne alcuni esempi, formule di questo tipo sono le formule di Stroud, la cui cardinalit\`a \`e $(n+1)^2/4$ e in generale, a pari ADE, non \`e minima. Per formule di questa natura, si ricorda che un limite dal basso \`e stato fornito anche da M\"{o}ller per ADE non troppo elevati. In particolare, tramite le sue formule, \`e possibile sapere a priori il numero di nodi richiesti da una formula, come evidenziato in \cite{Cools} e \cite{Cools2}.

Nello specifico, in questa tesi, si \`e scelto di seguire i codici illustrati ed implementati in \cite{SC} anche per scegliere quali formule di cubatura usare in questo caso.}

{Invece, per quanto riguarda i quadrilateri circolari $Q_k$, per ottenere una formula di cubatura con ADE = $n$, si adatter\`a ai poligoni circolari quanto trattato in \cite{FSV} a proposito della {\it quadratura subperiodica trigonometrica gaussiana} e della tecnica detta {\it arc blending}.

Sia $Q$ un quadrilatero circolare qualsiasi. Esso pu\`o essere riscritto come la trasformazione bilineare algebrico-trigonometrica di un rettangolo nella forma
\begin{equation} \label{eq:Q}
\mathcal{Q} = \{ (x,y) = \sigma (t,\theta) = tP(\theta) + (1 - t)Q(\theta) \ \ \ \ \ \  \ (t,\theta) \in [0,1] \times [\alpha,\beta] \}
\end{equation}
dove $P(\theta)$ e $Q(\theta)$ sono curve parametriche con parametro di grado 1.

In particolare esse hanno formula
\begin{equation}\label{eq:PthetaQtheta}
P(\theta) = A_1\cos (\theta ) + B_1\sin (\theta )+ C_1, \quad Q(\theta) = A_2\cos (\theta ) + B_2\sin (\theta )+ C_2, 
\end{equation}
con $A = (A_1,A_2)$, $B = (B_1,B_2)$, $\theta \in [\alpha,\beta]$ sotto le condizioni: $\alpha - \beta \leq \pi$ e $A_i,B_i,C_i \in \mathbb{R}^2$ per $i \in \{1,2\}$.


Questo tipo di scrittura viene chiamata {\it unione lineare di archi subperiodici} (o {\it arc blending}), dal momento che gli angoli in essa considerati appartengono sempre a un sottointervallo del periodo. Tramite questo tipo di trasformazioni, \`e possibile ottenere svariate sezioni di dischi o di domini analoghi legati agli archi di circonferenze o ellissi, come trattato in \cite{FSV} e \cite{FV}}

{Si reidentifichino dunque i vertici di $Q$, ordinati consecutivamente tramite coordinate cartesiane, ponendo $V_i = (\xi_i,\eta_i)$ per $i \in \{1,2,3,4\}$. Risulta che $\wideparen{V_1 V_4}$ coincide con l'arco di circonferenza di centro $C = (x_0,y_0)$ e raggio $r$ di cui $\alpha$ e $\beta$ sono le coordinate angolari rispettivamente di $V_1$ e $V_4$ rispetto a $C$.
Poich\'e non vi \`e perdita di generalit\`a, si assumer\`a $\beta - \alpha < \pi$.

Definiamo inoltre le variabili $s$ e $\phi$ nel seguente modo:
\[s = \sin \left(  \frac{\beta \ - \  \alpha}{2} \right) \ \ \ \ \ \ \ \ \ \ \ \ \ \
\phi = \frac{\beta \ + \ \alpha}{2}.\]

\`E immediato osservare dalle definizioni date che per definire un quadrilatero circolare come trasformazione bilineare \`e sufficiente porre per \eqref{eq:Q} e \eqref{eq:PthetaQtheta}
\[A_1 = (r,0), \ \ \ \ \ \ \ \ \ \ B_1 = (0,r) ,\ \ \ \ \ \ \ \ \ \ C_1 = C = (x_0,y_0)\]
\begin{equation} \label{eq:ABC12}
 A_2 = \frac{\sin ( \phi )}{2s} (V_3 - V_2), \ \ \ \ \ \ B_2 = \frac{\cos ( \phi )}{2s} (V_3 - V_2), \ \ \ \ \ \ C_2 = \frac{1}{2} (V_3 + V_2).
 \end{equation}}

{In questa notazione, $A_1$, $B_1$ e $C_1$ corrispondono alla rappresentazione polare dell'arco $\wideparen{V_1 V_4}$, mentre $A_2$, $B_2$ e $C_2$ sono una rappresentazione trigonometrica biettiva del segmento $\overline{V_2 V_3}$ lungo l'intervallo $[\alpha,\beta]$ parametrizzata da}
\[\frac{V_3 + V_2}{2} + \tau \frac{V_3 + V_2}{2} \ con \ \ \ \tau \in [-1,1],\]
\[\tau = \sin \left( \frac{\theta - \phi}{s} \right) =  \frac{\sin ( \theta )\cos ( \phi ) - \cos ( \theta )\sin ( \phi )}{s}\ \ e \ \ \ \theta \in [\alpha,\beta]. \]

{Poich\'e all'interno di $\mathcal{Q}$ lo jacobiano $J \sigma$ non varia mai di segno e la stessa funzione $\sigma$ \`e iniettiva se e solo se lo sono $P(\theta)$ e $Q(\theta)$ (o equivalentemente se qualsiasi coppia di segmenti $tP(\theta_1) + (1-t)Q(\theta_1)$ e $ tP(\theta_1) + (1-t)Q(\theta_2)$ con $\theta_1,\theta_2 \in [\alpha,\beta]$ si interseca solo ad una delle estremit\`a), come osservato in \cite{FSV}, possiamo scrivere $\forall \ p \in \mathbb{P}_n ^2$}

\begin{equation} \label{eq:JacInt}
\int \int_\Omega p(x,y) \ dxdy = \int \int_{[0,1] \times [\alpha, \beta]} p(\sigma(t,\theta))[\pm \det(J\sigma(t,\theta))] \ dtd\theta   
\end{equation}


{a seconda del segno del Jacobiano.

Infatti, dal momento che $ (p  \circ \sigma) \in \mathbb{P}_{n} \otimes \ 
\mathbb{T}_{n}$ e $\det(J\sigma) \in \mathbb{P}_{1} \otimes \ 
\mathbb{T}_{2} $ si ha che $ (p  \circ \sigma)[\pm \det(J\sigma)] \in \mathbb{P}_{n+1} \otimes \ \mathbb{T}_{n+2}$, in cui $\mathbb{P}_n$ e $\mathbb{T}_{n}$} sono gli spazi dei polinomi algebrici e trigonometrici di grado al pi\`u $n$.

{Questa struttura tensoriale \`e ci\`o che porta a propendere per l'utilizzo di una formula di quadratura prodotto via quadratura Gaussiana algebrica, purch\'e nei sottointervalli del periodo sia possibile sviluppare una buona formula di quadratura trigonometrica.
Tale propriet\`a viene formalizzata nella seguente proposizione sui {\it sottoperiodi trigonometrici della formula di quadratura Gaussiana}:


\newtheorem{proposition}{Proposizione}
\begin{proposition}
Siano ($\xi _j, \lambda _j$), $1 \leq j \leq k+1$, rispettivamente i nodi e i pesi positivi della formula di quadratura algebrica Gaussiana per la funzione peso


\[ w (x) = \frac{2 \sin (\omega /2)}{\sqrt{1-x^2 \sin ^2 (\omega /2)}} \ \ \ x \in (-1,1), \ \omega \in (0,\pi] \].


Allora dati $0 < \beta - \alpha \leq 2 \pi$, per la seguente formula trigonometrica di quadratura Gaussiana vale l'equivalenza
\begin{equation} \label{eq:INTab}
\int _\alpha ^\beta  f ( \theta ) \ d \theta = \sum _{j=1} ^ {k+1} \lambda_j f(\theta_j) \ , \ \forall \ f \in \mathbb{T}_k \ ,
\end{equation}
all'interno della quale impostiamo le costanti $\omega, \phi, \theta _j$ ai seguenti valori per $1 \leq j \leq k+1$:
\[ \omega = (\beta - \alpha)/2, \ \ \ 
\phi = (\beta + \alpha)/2, \ \ \ 
\theta_j = \phi + 2 \arcsin ( \xi_j \sin(\omega)). \ \ \  \]

\end{proposition}
La validit\`a della proposizione \`e dimostrata in \cite{FV}, mentre alcune delle sue applicazioni sono illustrate in \cite{FSV}.
A partire da questa proposizione \`e poi possibile svilupparne una seconda, ristretta alle formule prodotto di tipo gaussiano sui quadrilateri circolari.


\newtheorem{proposition2}{Proposizione}
\begin{proposition}
Sia $\mathcal{Q}$ un quadrilatero circolare nella forma \eqref{eq:Q}-\eqref{eq:ABC12}. Allora, definiti $\{\theta_j,\lambda_j\}$ rispettivamente come i nodi e i pesi della formula trigonometrica gaussiana con grado di precisione n+2 su $[\alpha,\beta]$ e $\{ t^GL _i, w^GL _i  \}$ come i nodi e i pesi di Gauss-Legendre della formula con grado di precisione n+1 su [0,1],
\begin{equation} \label{eq:FunzReq}
\int\int _\mathcal{Q} p(x,y) \ dxdy = \sum _{j=1} ^{n+2} \sum _{i=1} ^{ \lceil \frac{n+1}{2} \rceil} W_{ij} \ p(x_{ij}, y_{ij}), \ \forall p \in \mathbb{P}_n ^2 \ ,
\end{equation}
in cui
\begin{equation} \label{eq:CondizReq}
(x_{ij},y_{ij}) = \sigma (t_i ^{GL} , \theta_j ), \ 0 < W_{ij} = |\det (J \sigma(t_i ^{GL} , \theta_j )|w_i ^{GL} \lambda_j \ .
\end{equation}
\end{proposition}



La dimostrazione segue direttamente dalla prima proposizione e da \eqref{eq:JacInt}, mentre la sua formulazione nel caso generale viene esaminata pi\`u approfonditamente in \cite{FSV}.
In questo modo, su ciascuna delle componenti in cui \`e stato suddiviso il dominio $\Omega$, convesso o meno, si \`e definita una formula di cubatura del tipo richiesto.}


\subsection{Compressione della formula di cubatura}
{\vspace{0.1cm}}

{La formula di quadratura definita nella sezione precedente ha cardinalit\`a $(n+2) \lceil \frac{n+1}{2}\rceil = \frac{n^2}{2} + \mathcal{O}(n)$ e sar\`a il punto di partenza per definire una seconda formula ad essa equivalente di cardinalit\`a inferiore.
Dalle osservazioni sul teorema di Tchakaloff in \cite{SV} \`e noto che una formula di cubatura con ADE = $n$ e cardinalit\`a non inferiore a 
\begin{equation} \label{eq:N}
N =  dim(\mathbb{P}_{n}^2) = \binom{n+2}{2} = \frac{(n+1)(n+2)}{2}
\end{equation}
pu\`o essere sempre compressa in una formula con le stesse propriet\`a i cui nodi sono un sottoinsieme ricalibrato degli originali e la cui cardinalit\`a non \`e mai superiore ad $N$.

Questo studio si concentrer\`a principalmente sul caso discreto bivariato, ma \`e importante specificare che questi risultati hanno una validit\`a molto pi\`u generale per ogni misura discreta o continua e in qualsiasi dimensione, come mostrato nella trattazione del Teorema di Tchakaloff in \cite{SV}. Quanto segue descrive la compressione della formula definita nella sezione precedente, ripercorrendo il processo di costruzione in \cite{PSV}. Tale compressione \`e valida per ogni misura discreta e in qualsiasi dimensione.}

{Si consideri allora una formula di cubatura definita come in \eqref{eq:arcblendcub} su un dominio $\Omega \subset \mathbb{R}$ di cardinalit\`a $M = M_n > N$, in cui $n$ \`e il grado di precisione. Si definiscano $X = \{ (x_i, y_i) \}$ e W = $\{(w_i)\}$ gli insiemi contenenti rispettivamente gli $M_n$ nodi e pesi, sia {$p_1, \dots , \ p_n$} una base per $\mathbb{P}_n ^2$ e si calcoli a partire da tali elementi la corrispondente matrice di Vandermonde
\begin{equation} \label{eq:VanVan}
V = V_n (x) = [v_{ij}] = [p_j (x_i, y_i)] \in \mathbb{R}^{M \times N}.
\end{equation}
A partire dalla trasposta di questa matrice possiamo impostare il seguente sistema di uguaglianze dei momenti sotto vincoli di non negativit\`a
\begin{equation} \label{eq:PLVandermonde}
 V^t u = b = V^t w \ ,\  \ u\geq 0  .
\end{equation}
Per questo sistema di uguaglianze, la ricerca di una formula di cubatura polinomialmente esatta con $X$ come supporto \`e equivalente alla ricerca di una soluzione sparsa con al pi\`u $M$ valori non negativi.

Come si pu\`o vedere in \cite{Caratheodory}, grazie al teorema di Caratheodory per le combinazioni coniche in dimensioni finite applicato alle colonne di $V^t$, una tale soluzione sparsa non solo \`e garantita, ma in generale non \`e neppure unica 
e il numero di valori non negativi non \`e mai superiore ad $N$.

Per un problema come \eqref{eq:PLVandermonde}, la letteratura matematica ha a sua disposizione svariati studi, quali \cite{PSV}, \cite{SV} e \cite{Tcherny}, che descrivono pi\`u di un metodo attendibile per la sua risoluzione.}

{Una possibile strada consiste nel considerare il sistema di equazioni come un programma lineare
\[ \begin{cases}
\min  c^t u \\ V^t u = b \ , \ \ u \geq 0
\end{cases}\]}
e risolverlo tramite algoritmi di ottimizzazione quali il metodo del simplesso e delle due fasi. 

{Nel costruire questo programma, $u$ rappresenta il vettore incognito dei pesi, $V^t u = b$ sono i vincoli di esattezza forniti dalla matrice di Vandermonde \eqref{eq:VanVan} e $c^t$ \`e il vettore dei costi della funzione obiettivo generato artificialmente in modo da essere linearmente indipendente dai vincoli.}

Sotto questa luce, la validit\`a delle osservazioni fatte precedentemente risulta immediata. I vincoli identificano come regione delle soluzioni ammissibili un politopo di $\mathbb{R}^M$ sempre non vuoto, dal momento che $b = V^tw \geq0$, e dunque il sistema ha sempre almeno una soluzione ammissibile. Tuttavia, dal momento che il politopo \`e limitato, segue anche che esiste sempre almeno una soluzione ottima con almeno $M-N$ componenti uguali a 0 che l'algoritmo del simplesso \`e sicuramente in grado di trovare.
Infine, il vettore $c$ dei coefficienti della funzione obiettivo \`e costruito in modo da essere linearmente indipendente dalle righe di $V^t$, dunque \`e possibile sapere a priori che tale soluzione sar\`a non costante e non banale}.

{Eventualmente, qualora non ci si volesse discostare troppo dal teorema di Tchakaloff, \`e anche possibile considerare il sistema come un problema di ottimizzazione quadratica. 
In questo caso, esso coincide con un programma lineare di ottimizzazione convessa per i minimi quadrati non negativi (NNLS - NonNegative Least Square) nella forma
\begin{equation} \label{eq:NNLSu}
u^* : || V^t u^* - b ||_2 = \min_{u \geq 0} || V^t u - b ||_2 \  \end{equation}
in cui $u^*$ pu\`o essere calcolato tramite il {\it Metodo di ottimizzazione di Lawson-Hanson}, trattato in \cite{LawHan}, il quale \`e particolarmente adatto per la ricerca di soluzioni sparse.}

{Si consideri adesso una soluzione sparsa $u$ per \eqref{eq:PLVandermonde} e la successione di indici $i_k$, con $k \in \{1, \dots , m \leq N < M\}$, tali che $u_{i_k} \neq 0$. \`E possibile riscrivere la formula \eqref{eq:arcblendcub} nella forma compressa ricercata
\begin{equation} \label{eq:comprex}
\int \int_\Omega p(x,y) \ dxdy = \sum_{i=1}^{M} \ \omega_i \ p(x_{i_k},y_{i_k}) = \sum_{k=1}^{m} u_{i_k} p(x_{i_k}, y_{i_k}), \ \forall \ p \in \mathbb{P}_n ^2.
\end{equation}

{In virt\`u dei risultati in \cite{PSV}, possiamo dire di aver operato una valida compressione di Caratheodory-Tchakaloff alla formula di cubatura per poligoni circolari iniziale definita in \eqref{eq:FunzReq} e \eqref{eq:CondizReq}.

Nel prossimo capitolo verranno mostrate tramite tabelle numeriche le differenze nelle tempistiche e nei risultati degli integrali a seconda che si usi la formula compressa o meno e a seconda che si usi il programma {\sc{Matlab}} o {\sc{Python}}.}





\chapter{Traduzione da {\sc{Matlab}} a {\sc{Python}}}
{In questo capitolo si descriveranno la traduzione e il funzionamento degli algoritmi gi\`a implementati in {\sc{Matlab}} in \cite{SC} sulla base dei teoremi visti nel Capitolo 1. A ci\`o seguiranno una serie di esempi e risultati numerici per mettere a confronto l'implementazione in {\sc{Python}} con quella in {\sc{Matlab}}.

Tutti i codici {\sc{Python}} essenziali a questa tesi sono stati inseriti in calce.


\section{Gli algoritmi principali}
{Durante la traduzione, si \`e cercato di sviluppare gli algoritmi in modo da poterli utilizzare anche singolarmente in ambienti esterni alla funzione finale {\tt polygcirc}. Per tale ragione, e poich\'e spesso i programmi implementati si appoggiano alla libreria {\tt{numpy}}, gli elementi che \`e necessario definire come vettori vengono resi tali ogni volta all'interno del programma. In questo modo i valori possano di volta in volta venire dati in input alle varie funzioni sia in forma di liste che in forma di vettori.


}



\subsection{Polygcirc}
{Trattasi del programma principale, al quale sono finalizzate tutte le altre funzioni implementate in questa tesi.

Al suo interno si ripercorrono fedelmente tutti i vari passaggi descritti nel Capitolo 1 per arrivare ad una formula di cubatura compressa per i poligoni circolari con ADE = $n$.

Dati in input la lista dei vertici della figura ordinati in senso antiorario, gli estremi, il centro ed il raggio del segmento circolare e la convessit\`a o concavit\`a dell'arco, la funzione produce i nodi e i pesi della formula di cubatura \eqref{eq:arcblendcub} tramite le funzioni {\tt circtrap} e {\tt polygauss}. A tal proposito, come visto nella sezione 1.3.1, il programma opera in maniere differenti a seconda che il poligono circolare sia concavo o convesso.

Infine, come nella sezione 1.3.2, i nodi e i pesi trovati vengono compressi tramite la funzione {\tt comprexcub}.

Il programma restituisce poi in output i nodi e i pesi sia originali che compressi, sotto forma di matrici di tre colonne in cui la prima e la seconda colonna contengono ascisse e ordinate dei nodi, mentre la terza i pesi ad essi associati

{{Poich\'e per\`o in {\sc Matlab}, a seconda delle variabili richieste in output, i programmi possono procedere o meno al calcolo effettivo dei parametri definiti all'interno dei codici, mentre invece in {\sc Python} vengono sempre calcolati tutti, al programma in {\sc Python} sono stati aggiunti una condizione {\tt if} finale ed una {\tt flag} opzionale in input, per consentire una miglior valutazione dei tempi di calcolo tra i due linguaggi. In particolare, la {\tt flag} \`e collegata direttamente ed esclusivamente all'ultima condizione {\tt if}, e, qualora non venga specificata, \`e preimpostata per assumere il valore {\tt True}. Tali aggiunte consentono di non calcolare necessariamente i nodi e i pesi compressi per la formula di cubatura e di distinguere tra i tempi necessari al calcolo dei nodi e dei pesi compressi e i tempi necessari per calcolare solo quelli gaussiani. Tali modifiche sono state fondamentali per poter raccogliere i dati in \ref{tab:1.4}, \ref{tab:3.4} e \ref{tab:4.4}.}}

\subsection{Polygauss}
{Questa funzione permette il calcolo di nodi e pesi di tipo gaussiano su un poligono qualsiasi. All'interno di {\tt polygcirc}, essa produce nodi e pesi per tutte le componenti poligonali prive di lati curvi.

Come per la sua controparte {\sc{Matlab}}, questa funzione richiede che i lati del poligono forniti in input siano dati come lista di vertici consecutivi ordinati in senso antiorario, di cui il primo coincide con l'ultimo.

Inoltre, se in input non viene dato anche un rettangolo contenente il poligono circolare, \`e la funzione stessa a produrre il minimo rettangolo contenente l'elemento, per poi procedere al calcolo di nodi e pesi bidimensionali sul dominio tramite operazioni sui nodi monodimensionali ottenuti dalla funzione {\tt cubature\_rules\_1D}. A seconda dell'input dato a tale funzione, questi valori possono venire calcolati tramite le due regole di Fejer, la regola di Clenshaw-Curtis o l'algoritmo di Gauss-Legendre.}

\subsection{Circtrap e gqellblend}
{La formula {\tt circtrap} serve a calcolare nodi e pesi per l'integrazione numerica su tutte quelle componenti del dominio che presentano lati curvi. Queste tendenzialmente sono quadrilateri circolari, anche detti trapezi circolari, da cui il nome {\tt circtrap}. Essa tuttavia non calcola direttamente i pesi, ma piuttosto prende in input i vertici della figura e, in base al centro ed al raggio che generano il lato curvo, trasforma i vertici del quadrilatero circolare in coordinate polari per poi riordinarli in modo da trasformare il dominio di integrazione in un dominio standard, per poi ricavarne effettivamente nodi e pesi tramite {\tt gqellblend}.

Questa seconda funzione calcola i nodi e i pesi per una formula di cubatura gaussiana di tipo prodotto per polinomi bivariati di grado totale $\leq n$ definita su una regione piana ottenuta tramite combinazione convessa di due archi trigonometrici con equazioni parametriche, concordemente a quanto detto nel Capitolo 1 riguardo a \eqref{eq:JacInt}.
Essa sfrutta i codici {\tt gauss} e {\tt r\_jacobi} per ricavare la formula gaussiana sull'intervallo $[0,1]$ e {\tt trigauss} per calcolare la formula trigonometrica gaussiana sull'arco.
In particolare \`e possibile identificare {\tt trigauss} con la formula trigonometrica di quadratura gaussiana e {\tt gqellblend} con la formula di cubatura tramite unioni ad arco, entrambe discusse nella sezione 1.3.1 attenendosi all'implementazione dei codici in \cite{VianelloCodes}.
Dalla combinazione dei risultati ottenuti, {\tt gqellblend} restituisce la variabile {\tt xyw}, una matrice di tre colonne ciascuna rispettivamente per ascisse, ordiate e pesi dei nodi per la formula di cubatura.}


\subsection{Comprexcub}
{In questa funzione, i programmi per la costruzione della matrice di Chebyshev-Vandermonde {\tt chebvand} e {\tt chebpolys} fanno s\`i che una formula di cubatura, data in input sotto forma di nodi e relativi pesi, venga compressa come indicato da Tchakaloff sulla base dei risultati ottenuti in \eqref{eq:comprex}.

In particolare questa funzione ha come obiettivo la risoluzione del problema \eqref{eq:PLVandermonde} discusso nel Capitolo 1, il quale ammetteva pi\`u approcci differenti per essere risolto. Per rispettare tale libert\`a di approccio, al programma pu\`o essere dato come input il parametro {\tt pos} con cui selezionare l'algoritmo risolutivo.

In particolare, se 
\begin{itemize}
\item non viene dato nessun valore a {\tt pos}, il programma risolve automaticamente \eqref{eq:PLVandermonde} come un programma lineare di ottimizzazione convessa per i minimi quadrati non negativi tramite la funzione {\tt optimize.nnls} della libreria {\tt Scipy}, 
\item $pos = 1$ il programma risolve il sistema tramite l'algoritmo di Lawson-Hanson accelerato dalla strategia di selezione a blocco (Deviation Maximization). In particolare l'implementazione dell'algoritmo di Lawson-Hanson utilizzato in questa traduzione, sfrutta il codice implementato in: \url{https://github.com/laura-rinaldi/Cheap_Splinegauss}.
\end{itemize}

In {\sc Matlab} era anche contemplata una terza via risolutiva, tramite risoluzione sparsa di un sistema lineare standard con matrice non quadrata. Purtroppo in {\sc Python}, a parte {\tt optimize.nnls}, i codici per la risoluzione dei sistemi lineari tendono ad evitare approcci che restituiscano soluzioni sparse. Per tale ragione, la libertà di scelta del codice sorgente risulta non completamente replicabile in {\sc Python}.

Coerentemente con quanto detto nel primo capitolo, in base a \cite{PSV}, \cite{SV} e \cite{Tcherny}, questi algoritmi portano tutti a risultati equivalenti.}

\subsection{Demo_polygcirc}
{Si tratta di una funzione grafica e demo che, se da un lato permette di visualizzare ci\`o che fa la formula di cubatura, ovvero il dominio e i nodi di cubatura, dall'altro permette anche di visualizzare i risultati ottenuti tramite {\tt polygcirc}.

Tale funzione ha alcuni poligoni circolari definiti come casi al suo interno e sfrutta la libreria {\tt matplotlib} per restituire una figura rappresentante il poligono circolare relativo al caso scelto, suddiviso come nella sezione 1.2, con in evidenza i nodi compressi di grado $n$ (impostati con n=4).
Eventualmente, qualora ve ne sia necessit\`a, \`e possibile aggiungere ulteriori poligoni circolari all'elenco dei casi forniti dal programma nella sezione {\tt match}.

Oltre alle figure, il programma ritorna anche una tabella di valori che saranno utilizzati ampiamente nel Capitolo 3. \\Questi valori comprendono:
\begin{itemize}
\item il numero dell'esperimento;
\item il grado di precisione algebrica ADE;
\item il tipo di compressione utilizzata in {\tt comprexcub}; 
\item in numero di nodi e pesi trovati dalla formula di cubatura non compressa;
\item il numero di nodi e pesi a seguito della compressione;
\item il numero di pesi negativi, che dovrebbe essere sempre $0$;
\item il tempo di calcolo dei nodi non compressi;
\item il tempo di calcolo dei nodi compressi;
\item l'errore di ricostruzione dei momenti.
\end{itemize}

Per concludere, all'interno del programma sono state apportate alcune modifiche rispetto a {\sc Matlab}, al fine di soddisfare alcune necessit\`a di questa tesi, ovvero
\begin{itemize}
\item la funzione adesso ha dei valori facoltativi in input che permettono di selezionare a piacimento anche il grado di precisione della formula e il tipo di compressione;
\item la tabella dei valori ora presenta anche l'errore di ricostruzione dei momenti calcolato da {\tt comprexcub}; 
\item alcune righe di codice non presenti nel codice sorgente ma utili per la determinazione di alcuni risultati in questa tesi sono state lasciate all'interno del programma sotto forme di commenti. In particolare, quelle sotto la sezione {\it Nodes to copy in Matlab} permettono di stampare nodi e pesi compressi e non in un formato che {\sc Matlab} \`e in grado di leggere come input, mentre quelle contrassegnate come {\it  Plots with sorted weights} permettono di riprodurre dei grafici dei pesi ordinati come quelli che saranno mostrati in seguito in (\ref{fig:2.1}).
\end{itemize}
}




\section{Le differenze tra i linguaggi}
{Le difficolt\`a incontrate durante la traduzione in {\sc{Python}} degli algoritmi implementati in questa tesi sono state principalmente di tipo tecnico e notazionale e non legate alla struttura degli algoritmi. 

Per un miglior parallelismo tra i linguaggi, si \`e deciso di mantenere il pi\`u possibile la sequenzialit\`a dei codici {\sc{Matlab}}, modificando la struttura del programma solo nei punti dove era strettamente necessario a causa delle differenze di impostazione dei linguaggi. I casi pi\`u evidenti in cui si possono notare queste modifiche sono le funzioni 
\begin{itemize}
\item {\tt chebvand}, 
\item {\tt r\_jacobi}, 
\item {\tt polygauss}, 
\end{itemize}
nelle quali non vi sono condizioni interne al programma per la verifica degli input, ma sono gli stessi input che vengono impostati a priori, concordemente alle condizioni in {\sc{Matlab}}, qualora non venissero definiti.

Un ulteriore ostacolo intrinseco nella traduzione tra questi due linguaggi \`e la diversa indicizzazione delle collezioni di elementi. Infatti, in {\sc{Python}}, liste, tuple, dizionari ed elementi di questo genere identificano il proprio primo elemento con l'indice $0$, mentre in {\sc{Matlab}} partono dall'indice $1$. Riguardo a ci\`o, per la maggior parte dei cicli {\tt for} incontrati, si \`e cercato di fare in modo che il ciclo vagliasse fin da subito valori diminuiti di $1$, al fine di mantenere il codice interno al ciclo in {\sc{Python}} il pi\`u simile possibile a quello {\sc{Matlab}}. Si rinuncia a tale approccio solo in alcuni casi specifici, come ad esempio in {\tt chebvand}, in cui i valori vagliati dal ciclo {\tt for} hanno un'effettiva validit\`a numerica all'interno dell'algoritmo.}




\section{Limiti per una IA}
Dopo una prima traduzione manuale dei codici, sono state fatte anche delle prove con alcune IA e programmi di traduzione. Le IA utilizzate principalmente sono state {\textsc{ChatGPT}} e {\textsc{Gemini}}.

Quando il codice {\sc{Matlab}} veniva copiato su {\textsc{Google Colab}} e cominciava ad essere tradotto manualmente, la funzione forniva suggerimenti talvolta affidabili quando si traducevano linee di codice che presentavano una qualche affinit\`a alle precedenti. Tuttavia spesso non apportava le modifiche corrette agli indicatori di posizione per un elemento di una lista, scrivendo {\tt lista(posizione+1)} anzich\'e {\tt lista[posizione]}.

Per quanto riguarda {\textsc{ChatGPT}} invece, sono stati rilevati alcuni risultati interessanti. Per alcune funzioni pi\`u semplici, quali ad esempio 
\begin{itemize}
\item {\tt chebpolys}, 
\item {\tt points2distances}, 
\item {\tt gqellblend}, 
\end{itemize}
le funzioni fornite dall'IA riportavano alcune alterazioni strutturali rispetto al codice originario, ma risultavano nel complesso funzionanti e in alcune occasioni pi\`u rapide delle funzioni tradotte. 

Tuttavia, quando l'IA ha dovuto tradurre funzioni pi\`u intricate, quali {\tt chebvand} o {\tt polygauss}, vi erano delle imperfezioni che rendevano inutilizzabile il codice. Innanzitutto, le funzioni definite precedentemente, quali 
\begin{itemize}
\item {\tt gauss}, 
\item {\tt r\_jacobi},
\item {\tt cubature\_rules\_1D}, 
\end{itemize}
venivano scambiate per dei parametri e aggiunte alle variabili richieste in input, nonostante poi nel codice venissero utilizzate come funzioni.

Dove possibile, l'IA ha sempre tentato di unire i cicli {\tt for} per alleggerire il peso computazionale della funzione. Questo in funzioni come {\tt chebvand} ha compromesso le dimensioni della matrice di Chebyshev-Vandermonde costruita, risultando in un output scorretto. 

Infine, {\textsc{ChatGPT}} ha avuto difficolt\`a ad approcciarsi a quei vettori e a quelle matrici che in {\sc{Matlab}} venivano generate progressivamente. Questo avviene perch\'e in {\sc{Matlab}} vi\`e la possibilit\`a di generare progressivamente una variabile senza averla mai definita prima, mentre in {\sc{Python}} va sempre definita una variabile a priori per poi modificarla progressivamente. In questi casi, l'IA traduceva il programma senza adattarsi alle esigenze del nuovo linguaggio, andando a modificare una variabile mai definita prima.

Nonostante apparentemente questi siano errori banali e di semplice risoluzione, qualora si facesse tradurre all'IA un codice senza avere idea della nuova forma che dovrebbe assumere, si avrebbero non poche difficolt\`a nella ricerca ed identificazione dell'errore nel programma.

Il programma ideale per la traduzione di un programma da {\sc{Matlab}} a {\sc{Python}} molto probabilmente si avvicinerebbe, almeno concettualmente, al traduttore online {\textsc mat2py}, il quale ha implementati al suo interno algoritmi che traducono in maniera pedante ma precisa i codici da un linguaggio all'altro.

Anche questo programma, tuttavia, non \`e esente da difetti estremamente invalidanti, dal momento che, per quanto riguarda le librerie, {\textsc mat2py} \`e assolutamente autoreferenziale, ma i codici a sua disposizione non sono aggiornati in maniera attiva ed hanno forti lacune. Per tale ragione i codici da lui tradotti sono spesso privi delle funzioni numeriche adeguate ai calcoli che gli \`e richiesto compiere, funzioni numeriche che sono tuttavia ampiamente fornite da altre librerie quali {\tt numpy} o {\tt scipy}.}


\chapter{Esperimenti numerici}
{In questo capitolo si applicheranno le formule {\sc{Matlab}} e {\sc{Python}} su elementi poligonali con un lato curvo.

Per evidenziare l'equivalenza della traduzione, per ogni dominio di integrazione si effettuer\`a preliminarmente un'analisi delle cardinalit\`a delle formule e degli errori su nodi e pesi.

Nelle relative tabelle saranno visualizzati, in norma infinito, i massimi errori per nodi e pesi, compressi e non, per ciascun grado di precisione. In altri termini, se 
\begin{itemize}
\item $x^{(m)}$ e $w^{(m)}$ sono i nodi della formula originale in {\sc{Matlab}},
\item $x^{(p)}$ e $w^{(p)}$ sono i nodi della formula originale in {\sc{Python}},
\item $x_c^{(m)}$ e $w_c^{(m)}$ sono i nodi della formula compressa in {\sc{Matlab}},
\item $x_c^{(p)}$ e $w_c^{(p)}$ sono i nodi della formula compressa in {\sc{Python}},
\end{itemize}

\noindent verranno valutati
\begin{eqnarray}
E_{nodes}&=&\|x^{(m)}-x^{(p)}\|_{\infty} \nonumber\\
E_{weights}&=&\|w^{(m)}-w^{(p)}\|_{\infty} \nonumber \\
E^{(c)}_{nodes}&=&\|x_c^{(m)}-x_c^{(p)}\|_{\infty} \nonumber \\
E^{(c)}_{weights}&=&\|w_c^{(m)}-w_c^{(p)}\|_{\infty} \nonumber
\end{eqnarray}


In particolare, sia all'interno del programma {\sc Matlab} che all'interno del programma {\sc Python}, la funzione {\tt comprexcub} risolve il programma lineare \eqref{eq:PLVandermonde} con la funzione {\tt scipy.optimize.nnls}.


In ognuno degli esempi che seguiranno saranno considerate le approssimazioni di alcuni integrali tramite formule aventi gradi di precisione $ADE$ pari a $2,4,6,8$ e $10$. Questi valori sono stati scelti avendo in mente le applicazioni ai {\it{virtual elements}}, in cui generalmente i gradi di precisione non sono troppo alti.

Per ognuno dei gradi di esattezza ADE si raccoglieranno i seguenti dati:


\begin{itemize} 
  \item il valore corretto {\sl{INT}} dell'integrale, definito applicando la formula di cubatura \eqref{eq:FunzReq} con grado di precisione 60;
  \item i valori numerici {\sl{Int\_M}}, {\sl{Int\_P}} dell'integrale, ottenuti tramite la formula di cubatura \eqref{eq:FunzReq}, rispettivamente in {\sc{Matlab}} e in {\sc{Python}};
    \item i valori numerici {\sl{Compr\_Int\_M}}, {\sl{Compr\_Int\_P}} dell'integrale, ottenuti tramite la formula di cubatura compressa \eqref{eq:comprex}, rispettivamente in {\sc{Matlab}} e in {\sc{Python}};
  \item le cardinalit\`a delle formule di cubatura {\sl{Card\_M}}, {\sl{Card\_P}}, {\sl{Compr\_Card\_M}}, {\sl{Compr\_Card\_P}}, ottenute rispettivamente in {\sc{Matlab}} e in {\sc{Python}}, relativamente alla formula originale e a quella compressa;
\item gli errori relativi
{\sl{ER\_M}}, {\sl{ERC\_M}}, {\sl{ER\_P}}, {\sl{ERC\_P}}, compiuti dai codici in {\sc{Matlab}} e in {\sc{Python}}, relativamente dalla formula originale e da quella compressa;
  
  \item i tempi di calcolo {\sl{Time\_M}}, {\sl{Time\_P}} necessari per l'esecuzione di {\tt polygcirc}, rispettivamente in {\sc{Matlab}} e in {\sc{Python}}.
\end{itemize}
}


\section{Esperimenti su un elemento poligonale con un lato curvo e convesso}



{Quale primo dominio, si consideri il poligono circolare convesso avente come vertici i punti (0.25, 0), (0.4, 0.05), (0.5, 0.25), (0.45, 0.45), (0.3, 0.5), (0.1, 0.45), (0, 0.25) e come lato curvo l'arco di circonferenza di centro (0.25, 0.25) e raggio 0.25 avente come estremi i punti (0.25, 0) e (0, 0.25).

Il dominio \`e rappresentato dalle figure {\ref{fig:1.1}}, assieme rispettivamente all'insieme di nodi delle formule originali e compresse per $ADE=10$. In tali figure si evidenzia, come noto, che i nodi sono interni al dominio.

Di seguito, nella figura {\ref{fig:1.2}}, sono riportati i valori dei pesi ordinati in senso crescente, tanto per le formule originali quanto per quelle compresse. Si vede immediatamente la differeza di cardinalit\`a e che i pesi, per entrambe le formule, sono positivi.

Nella tabella \ref{tab:1.0} sono stati indicati, per ciascuno dei gradi stabiliti, le cardinalit\`a di tali formule. 

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & Card\_M & Card\_P & Compr\_Card\_M & Compr\_Card\_P \\
    \hline
    \hline
    2 & 52 & 52 & 6 & 6 \\
    \hline
    4 & 161 & 161 & 15 & 15 \\
    \hline
    6 & 330 & 330 & 28 & 28 \\
    \hline
    8 & 559 & 559 & 45 & 45 \\
    \hline
    10 & 848 & 848 & 66 & 66 \\
    \hline
\end{tabular}
\caption{Cardinalit\`a delle formule di cubatura originali e compresse tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:1.0}%
\end{center}
\end{table}



Dalla tabella {\ref{tab:Errori_1}}, invece, si vede che le formule originali sono numericamente uguali in termini di nodi e pesi. Per quanto riguarda le loro versioni compresse, nonostante vengano chiamate routines diverse di NNLS, anche queste risultano numericamente equivalenti. 


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & $E_{nodes}$ & $E_{weights}$ & $E^{(c)}_{nodes}$ & $E^{(c)}_{weights}$ \\
    \hline
    \hline
    2 & 5.6  $\cdot 10^{-16}$  & 5.0 $\cdot 10^{-16}$ & 4.9 $\cdot 10^{-16}$ & 4.2 $\cdot 10^{-16}$ \\
    \hline
    4 & 5.6  $\cdot 10^{-16}$  & 5.0 $\cdot 10^{-16}$ & 5.3 $\cdot 10^{-16}$ & 4.6 $\cdot 10^{-16}$ \\
    \hline
    6 & 5.6  $\cdot 10^{-16}$  & 5.0 $\cdot 10^{-16}$ & 5.6 $\cdot 10^{-16}$ & 5.2 $\cdot 10^{-16}$ \\
    \hline
    8 & 5.6  $\cdot 10^{-16}$  & 5.0 $\cdot 10^{-16}$ & 5.6 $\cdot 10^{-16}$ & 5.2 $\cdot 10^{-16}$ \\
    \hline
    10 & 5.6  $\cdot 10^{-16}$  & 5.0 $\cdot 10^{-16}$ & 5.3 $\cdot 10^{-16}$ & 7.6 $\cdot 10^{-16}$ \\
    \hline
\end{tabular}
\caption{Scarti per nodi e pesi, sia compressi che non, tra {\sc{Matlab}} e {\sc{Python}} sotto forma di norma infinito per il dominio di integrazione convesso.}
\label{tab:Errori_1}%
\end{center}
\end{table}


Di seguito abbiamo considerato l'approssimazione dell'integrale di  $f_1(x,y) = e^{(x-y)}$ sul'elemento in analisi, il cui risultato di riferimento $$INT = 0.18924464927762087$$ \`e stato ottenuto mediante una formula non compressa con grado di precisione $ADE=60$.





\begin{figure}[h!]
    \centering
    \includegraphics[width=7cm]{Esp01_Nodi Full}
    \qquad
    \includegraphics[width=7cm]{Esp01_Nodi compressi} 
    \caption{Nodi per le formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
    \label{fig:1.1}%
\end{figure}


\begin{figure}[h!]
    \centering
    {\includegraphics[width=7cm]{Esp1_Pesi_Full} }%
    \qquad
    {\includegraphics[width=7cm]{Esp1_Pesi_Comp} }%
        \caption{Pesi ordinati per valore delle formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
        \label{fig:1.2}%
 \end{figure}
}

}

Nelle tabelle {\ref{tab:1.1}} e {\ref{tab:1.2}} vengono riportati i valori ottenuti utilizzando formule di quadratura originali e compresse, tanto in {\sc{Matlab}} quanto in {\sc{Python}}, mentre in \ref{tab:1.3} si trovano gli errori relativi compiuti. Come atteso, i risultati raggiunti sono estremamente simili. 

{

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Int\_M & Int\_P \\
    \hline
    \hline
    2 &  0.1892445479685858  & 0.18924454796858572  \\
    \hline
    4 &  0.1892446492775920  & 0.18924464927759205 \\
    \hline
    6 &  0.1892446492776211  & 0.18924464927762100 \\
    \hline
    8 &  0.1892446492776211  & 0.18924464927762114 \\
    \hline
    10 & 0.1892446492776216  & 0.18924464927762155 \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale proposto con le formula di cubatura originali, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:1.1}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Compr\_Int\_M & Compr\_Int\_P \\
    \hline
    \hline
    2 & 0.1892014422189217  & 0.18920144221892168  \\
    \hline
    4 & 0.1892447779632670  & 0.18924477796326708  \\
    \hline
    6 & 0.1892446492824988  & 0.18924464928249871 \\
    \hline
    8 & 0.1892446492776253  & 0.18924464927762522  \\
    \hline
    10 & 0.1892446492776212 & 0.18924464927762111  \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale proposto con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:1.2}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & ER\_M & ER\_P & ERC\_M & ERC\_P \\
    \hline
    \hline
    2 & 5.4 $\cdot {10}^{-7}$ & 5.4 $\cdot {10}^{-7}$ &  2.3 $\cdot {10}^{-4}$ & 2.3 $\cdot {10}^{-5}$ \\
    \hline
    4 & 1.5 $\cdot {10}^{-13}$ & 1.5 $\cdot {10}^{-13}$ & 6.8 $\cdot {10}^{-7}$ & 6.8 $\cdot {10}^{-7}$ \\
    \hline
    6 & 1.3 $\cdot {10}^{-15}$ & 7.3 $\cdot {10}^{-16}$ & 2.6 $\cdot {10}^{-11}$ & 2.6 $\cdot {10}^{-11}$ \\
    \hline
    8 & 1.2 $\cdot {10}^{-15}$ & 1.5 $\cdot {10}^{-15}$ & 2.3 $\cdot {10}^{-14}$ & 2.3 $\cdot {10}^{-14}$ \\
    \hline
    10 & 4.0 $\cdot {10}^{-15}$ & 3.7 $\cdot {10}^{-15}$ & 1.6 $\cdot {10}^{-15}$ & 1.3 $\cdot {10}^{-15}$\\
    \hline
\end{tabular}
\end{center}
\caption{Errori relativi nel calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:1.3}%
\end{table}

Si raccolgono infine nelle ultime due tabelle in \ref{tab:1.4} i tempi di calcolo medi di tutte le formule utilizzate nei due linguaggi di programmazione. Dal momento che i tempi di valutazione per l'integrale sono trascurabili, le tempistiche dei programmi sono essenzialmente quelle del calcolo per la formula di quadratura.
In particolare, ognuno di questi risultati \`e ottenuto dalla media dei tempi di 20 lanci del programma {\tt polygcirc} per ciascun grado di precisione. 


\begin{center}
\begin{table}[h!]
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Rule\_Time\_M & Rule\_Time\_P \\
    \hline
    \hline
    2 & 7.458 $\cdot {10}^{-4}$ & 3.220 $\cdot {10}^{-3}$ \\
    \hline
    4 & 8.884 $\cdot {10}^{-4}$ & 2.142 $\cdot {10}^{-3}$ \\
    \hline
    6 & 5.278 $\cdot {10}^{-4}$ & 4.142 $\cdot {10}^{-3}$ \\
    \hline
    8 & 5.586 $\cdot {10}^{-4}$ & 1.210 $\cdot {10}^{-2}$ \\
    \hline
    10 & 6.396 $\cdot {10}^{-4}$ & 6.255 $\cdot {10}^{-3}$ \\
    \hline
\end{tabular}
\quad
\begin{tabular}{|c||c|c|}
    \hline
    ADE & C\_Rule\_Int\_M & C\_Rule\_Int\_P \\
    \hline
    \hline
    2 & 4.026 $\cdot {10}^{-3}$ & 5.388 $\cdot {10}^{-3}$ \\
    \hline
    4 & 3.035 $\cdot {10}^{-3}$ & 9.168 $\cdot {10}^{-3}$ \\
    \hline
    6 & 2.934 $\cdot {10}^{-3}$ & 1.400 $\cdot {10}^{-2}$ \\
    \hline
    8 & 4.258 $\cdot {10}^{-3}$ & 4.886 $\cdot {10}^{-2}$ \\
    \hline
    10 & 1.406 $\cdot {10}^{-2}$ & 2.776 $\cdot {10}^{-2}$ \\
    \hline
\end{tabular}
\caption{Tempi di calcolo con le formule di cubatura originali e compresse, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:1.4}
\end{table}

\end{center}


\FloatBarrier

{Si nota immediatamente che il programma nel suo linguaggio d'origine risulta pi\`u veloce rispetto al codice {\sc Python}.}

{Come secondo esperimento, calcoliamo numericamente l'integrale di una funzione meno regolare, come 
$$f_2(x,y)=((x-2/5)^2+(y-1/3)^2)^\frac{5}{2}$$ sullo stesso dominio definito per il primo esempio. Nel caso della funzione in esame, l'irregolarit\`a \`e data dal punto singolare $(x_0,y_0) \equiv (2/5, 1/3)$ che \`e interno al poligono curvilineo convesso $\Omega$.
Poich\'e il numero di nodi e pesi ottenuti dipende esclusivamente dalla figura in esame, si avr\`a di conseguenza che le cardinalit\`a degli insiemi contenenti i nodi risulteranno invariate.

Utilizzando il codice {\sc{Matlab}} con ADE=$60$ otteniamo il valore di riferimento 
\[ INT = 3.4852942237109879 \cdot 10^{-4}.\]}

{Poich\'e, come detto in precedenza, i tempi di calcolo degli integrali sono trascurabili e le tempistiche complessive sono approssimate a quelle del calcolo per la formula di quadratura, per i tempi di questo integrale si far\`a riferimento alla tabella \ref{tab:1.4}.}




\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Int\_M & Int\_P \\
    \hline
    \hline
    2 &  3.4693882669925368 $\cdot 10^{-4}$  & 3.4693882669925357 $\cdot 10^{-4}$ \\
    \hline
    4 &  3.4852956661042306 $\cdot 10^{-4}$  & 3.4852956661042311 $\cdot 10^{-4}$ \\
    \hline
    6 &  3.4852942373675845 $\cdot 10^{-4}$  & 3.4852942373675834 $\cdot 10^{-4}$ \\
    \hline
    8 &  3.4852942190582232 $\cdot 10^{-4}$  & 3.4852942190582233 $\cdot 10^{-4}$ \\
    \hline
    10 & 3.4852942217568768 $\cdot 10^{-4}$  & 3.4852942217568735 $\cdot 10^{-4}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura originali, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:2.1}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Compr\_Int\_M & Compr\_Int\_P \\
    \hline
    \hline
    2 & 5.2625000443101136 $\cdot 10^{-4}$  & 5.2625000443101136 $\cdot 10^{-4}$ \\
    \hline
    4 & 3.4669365134521070 $\cdot 10^{-4}$ & 3.4669365134521037 $\cdot 10^{-4}$ \\
    \hline
    6 & 3.4847637578881458 $\cdot 10^{-4}$ & 3.4847637578881398 $\cdot 10^{-4}$ \\
    \hline
    8 & 3.4853234110670140 $\cdot 10^{-4}$ & 3.4853234110670145 $\cdot 10^{-4}$ \\
    \hline
    10 & 3.4852899344312332 $\cdot 10^{-4}$ & 3.4852899344312325 $\cdot 10^{-4}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:2.2}%
\end{center}
\end{table}

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & ER\_M & ER\_P & ERC\_M & ERC\_P \\
    \hline
    \hline
    2 & 4.6 $\cdot {10}^{-3}$ & 4.6 $\cdot {10}^{-3}$ &  5.1 $\cdot 10^{-1}$ & 5.1 $\cdot {10}^{-1}$ \\
    \hline
    4 & 4.1 $\cdot {10}^{-7}$ & 4.1 $\cdot {10}^{-7}$ & 5.3 $\cdot {10}^{-3}$ & 5.3 $\cdot {10}^{-3}$ \\
    \hline
    6 & 3.9 $\cdot {10}^{-9}$ & 3.9 $\cdot {10}^{-9}$ & 1.5 $\cdot {10}^{-4}$ & 1.5 $\cdot {10}^{-4}$ \\
    \hline
    8 & 1.3 $\cdot {10}^{-9}$ & 1.3 $\cdot {10}^{-9}$ & 8.4 $\cdot {10}^{-6}$ & 8.4 $\cdot {10}^{-6}$ \\
    \hline
    10 & 5.6 $\cdot {10}^{-10}$ & 5.6 $\cdot {10}^{-10}$ & 1.2 $\cdot {10}^{-6}$ & 1.2 $\cdot {10}^{-6}$\\
    \hline
\end{tabular}
\end{center}
\caption{Errori relativi nel calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:2.3}%
\end{table}


{Nuovamente, gli integrali risultano estremamente simili, a riprova dell'equivalenza dei codici nonostante la diversit\`a dei linguaggi.

L'equivalenza di tali risultati \`e ulteriormente evidenziata dagli errori relativi, che diminuiscono rapidamente verso la precisione di macchina, com'\`e possibile constatare dalla tabella \ref{tab:2.3}.}











\section{Esperimenti su un elemento poligonale con un lato curvo e concavo}

{In questa sezione saranno proposti degli esperimenti di quadratura numerica su due elementi poligonali con un lato curvo di tipo concavo.

Analogamente ai casi con lato convesso, si analizzer\`a innanzitutto la cardinalit\`a delle formule proposte. Nel caso delle formule compresse si constater\`a che, pur risultando diverse, entrambe possiedono le propriet\`a richieste, ovvero un adeguato grado di precisione e dei pesi positivi.

Come integranda consideriamo per entrambi i domini la funzione analitica 
\begin{equation}\label{ftest}
f_3(x,y) = e^{-(x-0.2)^2-(y-0.2)^2}.
\end{equation}

Si tenga a mente che il proposito di questa trattazione non si limita all'osservazione dell'errore al variare del grado di precisione, ma richiede anche di verificare che il codice {\sc{Python}} esegua operazioni numericamente equivalenti a quelle proposte in {\sc{Matlab}}.

Nuovamente, per ottenere le formule compresse in {\sc{Python}}, \`e stata utilizzata la routine {\tt{comprexcub}} in cui l’algoritmo di Lawson-Hanson \`e implementato dalla funzione {\tt scipy.optimize.nnls}.}











\subsection{Un primo elemento poligonale con lato curvo e concavo}

In questa sezione consideriamo l'elemento composto dalla spezzata che unisce i vertici (0.25,0.2), (0.2,0.25), (0, 0.25), (0.25,0) e dall'arco della circonferenza di centro (0,0) e raggio 0.25 unente i punti (0,0.25), (0.25,0).

Il dominio \`e descritto nella figure \ref{fig:2.1}, assieme al corrispettivo insieme di nodi delle formule originali e compresse per $ADE = 10$. Come per l'esempio convesso, si propone anche qui, nella figura \ref{fig:2.2}, il grafico dei nodi ordinati rispettivamente originali e compressi, nuovamente con $ADE = 10$.

\begin{figure}[h!]
    \centering
    \includegraphics[width=7cm]{2_E1_Full_N}
    \qquad
    \includegraphics[width=7cm]{2_E1_Comp_N} 
    \caption{Nodi per le formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
    \label{fig:2.1}%
\end{figure}


\begin{figure}[h!]
    \centering
    {\includegraphics[width=7cm]{2_E1_Full_W} }%
    \qquad
    {\includegraphics[width=7cm]{2_E1_Comp_W} }%
        \caption{Pesi ordinati per valore delle formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
        \label{fig:2.2}%
 \end{figure}

{Si riporta poi nella tabella {\ref{tab:3.0}}, come per tutti gli altri domini trattati, il numero di nodi utilizzati nelle forme di integrazione.

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & Card\_M & Card\_P & Compr\_Card\_M & Compr\_Card\_P \\
    \hline
    \hline
    2 & 36 & 36 & 6 & 6 \\
    \hline
    4 & 78 & 78 & 15 & 15 \\
    \hline
    6 & 136 & 136 & 28 & 28 \\
    \hline
    8 & 210 & 210 & 45 & 45 \\
    \hline
    10 & 300 & 300 & 66 & 66 \\
    \hline
\end{tabular}
\caption{Cardinalit\`a delle formule di cubatura originali e compresse tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:3.0}%
\end{center}
\end{table}

\FloatBarrier
Come atteso, anche in questo caso (tabella \ref{tab:3.0}) e nel seguente, come sar\`a possibile constatare dalla tabella \ref{tab:4.0}, indipendentemente dal linguaggio di programmazione utilizzato, il programma restituisce sempre lo stesso numero di nodi, sia applicando la formula originale sia calcolandone la controparte compressa.

Si confrontano quindi le formule proposte dagli algoritmi implementati nei due linguaggi: dalla tabella {\ref{tab:Errori_2}}, si verifica nuovamente che le formule originali sono numericamente uguali in termini di nodi e pesi; al contrario, per quanto riguarda le loro versioni compresse, queste non sono equivalenti.

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
ADE & $E_{nodes}$ & $E_{weights}$ & $E^{(c)}_{nodes}$ & $E^{(c)}_{weights}$ \\
    \hline
    \hline
    2 & 5.3 $\cdot 10^{-16}$  & 3.9 $\cdot 10^{-16}$ & 1.0 $\cdot 10^{-1}$ & 5.3 $\cdot 10^{-3}$
 \\
    \hline
    4 & 5.6 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 8.0 $\cdot 10^{-2}$ & 3.9 $\cdot 10^{-3}$ \\
    \hline
    6 & 5.6 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 1.1 $\cdot 10^{-14}$ \\
    \hline
    8 & 5.3 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 1.5 $\cdot 10^{-1}$ & 8.2 $\cdot 10^{-4}$ \\
    \hline
    10 & 5.9 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 5.9 $\cdot 10^{-16}$ & 7.9 $\cdot 10^{-10}$ \\
    \hline
\end{tabular}
\caption{Scarti per nodi e pesi, sia compressi che non, tra {\sc{Matlab}} e {\sc{Python}} sotto forma di norma infinito per il primo dominio di integrazione concavo.}
\label{tab:Errori_2}%
\end{center}
\end{table}

\`E interessante notare come, in tutte e tre le tabelle \ref{tab:Errori_1}, \ref{tab:Errori_2} e \ref{tab:Errori_3A}, nodi e pesi non compressi presentino un errore estremamente piccolo riconducibile alla precisione di macchina, mentre, per quanto riguarda nodi e pesi compressi, vi sono pi\`u risultati in cui la differenza dei valori assume dimensioni tutt'altro che indifferenti. Tuttavia, alla luce di quanto visto nella sezione 1.3.2 riguardo ai sistemi lineari \eqref{eq:VanVan} e \eqref{eq:PLVandermonde}, sappiamo che la formula di compressione non ha necessariamente soluzione unica. Tali differenze nei risultati, dunque, sono causate dalle differenze intrinseche dei due linguaggi e dei programmi che risolvono il sistema all'interno della funzione {\tt comprexcub}, le quali portano a trovare in {\sc Python} un insieme di nodi e pesi differente, ma non per questo meno attendibile rispetto a quello trovato in {\sc Matlab}.

Per mostrare meglio questo dettaglio, confrontiamo nella tabella \ref{tab:momenti} gli errori di ricostruzione dei momenti calcolati da {\tt comprexcub} rispettivamente in {\sc Matlab} e in {\sc Python}.


In dettaglio, il parametro {\tt{momerr}} valuta l'errore sui momenti in norma 2 di una certa base polinomiale a grado $n$ (cf. {\cite{SV}}) e, qualora sia vicino alla precisione di macchina, esso indica che la formula \`e numericamente esatta. 

Quindi, indicati con
\begin{itemize}
\item ${\tt{momerr}}_M$ il valore del parametro {\tt{momerr}} ottenuto dal codice {\sc{Matlab}},
\item ${\tt{momerr}}_P$ il valore del parametro {\tt{momerr}} ottenuto dal codice {\sc{Python}},
\end{itemize}
\noindent dalla tabella {\ref{tab:momenti}} deduciamo che le formule compresse, per quanto diverse, sono entrambe numericamente esatte.




\begin{center}
\begin{table}[h!] \label{tab:3.22}%
\centering
\begin{tabular}{|c||c|c|}
    \hline
    ADE & ${\tt{momerr}}_M$ & ${\tt{momerr}}_P$ \\
    \hline
    \hline
    2 & 5.1 $\cdot 10^{-19}$  & 2.0 $\cdot 10^{-18}$ \\
    \hline
    4 & 6.0 $\cdot 10^{-19}$ & 1.3 $\cdot 10^{-18}$ \\
    \hline
    6 & 8.3 $\cdot 10^{-19}$  & 5.3 $\cdot 10^{-19}$ \\
    \hline
    8 & 9.2 $\cdot 10^{-19}$ & 6.1 $\cdot 10^{-19}$ \\
    \hline
    10 & 1.1 $\cdot 10^{-18}$  & 5.6 $\cdot 10^{-19}$ \\
    \hline
\end{tabular}

\caption{Errori dei momenti calcolati da {\tt comprexcub} tanto in {\sc Matlab} quanto in {\sc Python}.}
\label{tab:momenti}
\end{table}
\end{center}

Per quanto riguarda l'integrale della funzione (\ref{ftest}), utilizzando il codice {\sc{Matlab}} con ADE=$60$ otteniamo il valore di riferimento \[INT = 1.2106206423126596 \cdot 10^{-2}.\]\\
Come per gli esperimenti precedenti, anche qui i tempi di calcolo del codice riportati sono stati ottenuti dalla media dei tempi di 20 lanci del programma per ciascun grado di precisione, trascurando i tempi per la valutazione degli integrali. In questo test, i sorgenti in Matlab risultano leggermente pi\`u rapidi dei corrispondenti in Python, i quali riescono comunque a rimanere nell'ordine dei centesimi/millesimi di secondo.}




\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Int\_M & Int\_P \\
    \hline
    \hline
    2 &  1.2106186263541621 $\cdot 10^{-2}$  & 1.2106186263541615 $\cdot 10^{-2}$ \\
    \hline
    4 &  1.2106206436421048 $\cdot 10^{-2}$  & 1.2106206436421046 $\cdot 10^{-2}$ \\
    \hline
    6 &  1.2106206423119728 $\cdot 10^{-2}$  & 1.2106206423119719 $\cdot 10^{-2}$ \\
    \hline
    8 &  1.2106206423126557 $\cdot 10^{-2}$  & 1.2106206423126570 $\cdot 10^{-2}$ \\
    \hline
    10 & 1.2106206423126566 $\cdot 10^{-2}$  & 1.2106206423126559 $\cdot 10^{-2}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura originali, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:3.1}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Compr\_Int\_M & Compr\_Int\_P \\
    \hline
    \hline
    2 & 1.2106300117877378 $\cdot 10^{-2}$ & 1.2106300117877363 $\cdot 10^{-2}$ \\
    \hline
    4 & 1.2106206381439225 $\cdot 10^{-2}$ & 1.2106206381439236 $\cdot 10^{-2}$ \\
    \hline
    6 & 1.2106206423156058 $\cdot 10^{-2}$ & 1.2106206423156051 $\cdot 10^{-2}$ \\
    \hline
    8 & 1.2106206423126503 $\cdot 10^{-2}$ & 1.2106206423126500 $\cdot 10^{-2}$ \\
    \hline
    10 & 1.2106206423126570 $\cdot 10^{-2}$ & 1.2106206423126572 $\cdot 10^{-2}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:3.2}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & ER\_M & ER\_P & ERC\_M & ERC\_P \\
    \hline
    \hline
    2 & 1.7 $\cdot {10}^{-6}$ & 1.7 $\cdot {10}^{-6}$ &  7.7 $\cdot 10^{-6}$ & 7.7 $\cdot {10}^{-6}$ \\
    \hline
    4 & 1.1 $\cdot {10}^{-9}$ & 1.1 $\cdot {10}^{-9}$ & 3.4 $\cdot {10}^{-9}$ & 3.4 $\cdot {10}^{-9}$ \\
    \hline
    6 & 5.7 $\cdot {10}^{-13}$ & 5.7 $\cdot {10}^{-13}$ & 2.4 $\cdot {10}^{-12}$ & 2.4 $\cdot {10}^{-12}$ \\
    \hline
    8 & 3.2 $\cdot {10}^{-15}$ & 2.1 $\cdot {10}^{-15}$ & 7.6 $\cdot {10}^{-15}$ & 7.9 $\cdot {10}^{-15}$ \\
    \hline
    10 & 2.4 $\cdot {10}^{-15}$ & 3.0 $\cdot {10}^{-15}$ & 2.5 $\cdot {10}^{-15}$ & 2.0 $\cdot {10}^{-15}$ \\
    \hline
\end{tabular}
\end{center}
\caption{Errori relativi nel calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:3.3}%
\end{table}


\begin{center}
\begin{table}[h!]
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Rule\_Time\_M & Rule\_Time\_P \\
    \hline
    \hline
    2 & 1.658 $\cdot {10}^{-3}$ & 3.190 $\cdot {10}^{-3}$ \\
    \hline
    4 & 1.805 $\cdot {10}^{-3}$ & 3.639 $\cdot {10}^{-3}$ \\
    \hline
    6 & 1.700 $\cdot {10}^{-3}$ & 4.594 $\cdot {10}^{-3}$ \\
    \hline
    8 & 2.189 $\cdot {10}^{-3}$ & 1.175 $\cdot {10}^{-2}$ \\
    \hline
    10 & 2.398 $\cdot {10}^{-3}$ &  1.580 $\cdot {10}^{-2}$ \\
    \hline
\end{tabular}
\quad
\begin{tabular}{|c||c|c|}
    \hline
    ADE & C\_Rule\_Int\_M & C\_Rule\_Int\_P \\
    \hline
    \hline
    2 & 2.210 $\cdot {10}^{-3}$ & 3.755 $\cdot {10}^{-3}$ \\
    \hline
    4 & 2.405 $\cdot {10}^{-3}$ & 4.284 $\cdot {10}^{-3}$ \\
    \hline
    6 & 3.047 $\cdot {10}^{-3}$ & 5.749 $\cdot {10}^{-3}$ \\
    \hline
    8 & 4.785 $\cdot {10}^{-3}$ & 1.557 $\cdot {10}^{-2}$ \\
    \hline
    10 & 7.418 $\cdot {10}^{-3}$ &  3.477 $\cdot {10}^{-2}$ \\
    \hline
\end{tabular}
\caption{Tempi di calcolo con le formule di cubatura originali e compresse, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\end{table}
\label{tab:3.4}%
\end{center}
 





 \FloatBarrier
 \subsection{Secondo esperimento su un elemento poligonale con lato curvo e concavo}

Si consideri quale secondo elemento poligonale con lato curvo e concavo, quello composto dalla spezzata che unisce i vertici (0.4,0.05), (0.5,0.25), (0.45,0.45), (0.3, 0.5), (0.1, 0.45), (0, 0.25), (0.25,0) e dall'arco della circonferenza di centro (0,0) e raggio 0.25 unente i punti (0,0.25), (0.25,0).

Il dominio \`e descritto nelle figure \ref{fig:2.1b}, assieme al corrispettivo insieme di nodi delle formule originali e compresse per $ADE = 10$. Come per gli altri domini trattati, si mostrano anche i grafici dei pesi ordinati, originali e compressi, nelle figure \ref{fig:2.2b}.

\begin{figure}[h!]
    \centering
    \includegraphics[width=7cm]{2_E2_NF.png}
    \qquad
    \includegraphics[width=7cm]{2_E2_NC.png} 
    \caption{Nodi per le formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
    \label{fig:2.1b}%
\end{figure}


\begin{figure}[h!]
    \centering
    {\includegraphics[width=7cm]{2_E2_WF.png} }%
    \qquad
    {\includegraphics[width=7cm]{2_E2_WC.png} }%
        \caption{Pesi ordinati per valore delle formule di cubatura con $ADE=10$, relativamente alla formula originale (a sinistra) e alla sua versione compressa (a destra).}%
        \label{fig:2.2b}%
 \end{figure}


Come in precedenza, la cardinalit\`a delle formule risulta uguale, tanto nel caso originale quanto in quello compresso.

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & Card\_M & Card\_P & Compr\_Card\_M & Compr\_Card\_P \\
    \hline
    \hline
    2 & 56 & 56 & 6 & 6 \\
    \hline
    4 & 120 & 120 & 15 & 15 \\
    \hline
    6 & 208 & 208 & 28 & 28 \\
    \hline
    8 & 320 & 320 & 45 & 45 \\
    \hline
    10 & 456 & 456 & 66 & 66 \\
    \hline
\end{tabular}
\caption{Cardinalit\`a delle formule di cubatura originali e compresse tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:4.0}%
\end{center}
\end{table}

Nel paragone tra nodi e pesi, nelle formule prodotte dai due linguaggi di programmazione, come per il dominio concavo precedente, le formule originali sono numericamente uguali, mentre non lo sono quelle compresse. Nonostante questo, con ragionamenti analoghi, risultano nuovamente entrambe numericamente esatte, come descritto dalle tabelle \ref{tab:Errori_3A} e \ref{tab:momentiA}.



\begin{table}[h!]
\centering
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & $E_{nodes}$ & $E_{weights}$ & $E^{(c)}_{nodes}$ & 
    $E^{(c)}_{weights}$ \\
    \hline
    \hline
    2 & 5.0 $\cdot 10^{-16}$  & 4.7 $\cdot 10^{-16}$ & 4.4 $\cdot 10^{-16}$ & 4.9 $\cdot 10^{-16}$ \\
    \hline
    4 & 5.6 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 4.4 $\cdot 10^{-16}$ & 4.8 $\cdot 10^{-16}$ \\
    \hline
    6 & 5.6 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 3.3 $\cdot 10^{-1}$ & 1.7 $\cdot 10^{-2}$ \\
    \hline
    8 & 5.3 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 1.9 $\cdot 10^{-1}$ & 5.0 $\cdot 10^{-3}$ \\
    \hline
    10 & 5.6 $\cdot 10^{-16}$ & 5.0 $\cdot 10^{-16}$ & 3.0 $\cdot 10^{-1}$ & 6.7 $\cdot 10^{-3}$ \\
    \hline
\end{tabular}
\caption{Scarti per nodi e pesi, sia compressi che non, tra {\sc{Matlab}} e {\sc{Python}} sotto forma di norma infinito per il secondo dominio di integrazione concavo.}
\label{tab:Errori_3A}%
\end{table}









\begin{center}
\begin{table} [h!] \label{tab:3.22}%
\centering


\begin{tabular}{|c||c|c|}
    \hline
    ADE & ${\tt{momerr}}_M$ & ${\tt{momerr}}_P$ \\
    \hline
    \hline
    2 & 7.4 $\cdot 10^{-18}$ & 5.9 $\cdot 10^{-18}$ \\
    \hline
    4 & 9.0 $\cdot 10^{-18}$ & 7.1 $\cdot 10^{-18}$ \\
    \hline
    6 & 9.9 $\cdot 10^{-18}$ & 6.8 $\cdot 10^{-18}$ \\
    \hline
    8 & 9.3 $\cdot 10^{-18}$ & 6.3 $\cdot 10^{-18}$ \\
    \hline
    10 & 1.4 $\cdot 10^{-17}$ & 5.5 $\cdot 10^{-18}$ \\
    \hline
\end{tabular}
\caption{Errori dei momenti calcolati da {\tt comprexcub} per il secondo elemento concavo tanto in {\sc Matlab} quanto in {\sc Python}.}
\label{tab:momentiA}
\end{table}
\end{center}












{Per quanto riguarda l'integrale della funzione (\ref{ftest}), utilizzando il codice {\sc{Matlab}} con ADE=$60$, si ottiene il valore di riferimento \[INT = 0.145174464220773263845.\]}
\FloatBarrier

\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Int\_M & Int\_P \\
    \hline
    \hline
    2 &  1.4516536090623977 $\cdot 10^{-1}$  & 1.4516536090623974 $\cdot 10^{-1}$ \\
    \hline
    4 &  1.4517449328603046 $\cdot 10^{-1}$  & 1.4517449328603046 $\cdot 10^{-1}$ \\
    \hline
    6 &  1.4517446415284663 $\cdot 10^{-1}$  & 1.4517446415284657 $\cdot 10^{-1}$ \\
    \hline
    8 &  1.4517446422089852 $\cdot 10^{-1}$  & 1.4517446422089839 $\cdot 10^{-1}$ \\
    \hline
    10 & 1.4517446422077290 $\cdot 10^{-1}$  & 1.4517446422077293 $\cdot 10^{-1}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura originali, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:4.1}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Compr\_Int\_M & Compr\_Int\_P \\
    \hline
    \hline
    2 & 1.4519145766083637 $\cdot 10^{-1}$  & 1.4519145766083622 $\cdot 10^{-1}$ \\
    \hline
    4 & 1.4517441656674904 $\cdot 10^{-1}$ & 1.4517441656674912 $\cdot 10^{-1}$ \\
    \hline
    6 & 1.4517446407001958 $\cdot 10^{-1}$ & 1.4517446407001944 $\cdot 10^{-1}$ \\
    \hline
    8 & 1.4517446422105307 $\cdot 10^{-1}$ & 1.4517446422105293 $\cdot 10^{-1}$ \\
    \hline
    10 & 1.4517446422077313 $\cdot 10^{-1}$ & 1.4517446422077310 $\cdot 10^{-1}$ \\
    \hline
\end{tabular}
\caption{Calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:4.2}%
\end{center}
\end{table}


\begin{table}[h!]
\begin{center}
\begin{tabular}{|c||c|c|c|c|}
    \hline
    ADE & ER\_M & ER\_P & ERC\_M & ERC\_P \\
    \hline
    \hline
    2 & 6.3 $\cdot {10}^{-5}$ & 6.3 $\cdot {10}^{-5}$ &  1.2 $\cdot 10^{-4}$ & 1.2 $\cdot {10}^{-4}$ \\
    \hline
    4 & 2.0 $\cdot {10}^{-7}$ & 2.0 $\cdot {10}^{-7}$ & 3.3 $\cdot {10}^{-7}$ & 3.3 $\cdot {10}^{-7}$ \\
    \hline
    6 & 4.7 $\cdot {10}^{-10}$ & 4.7 $\cdot {10}^{-10}$ & 1.0 $\cdot {10}^{-9}$ & 1.0 $\cdot {10}^{-9}$ \\
    \hline
    8 & 8.6 $\cdot {10}^{-13}$ & 8.6 $\cdot {10}^{-13}$ & 1.9 $\cdot {10}^{-12}$ & 1.9 $\cdot {10}^{-12}$ \\
    \hline
    10 & 2.5 $\cdot {10}^{-15}$ & 2.3 $\cdot {10}^{-15}$ & 9.6 $\cdot {10}^{-16}$ & 1.1 $\cdot {10}^{-15}$ \\
    \hline
\end{tabular}
\end{center}
\caption{Errori relativi nel calcolo dell'integrale con le formula di cubatura compressa, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\label{tab:4.3}%
\end{table}

{I valori degli integrali e degli errori relativi sono praticamente identici, a riprova dell'equivalenza numerica delle formule. 

Come in precedenza valutiamo i tempi di calcolo del codice ottenuti dalla media dei tempi di 20 lanci del programma per ciascun grado di precisione, trascurando i tempi per la valutazione degli integrali. Anche in questo test, i sorgenti in Matlab risultano leggermente pi\`u rapidi dei corrispondenti in Python.}

\begin{center}
\begin{table}[h!]
\begin{tabular}{|c||c|c|}
    \hline
    ADE & Rule\_Time\_M & Rule\_Time\_P \\
    \hline
    \hline
    2 & 2.545 $\cdot {10}^{-3}$ & 5.410 $\cdot {10}^{-3}$ \\
    \hline
    4 & 1.546 $\cdot {10}^{-3}$ & 5.432 $\cdot {10}^{-3}$ \\
    \hline
    6 & 1.845 $\cdot {10}^{-3}$ & 6.905 $\cdot {10}^{-3}$ \\
    \hline
    8 & 1.991 $\cdot {10}^{-3}$ & 1.698 $\cdot {10}^{-2}$ \\
    \hline
    10 & 2.786 $\cdot {10}^{-3}$ & 2.169 $\cdot {10}^{-2}$ \\
    \hline
\end{tabular}
\quad
\begin{tabular}{|c||c|c|}
    \hline
    ADE & C\_Rule\_Int\_M & C\_Rule\_Int\_P \\
    \hline
    \hline
    2 & 2.406 $\cdot {10}^{-3}$ & 5.375 $\cdot {10}^{-3}$ \\
    \hline
    4 & 2.337 $\cdot {10}^{-3}$ & 6.218 $\cdot {10}^{-3}$ \\
    \hline
    6 & 3.376 $\cdot {10}^{-3}$ & 8.459 $\cdot {10}^{-3}$ \\
    \hline
    8 & 4.514 $\cdot {10}^{-3}$ & 2.845 $\cdot {10}^{-2}$ \\
    \hline
    10 & 9.514 $\cdot {10}^{-3}$ & 5.807 $\cdot {10}^{-2}$ \\
    \hline
\end{tabular}
\caption{Tempi di calcolo con le formule di cubatura originali e compresse, tanto in {\sc{Matlab}} quanto in {\sc{Python}}.}
\end{table}
\label{tab:4.4}%
\end{center}


{A seguito degli esperimenti trattati, è possibile concludere che, seppur con occasionali differenze per quanto riguarda gli algoritmi risolutivi, i codici possono definirsi in tutto e per tutto equivalenti, dal momento che anche gli scarti a livello di tempi non presentano differenze significative.}
























\begin{thebibliography}{99}

\bibitem{ASV} E. Artioli, A. Sommariva, M. Vianello, {\em{Algebraic cubature on polygonal elements with a circular edge}},
Computers Mathematics with Applications, Volume 79, Volume 7, 1 April 2020, pp.2057-2066.

\bibitem{Caratheodory} C. Caratheodory, {\em{\"{U}ber den Variabilittsbereich der Koeffizienten von
Potenzreihen, die gegebene Werte nicht annehmen}}, Math. Ann. 64 (1907), pp.95–115.

\bibitem{Cools} R. Cools, {\em{Constructing cubature formulae: the science behind the art}}, Acta Numer. 6 (1997), pp.1–54.

\bibitem{Cools2} R. Cools, {\em{An encyclopaedia of cubature formulas}}, J. Complexity 19 (2003), pp.445–453.

\bibitem{FSV} G. Da Fies, A. Sommariva, M. Vianello, {\em{ Algebraic cubature by
linear blending of elliptical arcs}}, Appl. Numer. Math. 74 (2013), pp.49–61.



\bibitem{FV} G. Da Fies, M. Vianello, {\em{Trigonometric Gaussian quadrature on
subintervals of the period}}, Electron. Trans. Numer. Anal. 39 (2012), pp.102–112.

\bibitem{LawHan} C.L. Lawson, R.J. Hanson, {\em{Solving least squares problems, Classics
in Applied Mathematics}}, 15, SIAM, Philadelphia, 1995.


\bibitem{PSV} F. Piazzon, A. Sommariva, M. Vianello, {\em{Caratheodory-Tchakaloff
Subsampling}}, Dolomites Res. Notes Approx. DRNA 10 (2017), pp.5–14.


\bibitem{RIN} L. Rinaldi, {\em{GitHub codes}},\\
\url{https://github.com/laura-rinaldi/Cheap_Splinegauss}

\bibitem{SV} A. Sommariva, M. Vianello, {\em{Compression of multivariate discrete measures and applications}}, Numer. Funct. Anal. Optim. 36 (2015), pp.1198–1223.

\bibitem{SC} A. Sommariva, {\em{Cubature codes and pointsets}},\\
\url{http://www.math.unipd.it/~alvise/software.html}

\bibitem{Tcherny} M. Tchernychova, {\em{Caratheodory cubature measures}}, Tesi di Dottorato in Matematica (supervisore T.Lyons), Universit\`a di Oxford, 2015.

\bibitem{TRA} G. Traversin, {\em{{\sc{Python}} package for numerical cubature on polygonal elements with one curved edge}}\\
{\url{https://github.com/2002232/Squaring-polygonal-elements-with-one-curved-side-in-Python.git}}



\bibitem{VianelloCodes} M. Vianello, {\em{UBP: {\sc{Matlab}} package for subperiodic trigonometric quadrature and multivariate applications}},\\
\url{http://www.math.unipd.it/~marcov/subp.html}



\end{thebibliography}

\newpage

\newpage

\chapter*{Appendice}

Vengono di seguito riportate le principali routines tradotte in {\sc{Python}} in questa tesi, con i relativi commenti ed eventuale documentazione.

Gli stessi codici sono disponibili, anche come programmi singoli, in forma open-source al link 
\begin{center}
{\small{\url{https://github.com/2002232/Squaring-polygonal-elements-with-one-curved-side-in-Python.git}}}
\end{center}

\include{Appendice}








\end{document}
