38 svar
381 visningar
vikfil är nöjd med hjälpen!
vikfil 22
Postad: 19 jul 2020 Redigerad: 26 jul 2020

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, Zn =a + bi 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 Zn = C. 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

tomast80 3372
Postad: 19 jul 2020

Jag kan inte spontant se nåt fel, förutom att det blir problem om a=0a=0 (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

a2+b21n\dfrac{\sqrt{a^2+b^2}^1}{n}

vilket inte är vad du vill få den att göra. För att få med /n i exponenten behövs parenteser: "**(1/n)".

Laguna 12476
Postad: 19 jul 2020

Vinkeln v blir fel om t. ex. både a och b är negativa. Det finns en funktion atan2 för ändamålet. 

vikfil 22
Postad: 20 jul 2020

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? 

vikfil 22
Postad: 20 jul 2020

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.)

Laguna 12476
Postad: 20 jul 2020

Jag föreslog atan2. 

vikfil 22
Postad: 20 jul 2020 Redigerad: 20 jul 2020

 

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. 

vikfil 22
Postad: 20 jul 2020

Ett förtydligande vad som bli fel.

Z3 = -1 ska lösas. 

Facit visar ger: Z0 = 12 + 32i, Z1 = -1Z2 = 12 - 32i

 

Mitt program ger: Z0 = -12+32iZ1=1Z2 = -12-32i

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.

tomast80 3372
Postad: 20 jul 2020

En kommentar: det är inte säkert att vinkeln är π2\frac{\pi}{2} bara för att a=0a=0. Den kan lika gärna vara -π2-\frac{\pi}{2}.

vikfil 22
Postad: 21 jul 2020

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: Z0 = ....Z1=....Z2=....

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.

vikfil 22
Postad: 21 jul 2020

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).

Laguna 12476
Postad: 21 jul 2020
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. 

vikfil 22
Postad: 23 jul 2020

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

elalat 29
Postad: 13 dec 2020

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.

elalat 29
Postad: 14 dec 2020
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 :)

elalat 29
Postad: 14 dec 2020

elalat 29
Postad: 14 dec 2020

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

Aerius 510
Postad: 14 dec 2020

Den förväntar sig en int. 

Laguna 12476
Postad: 14 dec 2020

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.

elalat 29
Postad: 14 dec 2020

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

Laguna 12476
Postad: 14 dec 2020

Den bilden går inte att läsa. Du kan kopiera in texten här i stället för en bild. 

elalat 29
Postad: 15 dec 2020

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"

elalat 29
Postad: 15 dec 2020

Vad behöver jag göra för att undvika felet här? 

Laguna 12476
Postad: 15 dec 2020

Det syns bättre, men inte bra. Kopiera texten i stället. 

elalat 29
Postad: 15 dec 2020

elalat 29
Postad: 15 dec 2020

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 >>

elalat 29
Postad: 15 dec 2020

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

>>

Aerius 510
Postad: 15 dec 2020

Jag kan inte läsa utskriften. Eftersom det är invalid syntax gissar jag att du missat en parentes någon stans.

elalat 29
Postad: 15 dec 2020

Jag försökte lägga till en parentes i olika ställen men det gick inte ändå. Har du nåt tips? Tack

elalat 29
Postad: 15 dec 2020

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.

Aerius 510
Postad: 15 dec 2020

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

Svara Avbryt
Close