#!/usr/bin/env python3 # QP_Grundlagen.py """ Kapitel QP/NLP: Die drei Faelle aus der Konvexitaets-Tabelle (Abschnitt 'Das quadratische Programm') an einem Mini-QP demonstriert: P positiv definit, P (singulaer) semidefinit, P mit negativem Eigenwert. """ import numpy as np import cvxpy as cp def loese_qp(P, q, name): n = len(q) w = cp.Variable(n) ziel = cp.Minimize(0.5 * cp.quad_form(w, P) + q @ w) bedingungen = [cp.sum(w) == 1, w >= 0] problem = cp.Problem(ziel, bedingungen) print(f"\n--- {name} ---") eigenwerte = np.linalg.eigvalsh(P) print(f"Eigenwerte von P: {np.round(eigenwerte, 4)}") print(f"DCP-konvex (CVXPY-Pruefung)? {problem.is_dcp()}") if not problem.is_dcp(): print("-> CVXPY lehnt das Problem ab, BEVOR ueberhaupt ein Solver laeuft.") return problem.solve() print(f"Status: {problem.status}") print(f"w* = {np.round(w.value, 4)}") print(f"Zielwert = {problem.value:.6f}") if __name__ == "__main__": q = np.zeros(2) # Fall 1: P positiv definit -> eindeutiges Minimum P_definit = np.array([[2.0, 0.5], [0.5, 1.0]]) loese_qp(P_definit, q, "P positiv definit") # Fall 2: P singulaer/semidefinit (zwei "identische" Assets) -> unendlich viele Minima P_semidefinit = np.array([[1.0, 1.0], [1.0, 1.0]]) loese_qp(P_semidefinit, q, "P positiv semidefinit (singulaer)") # Fall 3: P mit negativem Eigenwert -> nicht konvex P_indefinit = np.array([[1.0, 2.0], [2.0, 1.0]]) loese_qp(P_indefinit, q, "P indefinit (negativer Eigenwert)") print("\n--- Nachweis: 'unendlich viele Minima' im semidefiniten Fall ---") for punkt in [np.array([1.0, 0.0]), np.array([0.0, 1.0]), np.array([0.3, 0.7])]: wert = 0.5 * punkt @ P_semidefinit @ punkt print(f" w = {punkt} -> Zielwert = {wert:.4f} (identisch, obwohl w verschieden)")