Szukanie miejsc zerowych w Pythonie wykorzystując PyQt

0

Witam wszystkich. Otóż mam problem z aplikacją którą muszę napisać w języku Python z użyciem PyQt. Program ma wyszukiwać miejsca zerowe wielomianu podanego stopnia na odpowiednim podanym zakresie i wypisywać je w wierszu poleceń IDLEX oraz rysować ten wielomian jednakże zinterpolowany. Ale reszta z tym aktualnie jestem na etapie początkowym i stworzyłem właśnie zdarzenie dla przycisku oraz metodę bisekcji (musi być użyta ta metoda oraz siecznych ale nie w tym rzecz). Otóż po kliknięciu przycisku Metoda bisekcji program się wysypuje i nic z tego nie ma. Fajnie gdyby ktoś wytłumaczył co jest nie tak i pomógł w możliwy sposób. Po prostu pytam bo nie wiem co jest nie tak dla jasności :) Mam tak od początku i nie wiem co z tym zrobić oto kod programu:


```import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QPushButton,
                             QLabel, QGridLayout,
                             QLineEdit, QApplication)
from matplotlib.pyplot import plot, show
from scipy import interpolate
from numpy import arange, exp

class Program(QWidget):
    
    def __init__(self):
        super().__init__()

        self.lbl1 = QLabel('Podaj stopień wielomianu')
        self.lbl2 = QLabel('Podaj zakres szukania')
        self.btn1 = QPushButton('Metoda bisekcji')
        self.btn2 = QPushButton('Metoda siecznych')
        self.text1 = QLineEdit()
        self.text2 = QLineEdit()

        siatka = QGridLayout()
        siatka.setSpacing(10)

        siatka.addWidget(self.lbl1, 1, 0)
        siatka.addWidget(self.text1, 1, 1)

        siatka.addWidget(self.lbl2, 2, 0)
        siatka.addWidget(self.text2, 2, 1)
        
        siatka.addWidget(self.btn1, 3, 0)
        siatka.addWidget(self.btn2, 3, 1)

        self.btn1.clicked.connect(self.bisectionClicked)

        self.setLayout(siatka)

        self.setGeometry(300, 300, 450, 150)
        self.setWindowTitle('Wyszukiwanie miejsc zerowych')
        self.show()

    def bisectionClicked(self):
        nText=self.text1.text()
        n=int(nText)
        zakresText=self.text2.text()
        zakresSplit=zakresText.split(',');
        xp=float(zakresSplit[0])
        xk=float(zakresSplit[1])
        self.bisekcja(xp,xk,0.01,n);

    def wielomian(n,x):
        return 5*x**n-7*x**2+3*x+random()

    def bisekcja(self,xp,xk,dokladnosc,n):
            while np.absolute(xp-xk)>dokladnosc:
                punktSrodkowy=(xp+xk)*0.5
                if wielomian(n,punktSrodkowy)*wielomian(n,xp)<0:
                    xk=punktSrodkowy
                punktSrodkowy=(xp+xk)*0.5
                if wielomian(npunktSrodkowy)*wielomian(n,xk)<0:
                    xp=punktSrodkowy
                    miejsceZero=xk-(xk-xp)*wielomian(n,xk)/(wielomian(n,xk)-wielomian(n,xp))
                    if miejsceZero is None:
                        print('Brak znalezionego miejsca zerowego')
                    else: print(miejsceZero)
                


if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Program()
    sys.exit(app.exec_())
0

Podstawowa rzecz, czy Twoja funkcja licząca root metodą bisekcji jest poprawna?

0

Używałem tej funkcji również bez użycia w PyQt więc powinna być prawidłowa jedyne co dopisałem to

if miejsceZero is None:
                        print('Brak znalezionego miejsca zerowego')
                    else: print(miejsceZero)

Dopisałem bo w pierwotnej wersji funkcja zwracała miejsce zerowe a ja chciałem żeby wykonywało się to już tutaj.

0
Piotr0396 napisał(a):

Używałem tej funkcji również bez użycia w PyQt więc powinna być prawidłowa jedyne co dopisałem to

if miejsceZero is None:
                        print('Brak znalezionego miejsca zerowego')
                    else: print(miejsceZero)

Dopisałem bo w pierwotnej wersji funkcja zwracała miejsce zerowe a ja chciałem żeby wykonywało się to już tutaj.

To na pewno bym usunął - może wywalać program. Zrób inaczej(to jest standart w takich programach): Ogranicz liczbę iteracji, i jak algorytm się nie zbiegnie po skończeniu pętli to Zwracaj, Nulla, czy NaN. Pokaż stacktrace, gdzie to sie wysypuje, Przejechałeś program debugerem?

0
Piotr0396 napisał(a):

Używałem tej funkcji również bez użycia w PyQt więc powinna być prawidłowa jedyne co dopisałem to

if miejsceZero is None:
                        print('Brak znalezionego miejsca zerowego')
                    else: print(miejsceZero)

Dopisałem bo w pierwotnej wersji funkcja zwracała miejsce zerowe a ja chciałem żeby wykonywało się to już tutaj.

To na pewno bym usunął - może wywalać program. Zrób inaczej(to jest standart w takich programach): Ogranicz liczbę iteracji, i jak algorytm się nie zbiegnie po skończeniu pętli to Zwracaj, Nulla, czy NaN. Pokaż stacktrace, gdzie to sie wysypuje, Przejechałeś program debugerem?

0
lion137 napisał(a):
Piotr0396 napisał(a):

Używałem tej funkcji również bez użycia w PyQt więc powinna być prawidłowa jedyne co dopisałem to

if miejsceZero is None:
                        print('Brak znalezionego miejsca zerowego')
                    else: print(miejsceZero)

Dopisałem bo w pierwotnej wersji funkcja zwracała miejsce zerowe a ja chciałem żeby wykonywało się to już tutaj.

To na pewno bym usunął - może wywalać program. Zrób inaczej(to jest standart w takich programach): Ogranicz liczbę iteracji, i jak algorytm się nie zbiegnie po skończeniu pętli to Zwracaj, Nulla, czy NaN. Pokaż stacktrace, gdzie to sie wysypuje, Przejechałeś program debugerem?

Debuger się zawiesz i koniec. Myślę jeszcze nad inną koncepcją szczególnie z tym wielomianem ale muszę trochę podziałać. Dam znać co i jak.

0

Debuger się zawiesza? FTW?

0

Wymodziłem takie coś ale dalej się wysypuje. Sprawdzałem w Jupyter Notebook i działała ta współpraca bisekcji z wielomianem myśle że chodzi tutaj o coś z pobieraniem danych z pól:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QPushButton,
                             QLabel, QGridLayout,
                             QLineEdit, QApplication)
from matplotlib.pyplot import plot, show
from scipy import interpolate
from numpy import arange, exp

class Program(QWidget):
    
    def __init__(self):
        super().__init__()

        self.lbl1 = QLabel('Podaj wielomian')
        self.lbl2 = QLabel('Podaj zakres szukania')
        self.btn1 = QPushButton('Metoda bisekcji')
        self.btn2 = QPushButton('Metoda siecznych')
        self.text1 = QLineEdit()
        self.text2 = QLineEdit()

        siatka = QGridLayout()
        siatka.setSpacing(10)

        siatka.addWidget(self.lbl1, 1, 0)
        siatka.addWidget(self.text1, 1, 1)

        siatka.addWidget(self.lbl2, 2, 0)
        siatka.addWidget(self.text2, 2, 1)
        
        siatka.addWidget(self.btn1, 3, 0)
        siatka.addWidget(self.btn2, 3, 1)

        self.btn1.clicked.connect(self.bisectionClicked)

        self.setLayout(siatka)

        self.setGeometry(300, 300, 450, 150)
        self.setWindowTitle('Wyszukiwanie miejsc zerowych')
        self.show()

    
    def wielomian(n,x):
        return eval(wielomianText)
    
    def bisectionClicked(self):
        sender=self.sender()
        wielomianText=self.text1.text()
        
        '''
        zakresText=self.text2.text()
        zakresSplit=zakresText.split(',');
        xp=float(zakresSplit[0])
        xk=float(zakresSplit[1])
        '''
        print(self.bisection(wielomian,5,-1.5,-0.5,0.001))

    def bisection(self,n,fx,a,b,err):
        while np.absolute(b-a)>err:
            midPoint=(a+b)*0.5
            if fx(n,midPoint)*fx(a)<0:
                b=midPoint
            midPoint=(a+b)*0.5
            if fx(n,midPoint)*fx(b)<0:
                a=midPoint
        return b-(b-a)*fx(n,b)/(fx(n,b)-fx(n,a))
                                


if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Program()
    sys.exit(app.exec_())

Zakomentowane linijki to tylko próby różnych działań ale chyba coś z tym pobieraniem danych nie gra i dlatego wywołanie funkcji jest dla danych które działają wielomian też.

0

Spróbuj to przerobić, zaimplementować po ludzku wielomian, jako listę, np.:
[4, 2, 2, 1] to wielomian: 4x^3 + 2x^2 + 2x + 1

1 użytkowników online, w tym zalogowanych: 0, gości: 1