Uploaded Exam2026
This commit is contained in:
415
OptiNonLin2026 DAOUST Alexandre.ipynb.json
Normal file
415
OptiNonLin2026 DAOUST Alexandre.ipynb.json
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 1,
|
||||||
|
"id": "541f3ecd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# DAOUST Alexandre 242015"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 2,
|
||||||
|
"id": "c68d497b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import numpy as np"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 3,
|
||||||
|
"id": "018d8af6",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def fct(x, nargout=2):\n",
|
||||||
|
" x1, x2 = x\n",
|
||||||
|
" \n",
|
||||||
|
" f = 2*x1**3 + 3*x2**3 + 2*x1**2 + 4*x2**2 + x1*x2 - 3*x1 - 2*x2\n",
|
||||||
|
" g = np.array([6*x1**2 + 4*x1 + x2 - 3,\n",
|
||||||
|
" 6*x2**2 + 8*x2 + x1 - 2])\n",
|
||||||
|
" if nargout==3:\n",
|
||||||
|
" H = np.array([[12*x1 + 4, 1 ],\n",
|
||||||
|
" [ 1, 12*x2 + 8]])\n",
|
||||||
|
" return f, g, H\n",
|
||||||
|
" return f, g"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 4,
|
||||||
|
"id": "4ab88c2f",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"f = 19.0000\n",
|
||||||
|
"g = |28.0000|\n",
|
||||||
|
" |-2.0000|\n",
|
||||||
|
"H = |28.0000 1.0000|\n",
|
||||||
|
" |1.0000 -4.0000|\n",
|
||||||
|
"\n",
|
||||||
|
"f = 0.0000\n",
|
||||||
|
"g = |-3.0000|\n",
|
||||||
|
" |-2.0000|\n",
|
||||||
|
"H = |4.0000 1.0000|\n",
|
||||||
|
" |1.0000 8.0000|\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Test de f en 2,-1\n",
|
||||||
|
"x = np.array([2.0, -1.0])\n",
|
||||||
|
"f, g, H = fct(x, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"print()\n",
|
||||||
|
"\n",
|
||||||
|
"# Test de f en 0,0\n",
|
||||||
|
"x = np.array([0.0, 0.0])\n",
|
||||||
|
"f, g, H = fct(x, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"# On a bien le bon résultat"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"id": "958a11f2",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def CoordinateDescent(x0, maxiter=10):\n",
|
||||||
|
" # Formules calculées à la main selon x1 et x2 respectivement\n",
|
||||||
|
" # Elles correspondent à f(xi) = Somme(coeff*xi^n) + C (C constante reprennant le(s) xj!=xi actuel(s) et\n",
|
||||||
|
" # les autres constantes) qu'on dérive et qu'on optimise.\n",
|
||||||
|
" x = x0.copy()\n",
|
||||||
|
" n = len(x)\n",
|
||||||
|
" \n",
|
||||||
|
" for i in range(maxiter):\n",
|
||||||
|
" # Mise à jour de x1\n",
|
||||||
|
" delta = 4**2-4*6*(x[1]-3)\n",
|
||||||
|
" x[0] = (-4 + np.sqrt(delta))/12\n",
|
||||||
|
" \n",
|
||||||
|
" #Mise à jour de x2\n",
|
||||||
|
" delta = 8**2 - 4*6*(x[0]-2)\n",
|
||||||
|
" x[1] = (-8 + np.sqrt(delta))/12\n",
|
||||||
|
" return x"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 6,
|
||||||
|
"id": "0b6c0173",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"x* = |0.4297|\n",
|
||||||
|
" |0.1737|\n",
|
||||||
|
"f = -0.8975\n",
|
||||||
|
"g = |-0.0000|\n",
|
||||||
|
" |-0.0000|\n",
|
||||||
|
"H = |9.1560 1.0000|\n",
|
||||||
|
" |1.0000 10.0840|\n",
|
||||||
|
"Valeurs propres:\n",
|
||||||
|
" 8.5176\n",
|
||||||
|
" 10.7224\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Test de CoordinateDescent\n",
|
||||||
|
"\n",
|
||||||
|
"# On trouve bien un minimum car la gradient est nul (à une tolérance près) et la matrice hessienne est définie positive\n",
|
||||||
|
"# (on augmente f si on se déplace du point)\n",
|
||||||
|
"\n",
|
||||||
|
"x = np.array([2.0, -1.0])\n",
|
||||||
|
"x_opt = CoordinateDescent(x)\n",
|
||||||
|
"print(f\"x* = |{x_opt[0]:.4f}|\\n |{x_opt[1]:.4f}|\")\n",
|
||||||
|
"f, g, H = fct(x_opt, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"eigval, eigvec = np.linalg.eig(H)\n",
|
||||||
|
"print(f\"Valeurs propres:\\n {eigval[0]:.4f}\\n {eigval[1]:.4f}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 7,
|
||||||
|
"id": "230d6b8b",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def w1(fct, x, d, alpha, beta1):\n",
|
||||||
|
" f0, g0 = fct(x)\n",
|
||||||
|
" f1, g1 = fct(x + alpha*d)\n",
|
||||||
|
" return f1 <= f0 + alpha*beta1*(g0@d)\n",
|
||||||
|
"\n",
|
||||||
|
"def w2(fct, x, d, alpha, beta2):\n",
|
||||||
|
" f0, g0 = fct(x)\n",
|
||||||
|
" f1, g1 = fct(x + alpha*d)\n",
|
||||||
|
" return g1@d >= beta2*(g0@d)\n",
|
||||||
|
"\n",
|
||||||
|
"def wolfebissection(fct, x, d, alpha=1, beta1=0.0001, beta2=0.9):\n",
|
||||||
|
" alphal = 0\n",
|
||||||
|
" alphar = np.inf\n",
|
||||||
|
" \n",
|
||||||
|
" wf1 = False\n",
|
||||||
|
" wf2 = False\n",
|
||||||
|
" \n",
|
||||||
|
" # k pour ne pas boucler à l'infini\n",
|
||||||
|
" k = 0\n",
|
||||||
|
" \n",
|
||||||
|
" while not (wf1 and wf2) and k < 1e4:\n",
|
||||||
|
" wf1 = w1(fct, x, d, alpha, beta1)\n",
|
||||||
|
" wf2 = w2(fct, x, d, alpha, beta2)\n",
|
||||||
|
" \n",
|
||||||
|
" if not wf1:\n",
|
||||||
|
" alphar = alpha\n",
|
||||||
|
" alpha = (alphal + alphar)/2\n",
|
||||||
|
" \n",
|
||||||
|
" elif not wf2:\n",
|
||||||
|
" alphal = alpha\n",
|
||||||
|
" if alphar < np.inf:\n",
|
||||||
|
" alpha = (alphal + alphar)/2\n",
|
||||||
|
" else:\n",
|
||||||
|
" alpha *= 2\n",
|
||||||
|
" \n",
|
||||||
|
" k += 1\n",
|
||||||
|
" \n",
|
||||||
|
" return alpha"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 8,
|
||||||
|
"id": "14f1cafd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"alpha = 0.1250\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Test de wolfebissection\n",
|
||||||
|
"x = np.array([0.0, 0.0])\n",
|
||||||
|
"d = np.array([3.0, 2.0])\n",
|
||||||
|
"alpha = wolfebissection(fct, x, d)\n",
|
||||||
|
"print(f\"alpha = {alpha:.4f}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 9,
|
||||||
|
"id": "2e390c95",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def MethGradient(x0, maxiter=10):\n",
|
||||||
|
" x = x0.copy()\n",
|
||||||
|
" \n",
|
||||||
|
" for k in range(maxiter):\n",
|
||||||
|
" f, g = fct(x)\n",
|
||||||
|
" d = -g\n",
|
||||||
|
" alpha = wolfebissection(fct, x, d)\n",
|
||||||
|
" x = x + alpha*d\n",
|
||||||
|
" \n",
|
||||||
|
" if np.linalg.norm(x) < 1e-9:\n",
|
||||||
|
" break\n",
|
||||||
|
" \n",
|
||||||
|
" return x"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 10,
|
||||||
|
"id": "07f82a85",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"x* = |0.4291|\n",
|
||||||
|
" |0.1674|\n",
|
||||||
|
"f = -0.8978\n",
|
||||||
|
"g = |-0.0116|\n",
|
||||||
|
" |-0.0640|\n",
|
||||||
|
"H = |9.1490 1.0000|\n",
|
||||||
|
" |1.0000 10.0083|\n",
|
||||||
|
"Valeurs propres:\n",
|
||||||
|
" 8.4903\n",
|
||||||
|
" 10.6671\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Test de MethGradient\n",
|
||||||
|
"\n",
|
||||||
|
"# La méthode du Gradient se raproche de la solution (x1 est correct, x2 est légèrement différent) mais n'y converge pas à cause\n",
|
||||||
|
"# du calcul du pas alpha qui ne donne pas le pas exact pour arriver au minimum (autrement dit, on n'arrive pas à calculer\n",
|
||||||
|
"# le pas alpha permettant de converger vers le minimum). Au plus on est proche, au plus le calcul d'un alpha admissible prend\n",
|
||||||
|
"# du temps.\n",
|
||||||
|
"\n",
|
||||||
|
"x = np.array([0.0, 0.0])\n",
|
||||||
|
"x_opt = MethGradient(x)\n",
|
||||||
|
"print(f\"x* = |{x_opt[0]:.4f}|\\n |{x_opt[1]:.4f}|\")\n",
|
||||||
|
"f, g, H = fct(x_opt, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"eigval, eigvec = np.linalg.eig(H)\n",
|
||||||
|
"print(f\"Valeurs propres:\\n {eigval[0]:.4f}\\n {eigval[1]:.4f}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 11,
|
||||||
|
"id": "1efec1bb",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def MethNewton(x0, maxiter=10):\n",
|
||||||
|
" x = x0.copy()\n",
|
||||||
|
" \n",
|
||||||
|
" for k in range(maxiter):\n",
|
||||||
|
" f, g, H = fct(x, nargout=3)\n",
|
||||||
|
" z = np.linalg.solve(H,g)\n",
|
||||||
|
" \n",
|
||||||
|
" x = x - z\n",
|
||||||
|
" \n",
|
||||||
|
" if np.linalg.norm(x) < 1e-9:\n",
|
||||||
|
" break\n",
|
||||||
|
" \n",
|
||||||
|
" return x"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 12,
|
||||||
|
"id": "f151f070",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"x* = |-1.2757|\n",
|
||||||
|
" |-1.6619|\n",
|
||||||
|
"f = 5.6516\n",
|
||||||
|
"g = |0.0000|\n",
|
||||||
|
" |-0.0000|\n",
|
||||||
|
"H = |-11.3086 1.0000|\n",
|
||||||
|
" |1.0000 -11.9422|\n",
|
||||||
|
"Valeurs propres:\n",
|
||||||
|
" -10.5764\n",
|
||||||
|
" -12.6744\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Test de MethNewton\n",
|
||||||
|
"\n",
|
||||||
|
"# La méthode de Newton est très sensible au point de départ, cela peut conduire (comme c'est le cas ici) à trouver un point\n",
|
||||||
|
"# qui n'est pas un minimum mais un maximum.\n",
|
||||||
|
"\n",
|
||||||
|
"x = np.array([-1.0, -1.0])\n",
|
||||||
|
"x_opt = MethNewton(x)\n",
|
||||||
|
"print(f\"x* = |{x_opt[0]:.4f}|\\n |{x_opt[1]:.4f}|\")\n",
|
||||||
|
"f, g, H = fct(x_opt, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"eigval, eigvec = np.linalg.eig(H)\n",
|
||||||
|
"print(f\"Valeurs propres:\\n {eigval[0]:.4f}\\n {eigval[1]:.4f}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 13,
|
||||||
|
"id": "b023fe44",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"x* = |0.4297|\n",
|
||||||
|
" |0.1737|\n",
|
||||||
|
"f = -0.8975\n",
|
||||||
|
"g = |0.0000|\n",
|
||||||
|
" |0.0000|\n",
|
||||||
|
"H = |9.1560 1.0000|\n",
|
||||||
|
" |1.0000 10.0840|\n",
|
||||||
|
"Valeurs propres:\n",
|
||||||
|
" 8.5176\n",
|
||||||
|
" 10.7224\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"# Validation du point calculé par la CoordinateDescent (et par la MethGradient aussi)\n",
|
||||||
|
"\n",
|
||||||
|
"# On trouve bien un minimum car la gradient est nul (à une tolérance près) et la matrice hessienne est définie positive\n",
|
||||||
|
"# (on augmente f si on se déplace du point)\n",
|
||||||
|
"\n",
|
||||||
|
"x = np.array([0.0, 0.0])\n",
|
||||||
|
"x_opt = MethNewton(x)\n",
|
||||||
|
"print(f\"x* = |{x_opt[0]:.4f}|\\n |{x_opt[1]:.4f}|\")\n",
|
||||||
|
"f, g, H = fct(x_opt, nargout=3)\n",
|
||||||
|
"print(f\"f = {f:.4f}\")\n",
|
||||||
|
"print(f\"g = |{g[0]:.4f}|\\n |{g[1]:.4f}|\")\n",
|
||||||
|
"print(f\"H = |{H[0][0]:.4f} {H[0][1]:.4f}|\\n |{H[1][0]:.4f} {H[1][1]:.4f}|\")\n",
|
||||||
|
"eigval, eigvec = np.linalg.eig(H)\n",
|
||||||
|
"print(f\"Valeurs propres:\\n {eigval[0]:.4f}\\n {eigval[1]:.4f}\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e3b81f36",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"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.9.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user