SymPy: Warum funktioniert hier das Vereinfachen eines mathematischen Ausdrucks nicht?

4 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Ich habe Python mal ausprobiert gehabt, aber da mir die Art und Weise wie in Python Arrays indiziert werden nicht gefallen hat, habe ich diese Programmiersprache nicht mehr weiter verfolgt.

Ich hätte da mal eine Gegenfrage, und zwar -->

Was soll dein Programm eigentlich leisten ?

Soll es

(12sin(2)2sin(4)sin(x) + 3sin(8)sin(x) + 12sin(2)sin(x) + 40sin(2)*2sin(4)cos(x) + 10sin(8)cos(x) + 40sin(2)cos(x))/(2(sin(4) + 2*sin(2)))

zu 3 * sin(x) + 10 * cos(x) vereinfachen, oder wie ist das zu verstehen ?

Oder soll das zu 3 * sin(x) + 10 * cos(x) approximiert werden, wobei der Fehler so gering wie möglich zu halten ist ?


precursor  16.02.2019, 15:44

Anmerkung :

Irgendwas stimmt da nicht -->

1.)

(12 * SIN(2) * 2 * SIN(4) * SIN(x) + 3 * SIN(8) * SIN(x) + 12 * SIN(2) * SIN(x) + 40 * SIN(2) * 2 * SIN(4) * COS(x) + 10 * SIN(8) * COS(x) + 40 * SIN(2) * COS(x)) / (2 * (SIN(4) + 2 * SIN(2)))

ist nicht identisch mit 3 * SIN(x) + 10 * COS(x)

2.)

-1.2413734172586 * SIN(x) - 4.1379113908621 * COS(x)

approximiert viel besser als 3 * SIN(x) + 10 * COS(x)

Hast du dich irgendwo verschrieben ?

0
precursor  16.02.2019, 16:01
@precursor

Anmerkung :

(12 * SIN(2) * 2 * SIN(4) * SIN(x) + 3 * SIN(8) * SIN(x) + 12 * SIN(2) * SIN(x) + 40 * SIN(2) * 2 * SIN(4) * COS(x) + 10 * SIN(8) * COS(x) + 40 * SIN(2) * COS(x)) / (2 * (SIN(4) + 2 * SIN(2)))

ist auch nicht mit 10 * COS(x) + 3 * COS(x) identisch.

0
michiwien22 
Fragesteller
 16.02.2019, 16:52
@precursor

(12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2)))

ist identisch mit

3*sin(x)+10*cos(x)

Du hast meine ** durch * ersetzt, in Python ist das Zeichen für "hoch ^" der Operator "**"

1
precursor  16.02.2019, 16:55
@michiwien22

In deinem Originaltext tauchen die ** gar nicht auf, scheinbar hat der GF - Editor die verschluckt.

Wie lautet der Ausdruck denn vernünftig hingeschrieben ?

1
michiwien22 
Fragesteller
 16.02.2019, 17:01
@precursor

Ach Gott, der sch... Editor bei GF... das wurde bei copy/paste verschluckt.

Der Ausdruck lautet:

u(x) = (12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2)))

1
precursor  16.02.2019, 17:03
@michiwien22

Ja, daran ist der GF-Editor Schuld, ich erinnere mich in der Vergangenheit schon mal ähnliche Probleme gelesen zu haben, die Leute mit dem GF-Editor hatten.

1
michiwien22 
Fragesteller
 16.02.2019, 17:04
@precursor

Problem ist, dass man auch nichts mehr ändern kann, wenn die Zeit abgelaufen ist. Das ist jener Faktor, der mich hier am allermeisten stört...Aber das hier habe ich selbst nicht bemerkt.

1
precursor  16.02.2019, 17:05
@michiwien22

Jetzt ist aber Dank deines Kommentare für jeden ersichtlich, wie es exakt gemeint ist.

1
michiwien22 
Fragesteller
 16.02.2019, 16:59

Es geht hier nicht um ein konkretes Problem, für welches ich ein Skript schreibe, sondern ich probiere SymPy einfach mal quer durch den Gemüsegarten aus.

Die Aufgabe hier wäre:

Gegeben ist eine funktion f(x). Approximiere diese durch eine Linearkombination eines Sets aus Funktionen λ_i(x), sodass die Summe der qauadratischen Abweichungen minimal wird (ein klassischer Funktions-Fit also).

Nun wäre meine Funktion f(x) = 3 * SIN(x) + 10 * COS(x)

und meine Basisfuinktionen

λ1(x) = SIN(x)

λ2(x) = COS(x)

Das Prgramm ermittelt die Koeffizienten c1=3, c2=10 richtig und bekommt den Ausdruck

u(x) = (12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2)))

Das ist vereinfacht wieder 3 * SIN(x) + 10 * COS(x); somit funktioniert das Programm (hier ist die Anpassung eben perfekt), nur verstehe ich nicht, wieso SymPy es nicht schafft, den Ausdruck zu vereinfachen.

1
michiwien22 
Fragesteller
 16.02.2019, 17:15
@precursor

Habe noch ein Beispiel eingefügt, wo es klaglos funktioniert. Neue Eigenantwort.

1
precursor  18.02.2019, 10:11

Vielen Dank für den Stern !

Schade, dass du nicht mehr Antworten bekommen hast, außer meiner.

0

Für die zu fittende Funktion

f(x) = x + (x - 1)² + 1

und den Basisfunktionen (1, x)

findet man für das Intervall [1,2]

den Fit

u(x) = 2*x-1/6

Wie man sieht, ist das die richtige Lösung.

Hier hat SymPy kein Problem und gibt einen Ausdruck, der nicht weiter vereinfacht werden kann.

Bild zum Beitrag

function to approximate: x + (x - 1)**2 + 1

Basic functions:

 - 1

 - x

simplified u:

2*x - 1/6

Ich hoffe es wird klar, worauf ich hinaus will.

 - (Computer, Mathematik, programmieren)

Hier nochmal das Python Skript in lesbarer Form:


import sympy as sym

def functionFit(f, funcset, interval):

	N = len(funcset) - 1

	A = sym.zeros(N+1, N+1)

	b = sym.zeros(N+1, 1)

	x = sym.Symbol('x')

	for i in range(N+1):

		for j in range(i, N+1):

			A[i,j] = sym.integrate(funcset[i]*funcset[j],

			(x, interval[0], interval[1]))

			A[j,i] = A[i,j]

		b[i,0] = sym.integrate(funcset[i]*f, (x, interval[0], interval[1]))

	c = A.LUsolve(b)

	u = 0

	for i in range(len(funcset)):

		u += c[i,0]*funcset[i]

	return u, c

	
x = sym.Symbol('x')

f = 10*sym.cos(x)+3*sym.sin(x)

fooset=(sym.sin(x), sym.cos(x))

interval = (1,2)

print("function to approximate:", f)

print("Basic functions:")

for foo in fooset:

	print(" - ", foo)

u,c = functionFit(f, fooset, interval)

print()

print("simplified u:")

print(sym.simplify(u))

print()

print("simplified c:")

print(sym.simplify(c))

Setze ich aber

f = 10sym.cos(x)+3sym.sin(x)

meinte ich natürlich.