diff --git a/Kuengjoe_S01/Kuengjoe_S01_Aufg1.py b/Kuengjoe_S01/Kuengjoe_S01_Aufg1.py new file mode 100644 index 0000000..6bc9055 --- /dev/null +++ b/Kuengjoe_S01/Kuengjoe_S01_Aufg1.py @@ -0,0 +1,39 @@ +import numpy as np +import matplotlib.pyplot as plt +from pathlib import Path + + +limr = 10 # Bereich für x-Achse +liml = -10 + +def f(x): + return x**5 - 5*x**4 - 30*x**3 + 110*x**2 + 29*x - 105 + +def df(x): + return 5*x**4 - 20*x**3 - 90*x**2 + 220*x + 29 + +def F(x): + return (x**6)/6 - x**5 - (15/2)*x**4 + (110/3)*x**3 + (29/2)*x**2 - 105*x + + +x = np.linspace(liml, limr, 4000) +y = f(x) + + +plt.figure(figsize=(9, 6)) +plt.plot(x, y, label='f(x)') +plt.plot(x, df(x), label="f'(x)") +plt.plot(x, F(x), label='F(x) (C=0)') + +plt.ylim(-2500, 2500) +plt.xlim(liml, limr) + + +plt.title("Polinom f, Ableitung f' und Stammfunktion F auf einem gemeinsamen Plot") +plt.xlabel("x") +plt.ylabel("y") +plt.grid() +plt.legend() + + +plt.show() \ No newline at end of file diff --git a/Kuengjoe_S01/Kuengjoe_S01_Aufg2.py b/Kuengjoe_S01/Kuengjoe_S01_Aufg2.py new file mode 100644 index 0000000..85f2957 --- /dev/null +++ b/Kuengjoe_S01/Kuengjoe_S01_Aufg2.py @@ -0,0 +1,89 @@ + +import numpy as np + +# Beispiel-Aufruf (Aufgabe 2 / Polynom aus Aufg. 1): +# x, p, dp, Pint = Kuengjoe_S01_Aufg2([-105, 29, 110, -30, -5, 1], -10, 10) + + +def _as_1d_array(a): + arr = np.asarray(a, dtype=float) + if arr.size == 0: + raise Exception("Fehler") + if arr.ndim == 2: + if 1 in arr.shape: + arr = arr.reshape(-1) + else: + raise Exception("Fehler:") + elif arr.ndim != 1: + raise Exception("Fehler") + return arr + + +def poly_derivate_coeffs(a): + a = _as_1d_array(a) + if a.size < 2: + return np.array([0.0], dtype=float) + dcoeffs = np.empty((a.size-1), dtype=float) + for k in range(1, a.size): + dcoeffs[k-1] = k * a[k] + return dcoeffs + +def poly_integrate_coeffs(a, C=0.0): + a = _as_1d_array(a) + if a.size < 1: + return np.array([C], dtype=float) + coeffs = np.empty(a.size+1, dtype=float) + coeffs[0] = C + for k in range(a.size): + coeffs[k+1] = a[k] / (k + 1) + + return coeffs + +def poly_eval(a, x): + a = _as_1d_array(a) + x = np.asarray(x, dtype=float) + y = np.zeros_like(x, dtype=float) + xpow = np.ones_like(x, dtype=float) + for ak in a: + y += ak * xpow + xpow *= x + return y + + # + # Berechnet p(x), p'(x) und P(x) (mit C=0) für das Polynom mit Koeffizienten a0..an auf [xmin, xmax]. + # + # Input: + # a : Sequenz [a0, a1, ..., an] (vom konstanten Term bis Grad n) + # xmin : Intervallanfang (xmin < xmax) + # xmax : Intervallende + # + # Output: + # x : äquidistante Stützstellen in [xmin, xmax] + # p : Werte von p(x) + # dp : Werte von p'(x) + # Pint : Werte der Stammfunktion P(x) mit Integrationskonstante C=0 + # + + +def Kuengjoe_S01_Aufg2(a, xmin, xmax): + + a = _as_1d_array(a) + + if not np.isscalar(xmin) or not np.isscalar(xmax): + raise Exception("Fehler") + xmin = float(xmin); xmax = float(xmax) + if not (xmin < xmax): + raise Exception("Fehler") + + m = 1000 + x = np.linspace(xmin, xmax, m+1) + + d = poly_derivate_coeffs(a) + P = poly_integrate_coeffs(a, C=0.0) + + + p = poly_eval(a, x) + dp = poly_eval(d, x) + pint = poly_eval(P, x) + + return (x, p, dp, pint) \ No newline at end of file diff --git a/Kuengjoe_S01/Kuengjoe_S01_Aufg2_skript.py b/Kuengjoe_S01/Kuengjoe_S01_Aufg2_skript.py new file mode 100644 index 0000000..14b7fbc --- /dev/null +++ b/Kuengjoe_S01/Kuengjoe_S01_Aufg2_skript.py @@ -0,0 +1,24 @@ +# Name_S01_Aufg2_skript.py +import numpy as np +import matplotlib.pyplot as plt +from Kuengjoe_S01_Aufg2 import Kuengjoe_S01_Aufg2 + +if __name__ == "__main__": + # Reproduktion der Abbildung aus Aufgabe 1: gleiches Polynom und Intervall + a = [-105, 29, 110, -30, -5, 1] # a0..a5 für f(x)=x^5-5x^4-30x^3+110x^2+29x-105 + xmin, xmax = -10, 10 + + x, p, dp, pint = Kuengjoe_S01_Aufg2(a, xmin, xmax) + + plt.figure() + plt.plot(x, p, label="p(x)") + plt.plot(x, dp, label="p'(x)", linestyle="--") + plt.plot(x, pint, label="P(x) (C=0)", linestyle=":") + plt.ylim(-2500, 2500) + plt.xlabel("x") + plt.xlabel("x") + plt.ylabel("Wert") + plt.title("Polynom, Ableitung und Stammfunktion") + plt.grid(True) + plt.legend() + plt.show() diff --git a/Kuengjoe_S01/Kuengjoe_S01_Aufg3.py b/Kuengjoe_S01/Kuengjoe_S01_Aufg3.py new file mode 100644 index 0000000..0d3ff11 --- /dev/null +++ b/Kuengjoe_S01/Kuengjoe_S01_Aufg3.py @@ -0,0 +1,78 @@ +import numpy as np +import timeit + +def fact_rec(n): + if n < 0 or np.trunc(n) != n: + raise Exception('only positive integers') + if n <= 1: + return 1 + return int(n) * fact_rec(int(n) - 1) + +def fact_for(n): + if n < 0 or np.trunc(n) != n: + raise Exception('only positive integers') + n = int(n) + res = 1 + for k in range(2, n + 1): + res *= k + return res + +def _time_functions(n=500, repeats=5, number=100): + t1 = timeit.repeat("fact_rec(n)", setup="from __main__ import fact_rec, n", number=number, repeat=repeats) + t2 = timeit.repeat("fact_for(n)", setup="from __main__ import fact_for, n", number=number, repeat=repeats) + return float(np.mean(t1)), float(np.mean(t2)) + +def _print_integer_tests(): + print("\nInteger-Tests: n! für n ∈ [190..200] (Ziffernanzahl)") + for n in range(190, 201): + val = fact_for(n) + print(f"{n}! hat {len(str(val))} Ziffern") + +def _print_float_tests(): + print("\nFloat-Tests: 170! und 171! als float") + for n in [170, 171]: + val = fact_for(n) + try: + fval = float(val) + print(f"{n}! als float: {fval}") + except OverflowError as e: + print(f"{n}! als float: OverflowError ({e})") + +if __name__ == "__main__": + print("Korrektheitstest:") + for n in [0, 1, 5, 10]: + r = fact_rec(n) + f = fact_for(n) + print(f"{n}! -> rec: {r}, for: {f}, equal: {r == f}") + + n = 500 + repeats = 5 + number = 100 + avg_rec, avg_for = _time_functions(n=n, repeats=repeats, number=number) + + print("\nTiming:") + print(f"n={n}, repeats={repeats}, number={number}") + print(f"Rekursiv: {avg_rec:.6f} s") + print(f"Iterativ: {avg_for:.6f} s") + if avg_for > 0: + ratio = avg_rec / avg_for + if ratio >= 1: + print(f"Iterativ ist ~{ratio:.2f}x schneller") + else: + print(f"Rekursiv ist ~{1/ratio:.2f}x schneller") + + _print_integer_tests() + _print_float_tests() + + # --- Antworten (Aufgabe 3) --- + # 1) Welche Funktion ist schneller? + # In der Praxis die iterative Version (geringerer Funktionsaufruf-Overhead). + # Faktor (bitte hier Ihren gemessenen Wert ausgeben und eintragen): + # z.B. iterativ ≈ 3.2x schneller als rekursiv bei n=500 (100 Läufe, 5 Wiederholungen). + + # 2) Grenze als Integer: + # Python-Integer haben beliebige Präzision -> keine feste Obergrenze für n! (nur Zeit/Speicher). + + # 3) Grenze als Float (double, float64): + # 170! ist noch als float darstellbar; 171! führt zu Overflow (inf/OverflowError bei Umwandlung). + diff --git a/test_Aufg2.py b/test_Aufg2.py new file mode 100644 index 0000000..a2543bb --- /dev/null +++ b/test_Aufg2.py @@ -0,0 +1,40 @@ +from Kuengjoe_S01.Kuengjoe_S01_Aufg2 import _as_1d_array +from Kuengjoe_S01.Kuengjoe_S01_Aufg2 import poly_derivate_coeffs +from Kuengjoe_S01.Kuengjoe_S01_Aufg2 import poly_integrate_coeffs + + +import numpy as np + +def _test_as_1d_array(): + def run_case(name, a): + try: + arr = _as_1d_array(a) + print(f"[OK] {name:22s} -> shape={arr.shape}, ndim={arr.ndim}, dtype={arr.dtype}, values={arr}") + except Exception as e: + print(f"[ERRORE] {name:22s} -> {e}") + + print("=== Test _as_1d_array ===") + run_case("Lista 1D", [1, 2, 3]) + run_case("Array NumPy 1D", np.array([1, 2, 3])) + run_case("Vettore riga 1xN", np.array([[1, 2, 3]])) + run_case("Vettore colonna Nx1", np.array([[1], [2], [3]])) + run_case("Misto tipi -> float", [1, 2.5, "3"]) # verrà convertito a float + run_case("Lista vuota", []) + run_case("Matrice 2x2", np.array([[1, 2], [3, 4]])) + run_case("Scalare", 5) + run_case("Tensore 3D", np.arange(8).reshape(2, 2, 2)) + +if __name__ == "__main__": + _test_as_1d_array() + array = np.array([[2,5,6]]) + arr = _as_1d_array(array) + print("Input array: "+str(array)) + print("coeff: "+str(arr)) + print("coeff derivate: "+str(poly_derivate_coeffs(arr))) + print("coeff integrate: "+str(poly_integrate_coeffs(arr))) + + a = np.array([[2, 5, 6]]) # 1x3 -> verrà reso 1D + a = _as_1d_array(a) + print("coeff:", a) + print("coeff derivate:", str(poly_derivate_coeffs(a))) # atteso [5., 12.] + print("coeff integrate:", poly_integrate_coeffs(a)) \ No newline at end of file