Ich definiere ein Monom, ein Polynom ist dann eine Summe von Monomen:
class Monom():
def __init__(self, c, e):
self.c = c
self.e = e
Dabei ist c der Koeffizient und e ein np.array, das den Exponentenvektor darstellt, z.B. wäre
2.5x^2y^5z
als
h1 = Monom(2,5, np.array([2,5,1]))
dargestellt.
Da man arrays nicht lexikorafisch verggleichen kann, bilde ich daraus eine Liste und definiere Funktionen
lt, gt, eq
die das gewünschte Ergebnis liefern.
Bei der Abfrage
if eq(m.e, b.e):
will ich zwei Exponentenvektoren verleichen, erhalte aber die Fehlermeldung
File "C:\Users\hubert grassmann\py\p.py", line 61, in addm
if lt(m.e, b[0]).e:
File "C:\Users\hubert grassmann\py\p.py", line 47, in lt
ba = [b[0],b[1],b[2]]
TypeError: 'Monom' object is not subscriptable
Dabei ist ba die aus einem Exponentenvektor eines Monoms gebildete Liste, nämlich von b[0].e, aber kein Monom.
Computeralgebra
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Ich habe die Listen (aus meiner Frage nach falschem Rechnen) durch np.array ersetzt, es tritt derselbe Effekt auf.
Sollten nicht verschiedene Bezeichner auf verschiedene Objekte verweisen?
Wenn ich a = np.array([1]) und b = a festlege und a ändere, ändert sich dann auch b?
Sollten nicht verschiedene Bezeichner auf verschiedene Objekte verweisen?
Wenn ich a = np.array([1]) und b = a festlege und a ändere, ändert sich dann auch b?
Also den Teil kann ich beantworten: "Nein" und "Ja"hubertgrassmann hat geschrieben: ↑Montag 26. Dezember 2022, 19:08 Sollten nicht verschiedene Bezeichner auf verschiedene Objekte verweisen?
Wenn ich a = np.array([1]) und b = a festlege und a ändere, ändert sich dann auch b?
Nach b = a verweisen beiden Namen (a und jetzt auch b) auf das Objekt das vorher nur über a zugreifbar war. Einfach mal
Code: Alles auswählen
a = np.array([1])
print(id(a))
b = a
print(id(b))
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Ich programmiere seit ca. 40 Jahren, dieses Verhalten ist unerwartet:
import numpy as np
a = np.array([1])
print("a",a)
b = a.copy()
a[0] = 15
print("b",b)
"""Ausgabe ohne das angehängte copy
a [1]
b [15]
"""
mit copy kommt die erwartete Ausgabe des Werts von b
import numpy as np
a = np.array([1])
print("a",a)
b = a.copy()
a[0] = 15
print("b",b)
"""Ausgabe ohne das angehängte copy
a [1]
b [15]
"""
mit copy kommt die erwartete Ausgabe des Werts von b
In Python ist dieses Verhalten seit ca. 30 Jahren erwartet. In vielen anderen Sprachen (den meisten anderen?) auch.
Ein `=` macht in Python keine Kopie, sondern bindet einen Wert an einen Namen. Mit `<name> = <expr>` wird der Wert der Expression auf der rechten Seite des `=` an den Namen auf der linken Seite gebunden. Also: Nach `a = 42` ist der Wert von `42` (also 42) an den Namen `a` gebunden. Nach `b = a` ist der Wert der Expression `a` (also immer noch die gleiche 42) zusätzlich (!) an den Namen `b` gebunden.
Auch wenn es nach 40 Jahren wahrscheinlich schwer fällt: Eine neue Sprache kann man nicht lernen, indem man das ganze Wissen aus einer anderen Sprache 1 zu 1 kopiert (und geschweifte Klammern durch Doppelpunkte und Einrückungen ersetzt). Man muss immer auch einen Schritt zurückgehen und sich klar machen, welches alte Wissen man nicht mitnehmen kann.
Und bitte für Code Codeblöcke benutzen, dann bleibt die Einrückung erhalten, [ i ] wird nicht als „kursiv“ interpretiert und man kann den Code lesen.
Ein `=` macht in Python keine Kopie, sondern bindet einen Wert an einen Namen. Mit `<name> = <expr>` wird der Wert der Expression auf der rechten Seite des `=` an den Namen auf der linken Seite gebunden. Also: Nach `a = 42` ist der Wert von `42` (also 42) an den Namen `a` gebunden. Nach `b = a` ist der Wert der Expression `a` (also immer noch die gleiche 42) zusätzlich (!) an den Namen `b` gebunden.
Auch wenn es nach 40 Jahren wahrscheinlich schwer fällt: Eine neue Sprache kann man nicht lernen, indem man das ganze Wissen aus einer anderen Sprache 1 zu 1 kopiert (und geschweifte Klammern durch Doppelpunkte und Einrückungen ersetzt). Man muss immer auch einen Schritt zurückgehen und sich klar machen, welches alte Wissen man nicht mitnehmen kann.
Und bitte für Code Codeblöcke benutzen, dann bleibt die Einrückung erhalten, [ i ] wird nicht als „kursiv“ interpretiert und man kann den Code lesen.
Aber Achtung: Zuweisung einerseits und Änderung eines (änderbaren) Objekts andererseits tun Verschiedenes, gerade auch im Hinblick auf zwei Namen für dasselbe Ding:narpfel hat geschrieben: ↑Montag 26. Dezember 2022, 23:34 In Python ist dieses Verhalten seit ca. 30 Jahren erwartet. In vielen anderen Sprachen (den meisten anderen?) auch.
Ein `=` macht in Python keine Kopie, sondern bindet einen Wert an einen Namen. Mit `<name> = <expr>` wird der Wert der Expression auf der rechten Seite des `=` an den Namen auf der linken Seite gebunden. Also: Nach `a = 42` ist der Wert von `42` (also 42) an den Namen `a` gebunden. Nach `b = a` ist der Wert der Expression `a` (also immer noch die gleiche 42) zusätzlich (!) an den Namen `b` gebunden.
Code: Alles auswählen
a = 42
b = a
print(a, b)
42 42
a = 21
print(a, b)
21 42
a = [1, 3, 5]
b = a
print(a, b)
[1, 3, 5] [1, 3, 5]
a.append(7)
print(a, b)
[1, 3, 5, 7] [1, 3, 5, 7]
a = a[:3]
print(a, b)
[1, 3, 5] [1, 3, 5, 7]
@bb1898: Deine Erklärung und den Codeabschnitt finde ich eher verwirrend für den TE als hilfreich.
Wie man sieht, sind an an und b nach der Zuweisung "b=a" das selbe Objekt gebunden.
MIt b = 43 bindet man ein anderees Objekt (Integer mit dem Wert 43) an den Namen "b".
Ansonsten weiß ich nicht, worauf du hinaus willst, denn das vehält sich bei Listen ja gleich:
Code: Alles auswählen
>>> a = 42
>>> b = a
>>> id(a)
1766869528144
>>> id(b)
1766869528144
>>> b = 43
>>> id(b)
1766869528176
MIt b = 43 bindet man ein anderees Objekt (Integer mit dem Wert 43) an den Namen "b".
Ansonsten weiß ich nicht, worauf du hinaus willst, denn das vehält sich bei Listen ja gleich:
Code: Alles auswählen
>>> a = []
>>> b = a
>>> id(a)
1766910889344
>>> id(b)
1766910889344
>>> b = []
>>> id(b)
1766905651328
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Ich habe diese Erfahrung nun hinter mir: für den Exponentenvektor der Monome hatte ich eine Variable e vereibart und für jedes Monom neu belegt, was sich aber nur lokal auswirkte (korrekte Ausgabe), aber am Ende hatte der letzte gewonnen.
Viel Dank für die Hinweise.
Ich probiere doch, durch weglassen von { } ; aus einem Java-Programm eins für Python zu machen, ganz hoffnungslos bin ich nicht.
Viel Dank für die Hinweise.
Ich probiere doch, durch weglassen von { } ; aus einem Java-Programm eins für Python zu machen, ganz hoffnungslos bin ich nicht.
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Ich hatte einen gewissen Erfolg:
ca. 100 Zeilen Quelltext ermöglichen formales Rechnen mit "Variablen" z, y, z, also mit Polynonen.
ein Beispiel: Es wird für das Anfangspolynom die 2., 4., 8. Potzenz berechnet
+x-1z
a = +x^2-2xz+z^2
+x^4-4x^3z+6x^2z^2-4xz^3+z^4
+x^8-8x^7z+28x^6z^2-56x^5z^3+70x^4z^4-56x^3z^5+28x^2z^6-8xz^7+z^8
gibt es Interesse?
ca. 100 Zeilen Quelltext ermöglichen formales Rechnen mit "Variablen" z, y, z, also mit Polynonen.
ein Beispiel: Es wird für das Anfangspolynom die 2., 4., 8. Potzenz berechnet
+x-1z
a = +x^2-2xz+z^2
+x^4-4x^3z+6x^2z^2-4xz^3+z^4
+x^8-8x^7z+28x^6z^2-56x^5z^3+70x^4z^4-56x^3z^5+28x^2z^6-8xz^7+z^8
gibt es Interesse?
- __blackjack__
- User
- Beiträge: 13241
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@hubertgrassmann: Also wenn der Ausgangspunkt Java ist, verstehe ich nicht so ganz die ursprüngliche Überraschung bei der Zuweisung/Übergabe und dem ändern von Objekten, weil sich Java da ja bei Objekten wie Python verhält. Das Beispiel aus Deinem anderen Thema liefert in Java exakt das gleiche Verhalten:
Ausgabe:
Aber auch wenn sich Java und Python in dem Aspekt sehr ähnlich sind, ist es keine gute Idee einfach nur geschweifte Klammern und Semikolons weg zu lassen (das auch Java-Quelltext ordentlich eingerückt ist, setze ich hier mal voraus). Die Sprachen unterscheiden sich in der idiomatischen Verwendung an einigen Punkten, hier und da in technischen Details, und auch die Richtlinien an die sich fast alle Programmierer halten, weisen Unterschiede auf.
Zum Beispiel gilt zwar auch bei Java das man gute, aussagekräftige Namen wählen sollte, durch die statische Typisierung ist es aber in der Regel okay für lokale Namen Abkürzungen zu verwenden wenn da gleich in der Nähe die ordentlich benannte Typdeklaration steht. Also in Python wäre ``b = do_something()`` nicht okay, während das bei Java in ``Butterfly b = doSomething();`` in kurzen Funktionen akzeptabel ist, weil die Bedeutung von `b` durch die Typdeklaration klar ist. Während ``var b = doSomething();`` auch in Java nicht gut ist. Und das gilt natürlich nur wenn `b` tatsächlich nur für das generische `Butterfly` steht. Sollte das die Abkürzung für den Oberschmetterling sein, dann sollte das auch mit Typdeklaration ``Butterfly boss = doSomething();`` heissen.
Wenn ich mir Deine maximal zwei Buchstaben pro Namen Beispiele so anschaue, möchte ich den Code wahrscheinlich eher nicht sehen.
Code: Alles auswählen
import java.util.Arrays;
public final class Test {
private Test() {}
private static void print(int[] a) {
System.out.println(Arrays.toString(a));
}
private static void print(Object[] a) {
System.out.println(Arrays.deepToString(a));
}
private static int[][] ma(int[] m, int[][] a) {
for (var p: a) p[0] = p[0] + m[0];
return a;
}
public static void main(String... args) {
var h1 = new int[] {1};
var h2 = new int[] {2};
var h3 = new int[] {3};
var b = new int[][]{h1, h2, h3};
print(h2);
print(b);
var c = ma(h2, b);
print(c);
}
}
Code: Alles auswählen
[2]
[[1], [2], [3]]
[[3], [4], [7]]
Zum Beispiel gilt zwar auch bei Java das man gute, aussagekräftige Namen wählen sollte, durch die statische Typisierung ist es aber in der Regel okay für lokale Namen Abkürzungen zu verwenden wenn da gleich in der Nähe die ordentlich benannte Typdeklaration steht. Also in Python wäre ``b = do_something()`` nicht okay, während das bei Java in ``Butterfly b = doSomething();`` in kurzen Funktionen akzeptabel ist, weil die Bedeutung von `b` durch die Typdeklaration klar ist. Während ``var b = doSomething();`` auch in Java nicht gut ist. Und das gilt natürlich nur wenn `b` tatsächlich nur für das generische `Butterfly` steht. Sollte das die Abkürzung für den Oberschmetterling sein, dann sollte das auch mit Typdeklaration ``Butterfly boss = doSomething();`` heissen.
Wenn ich mir Deine maximal zwei Buchstaben pro Namen Beispiele so anschaue, möchte ich den Code wahrscheinlich eher nicht sehen.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
an blackjack
Danke für die Belehrung, ich habe natürlich beim Weglassen nachgedacht. Die probeweise eingeführten Funktionen lt, gt, eq werden Fortran-Kennern bekannt vorkommen.
Die von mir implementierten Punktionen heißen add, mult und write, deren Wirkung ist wohl gut verständlich; die Eingabemöglichkeiten sind noch nicht optimal.
Danke für die Belehrung, ich habe natürlich beim Weglassen nachgedacht. Die probeweise eingeführten Funktionen lt, gt, eq werden Fortran-Kennern bekannt vorkommen.
Die von mir implementierten Punktionen heißen add, mult und write, deren Wirkung ist wohl gut verständlich; die Eingabemöglichkeiten sind noch nicht optimal.
Das hört sich an, als ob man die Monom- bzw. Polynom-Klassen mit den entsprechenden special methods sinnvoll aufrüsten könnte (Vergleiche, Multiplikation, Addition, ...).hubertgrassmann hat geschrieben: ↑Mittwoch 28. Dezember 2022, 18:39 an blackjack
Danke für die Belehrung, ich habe natürlich beim Weglassen nachgedacht. Die probeweise eingeführten Funktionen lt, gt, eq werden Fortran-Kennern bekannt vorkommen.
Die von mir implementierten Punktionen heißen add, mult und write, deren Wirkung ist wohl gut verständlich; die Eingabemöglichkeiten sind noch nicht optimal.
Gibt es das nicht alles schon mit https://docs.sympy.org/latest/modules/p ... rence.html ?
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
an deets
Ich habe es mir angesehen, es geht sicher etwas weniger aufwendig
an bord0
ich weiß nicht, wie man Polynome vergleichen will.
Sinnvolle Erweiterungen wäre ggT-Berechnung, Nullstellenmenge von F(x,y,z) (das ist eine algebraische Fläche) grafisch darstellen
Ich habe es mir angesehen, es geht sicher etwas weniger aufwendig
an bord0
ich weiß nicht, wie man Polynome vergleichen will.
Sinnvolle Erweiterungen wäre ggT-Berechnung, Nullstellenmenge von F(x,y,z) (das ist eine algebraische Fläche) grafisch darstellen
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Verzeiung: ggt bei Polynomen in einer Variablen
- __blackjack__
- User
- Beiträge: 13241
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@hubertgrassmann: Wenn Du jetzt gesagt hättest, dass man die Funktionsnamen von den entsprechenden ”magischen” Methoden von Python kennt, okay, aber FORTRAN ist doch schon ziemlich weit weg von Python und Sprach- und Entwurfsentscheidungen die aus *den* Zeiten stammen, sollten heute keine Massstäbe für gute Namen sein. Man kennt die vielleicht auch aus Shell-Programmierung als Argumentnamen für ``test`` oder in der PowerShell wo ``<`` und ``>`` ja schon für Umleitungen von Ein- und Ausgaben verwendet werden, oder aus Perl wo man eine Unterscheidung zwischen Zahlenvergleich und Zeichenkettenvergleich braucht. Ebenso als Operatoren von alten Microsoft-BASIC-Compilern, als Rückfalloption für Rechner wo es so exotische Sachen wie ``<`` oder ``>`` nicht auf der Tastatur gibt, oder wo solche Sonderzeichen schwierig(er) einzugeben sind.
Nur sollte man halt keinen Code schreiben den nur Leute verstehen die schon so lange dabei sind, dass die ersten Erfahrungen mit BASIC-Dialekten gesammelt wurden, die nur 1 bis 2 Buchstaben lange Namen erlaubt haben (mein Erstkontakt: CBM BASIC V2 auf einem C64). Teilweise sogar nur 1 Buchstabe (Beispiel: ZX Spektrum für alles ausser skalare Zahlen). Best practice heute ist es nicht kryptisch abzukürzen, und in der Regel gibt es auch eine Konvention für Funktionen und Methoden die einen Wahrheitswert zurück geben. Also hier `is_less_than()`, `is_greater_than()`, und `is_equal()`. Wobei, wie von bords0 schon angemerkt, das prima Kandidaten für Operatorüberladung zu sein scheinen, so das man dann einfach ``<``, ``>``, und ``==`` mit den Objekten verwenden kann. Das ist etwas was in Java nicht geht, in Python aber schon.
Nur sollte man halt keinen Code schreiben den nur Leute verstehen die schon so lange dabei sind, dass die ersten Erfahrungen mit BASIC-Dialekten gesammelt wurden, die nur 1 bis 2 Buchstaben lange Namen erlaubt haben (mein Erstkontakt: CBM BASIC V2 auf einem C64). Teilweise sogar nur 1 Buchstabe (Beispiel: ZX Spektrum für alles ausser skalare Zahlen). Best practice heute ist es nicht kryptisch abzukürzen, und in der Regel gibt es auch eine Konvention für Funktionen und Methoden die einen Wahrheitswert zurück geben. Also hier `is_less_than()`, `is_greater_than()`, und `is_equal()`. Wobei, wie von bords0 schon angemerkt, das prima Kandidaten für Operatorüberladung zu sein scheinen, so das man dann einfach ``<``, ``>``, und ``==`` mit den Objekten verwenden kann. Das ist etwas was in Java nicht geht, in Python aber schon.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Ich hatte die Vergleiche erwähnt, weil du von lt, gt, eq geschrieben hattest. Das hatte ich so verstanden, dass du Vergleichsfunktionen schreiben willst. (Ich hatte deinem Post entnommen, dass es darum geht, die Koeffizientenfolgen miteinander zu vergleichen, aber vielleicht ist etwas anderes gemeint.)hubertgrassmann hat geschrieben: ↑Mittwoch 28. Dezember 2022, 19:18 an bord0
ich weiß nicht, wie man Polynome vergleichen will.
-
- User
- Beiträge: 61
- Registriert: Montag 26. Dezember 2022, 14:53
Ich habe einen Modul Rxy fertigestellt (formales Rechnen mit Unbestimmten x, y) und kann die Lösungen von
+0.3x^2+0.2xy^2+0.1y^3+0.5y^2-1=0
plotten (eine komische Kurve, ich würde sie gern zeigen): in einer Liste w stehen alle Punktkoorinaten und ich starte
for p in w:
plt.plot(p[0],p[1],'.r')
Das klappt nicht ohne '.r', auch nicht mit '-r', es ergibt sich also ein recht grobes Bild.
In allen Beispielen, die ich gesehn habe, wird einfach
plt.plot(x,y)
aufgerufen. Was mache ich falsch?
+0.3x^2+0.2xy^2+0.1y^3+0.5y^2-1=0
plotten (eine komische Kurve, ich würde sie gern zeigen): in einer Liste w stehen alle Punktkoorinaten und ich starte
for p in w:
plt.plot(p[0],p[1],'.r')
Das klappt nicht ohne '.r', auch nicht mit '-r', es ergibt sich also ein recht grobes Bild.
In allen Beispielen, die ich gesehn habe, wird einfach
plt.plot(x,y)
aufgerufen. Was mache ich falsch?
Statt jedes Mal für jeden Punkt ein Plot Kommando aufzurufen, Bilde zwei Listen x und y. Und rufe damit einmal Plot auf.
Der kanonische Weg das zu tun ist
Der kanonische Weg das zu tun ist
Code: Alles auswählen
x, y = zip(*w)