Python polynomekvation
Hej, jag försöker skriva ett program för att besvara följande fråga:
Programmeringsuppgift: Skriv ett program som löser ekvationen, där a, b heltal och n är ett positivt heltal.
Användaren av programmet ska kunna välja talen n, a och b själv.
detta har jag fått ihop, försöker efterlikna formeln i boken som får fram rötter ur . Svaret blir fel dock och jag tror det beror på att vinkeln V blir fel, har någon nån tanke? Första gången jag programmerar och förstår bara grunderna.
Tack!
Flyttade tråden från Matematik/Ma4 till Programmering/Python /Smaragdalena, moderator
Jag kan inte spontant se nåt fel, förutom att det blir problem om (division med 0 vid vinkelberäkningen). Man får nog göra ett undantag för den varianten.
Vad ger ditt program för lösningar i två enkla fall?
1) a=8, b=0, n=3
2) a=0, b=-8, n=3
"**1/n" som du skrivit på rad 7 borde bli konstigt. Här ska ju hela "1/n" ingå i exponenten, men det kan inte Python (eller miniräknare) själv veta. Python utgår istället från att exponenten bara är det som direkt följer efter **, alltså ettan, och sen delas hela resultatet med n. Med uttrycket som står gör Python alltså beräkningen
vilket inte är vad du vill få den att göra. För att få med /n i exponenten behövs parenteser: "**(1/n)".
Vinkeln v blir fel om t. ex. både a och b är negativa. Det finns en funktion atan2 för ändamålet.
Hej! tack för svar, tror jag får rätt svar på ekvationerna. Ändrade till "**(1/n).
a=8, b=0, n=3 ger svaret: z0 = 2 + 0i, z1 = -1 + 1.73i, z2 = -1 - 1.73i
Programmet ger error då a = 0 som sagt, finns det nån lösning?
Kan jag göra en "if" regel om a och b är negativa? och även om a = 0?
a= 0
b= -8
n= 3
(1.7320508075688774+0.9999999999999999j)
(-1.7320508075688774+0.9999999999999999j)
(-3.6739403974420594e-16-2j)
Där är svaren för ett exempel med a = 0 nu när jag la in att "if a = 0, v = pi/2 (alltså 90 grader.)
Jag föreslog atan2.
from math import*
a = int(input("a= "))
b = int(input("b= "))
if a != 0:
v = math.atan(b/a)
elif a==0:
v = math.pi/2
n = int(input("n= "))
r = (sqrt(a**2+b**2))**(1/n)
k = 0
while k < n:
print(r*(cos((v+k*2*math.pi)/n)+complex(0,1)*sin((v+k*2*math.pi)/n)))
k = k + 1
Ursäkta om det är lite rörigt! Felet som bli på vissa ekvationer är att den reela delen får fel tecken, den bli negativ då det ska vara positivt osv.. men de har rätt värden. Sen får även den reela delen av svaret värdet som den imaginära delen ska ha, det måste vara felvänt någonstans.
Ett förtydligande vad som bli fel.
ska lösas.
Facit visar ger:
Mitt program ger:
Funktionen atan (arctangens) svarar alltid med en vinkel mellan -pi/2 och pi/2. Det finns ju oändligt många vinklar med samma tangensvärde, så när funktionen ska ta ditt tangensvärde och räkna ut en enda vinkel måste den göra ett val. Det valet är alltså "vinkeln i första eller fjärde kvadranten som har det tangensvärdet". Punkten du räknar på ligger dock inte i någon av de kvadranterna, och därför får du fel vinkel.
Lösningen är som Laguna nämnde att använda atan2 istället för atan. atan2 tar täljare och nämnare som separata argument och kan därför lista ut vilken kvadrant du är i, och därmed ge rätt vinkel: atan2(b, a)
En annan kommentar: Eftersom du har skrivit "from math import *" så har ditt program redan importerat allt som modulen math innehåller. Därför behöver du inte skriva "math.pi", det räcker med bara "pi". Att skriva "math.pi" är som att säga "hämta pi från modulen math", men du har alltså redan hämtat allting från math.
En kommentar: det är inte säkert att vinkeln är bara för att . Den kan lika gärna vara .
print("Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv a, b, n")
from math import* #ger tillgång till bl.a. pi och trigonometriska funktioner
a = int(input("a= ")) #int(input) ger variablerna värdet som användaren anger. Int gör att värdet av det inskriva blir ett heltal.
b = int(input("b= "))
n = int(input("n= "))
if a != 0:
v = atan(b/a) #Tan**-1 ger värdet av vinkeln v.
elif a==0 and b>0: #Detta sätter vinkeln till 90 grader då a=0 och b>0
v = (pi/2)
if a==0 and b<0: #Detta sätter v till -90 grader då b<0
v = (-pi/2)
if b == 0 and a>0: #detta sätter v=0 då b=0 och a>0
v == 0
if b==0 and a<0: #Detta sätter v=pi då b=0 och a<0
v = pi
r = (sqrt(a**2+b**2))**(1/n) #Ger r värdet av absolutbeloppet av Z, och tar sedan n-roten ut för att få r till rätt grad.
k = 0
while k < n: #Detta gör att ekvationen görs om tills det att k = n-1, för att ekvationen har lika många rötter som n och python börjar räkna vid 0
print(r*(cos((v+k*2*pi)/n)+complex(0,1)*sin((v+k*2*pi)/n)))
k = k + 1
Där är programmet, nu verkar svaret bli rätt oavsett vilka värden som matas in. Tack så hemskt mycket för alla svar, hade inte klarat det annars. Det här forumet gör det möjligt att studera utan lärare.
Jag har bara en fråga till för att snygga till svaret, hur gör jag för att svaret som skrivs ut blir:
Mvh
Som sagt: atan kan bara räkna ut rätt vinkel för punkter till höger om y-axeln. Om du verkligen inte vill använda atan2 måste du själv lägga på ett halvt varv för att få rätt vinkel för punkter vänster om y-axeln. Du specialhanterar punkter på koordinataxlarna nu, men du får problem med punkter som inte är på koordinataxlarna och vänster om y-axeln. Prova t.ex. a=-1, b=1 så ser du att ditt program räknar som om punkten var a=1, b=-1.
För utskrifterna kan du använda en f-string (förutsatt att din Pythonversion är minst 3.6). Med ett f framför strängfnuttarna får man sätta in variabler i strängen, så du skulle t.ex. kunna skriva:
z = r*(cos((v+k*2*pi)/n)+complex(0,1)*sin((v+k*2*pi)/n))
print(f"Z{k} = {z}")
Det blir dock inte supervackert direkt, men man kan lägga in lite formateringsinfo genom att sätta ett kolon efter variabeln. Så här kan du få den att avrunda till 3 decimaler, t.ex.:
print(f"Z{k} = {z:.3f}")
Om det är viktigt att k:et är nedsänkt får man bråka lite till med den, men det går. Se t.ex. här för hur man kan byta ut siffror mot nedsänkta varianter.
Med atan2 får jag: "TypeError: atan2 expected 2 arguments, got 1" om jag byter atan till atan2 rakt av. Förstår inte riktigt hur jag ska lägga in det?
Ok! Ska kolla på svaret lite senare, tack för tipset =)
Den tar täljare och nämnare separat: atan2(b, a).
vikfil skrev:Med atan2 får jag: "TypeError: atan2 expected 2 arguments, got 1" om jag byter atan till atan2 rakt av. Förstår inte riktigt hur jag ska lägga in det?
Ok! Ska kolla på svaret lite senare, tack för tipset =)
Du får förstås slå upp hur den fungerar.
print("Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv n, a, b")
from math import* #ger tillgång till bl.a. pi och trigonometriska funktioner
a = int(input("a= ")) #int(input) ger variablerna värdet som användaren anger. Int gör att värdet av det inskriva blir ett heltal.
b = int(input("b= "))
n = int(input("n= "))
v = atan2(b, a) #Tan**-1 ger värdet av vinkeln v. atan2 används för att programmet ska veta vilken kvadrant talet finns i.
r = (sqrt(a**2+b**2))**(1/n) #Ger r värdet av absolutbeloppet av Z, och tar sedan n-roten ut för att få r till rätt grad.
k = 0 #k är antalet varv i enhetscirkeln
while k<n: #Detta gör att ekvationen görs om tills det att k = n-1, för att ekvationen har lika många rötter som n och python börjar räkna vid 0
z = r*(cos((v+k*2*pi)/n)+complex(0,1)*sin((v+k*2*pi)/n)) #Detta är den generella formeln för att ta ut rötter i en polynomekvation.
print(f"Z{k} = {z:.3f}") #f-string används för att svaret ska skrivas ut som Z0, Z2 osv..= svaret. Detta för att tydligöra resultatet. :.3 är till för att avrunda till 3 decimaler.
k = k + 1 # Varje gång uträkningen sker ökar värdet på k med 1. Annars hade inte uträkningen gått vidare till nästa rot.
Här är programmet om någon har samma problem! Tack för hjälpen, det uppskattas verkligen.
Mvh
Hej!
Kan du skicka en bild på programmet, alltså hur såg det ut till slut.
MVH
elalat skrev:Hej!
Kan du skicka en bild på programmet, alltså hur såg det ut till slut.
MVH
Koden står i inlägget ovanför ditt.
Skaft skrev:elalat skrev:Hej!
Kan du skicka en bild på programmet, alltså hur såg det ut till slut.
MVH
Koden står i inlägget ovanför ditt.
Är programmet helt rätt? Eftersom jag har några frågor om några koder som jag inte kunde förstå. Tack
Jag ser inget uppenbart fel, men jag har inte testat det. Föreslår att du startar en egen tråd om saken så kan vi reda ut frågetecknen :)
När jag skriver a=int(input("a= ")) och trycker på enter för att flytta till nästa rad kommer a=
Men när jag trycker på enter nästa gång, för att flytta till nästa rad, kommer den röda texten ,som finns i den bifogade bilden, vad är felet här? Tack
Den förväntar sig en int.
När du trycker på enter så avslutas inmatningen och du ger den en tom rad. Skriv in ett heltal och tryck sen på enter.
ok, nu gick det bra. Jag trodde att jag skulle en int i slutet. Tack så mycket.
Nu efter print ger att syntaxen är felaktig
Den bilden går inte att läsa. Du kan kopiera in texten här i stället för en bild.
Allt går bra tills jag skriver print(f"Z{k} = {z:.3f}") när jag trycker på enter kommer följande text:
"SyntaxError: invalid syntax"
Vad behöver jag göra för att undvika felet här?
Det syns bättre, men inte bra. Kopiera texten i stället.
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >> print("Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv n, a, b")
Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv n, a, b >> from math import* >> a = int(input("a= "))
a= 8 >> b = int(input("b= "))
b= 0 >> n = int(input("n= "))
n= 3 >> v = atan2(b, a) >> r = (sqrt(a**2+b**2))**(1/n) >> k = 0 >> while k<n:
z = r*(cos((v+k*2*pi)/n)+complex(0,1)*sin((v+k*2*pi)/n)) print(f"Z{k} = {z:.3f}") SyntaxError: invalid syntax >>
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information.
>> print("Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv n, a, b")
Programmet löser ut rötterna till ekvationen Z**n = a + bi, du väljer själv n, a, b >>
from math import*
>> a = int(input("a= "))
a= 8
>> b = int(input("b= "))
b= 0
>> n = int(input("n= "))
n= 3
>> v = atan2(b, a)
>> r = (sqrt(a**2+b**2))**(1/n)
>> k = 0
>> while k<n:
z = r*(cos((v+k*2*pi)/n)+complex(0,1)*sin((v+k*2*pi)/n))
print(f"Z{k} = {z:.3f}")
SyntaxError: invalid syntax
>>
Jag kan inte läsa utskriften. Eftersom det är invalid syntax gissar jag att du missat en parentes någon stans.
Jag försökte lägga till en parentes i olika ställen men det gick inte ändå. Har du nåt tips? Tack
Obs: När jag provar skriva sista raden
print(f"Z{k} = {z:.3f}")
i ett helt nytt program går det bra.
Men när jag skriver det efter de kodar blir det fel.
I IDLE måste du köra while-loopen först. Sen när Z är beräknat kan du skriva print(...) på en ny rad. Det ser inte ut som k incrementeras i while-loopen. Ser ut som du borde skriva ditt program i en modul (.py), inte direkt i IDLE. IDLE är till för att testa små delar av sitt program