A Complex numbers nem bonyolult.
Csupán egy kevésbé ijesztő névre lenne szükségük.
Olyannyira hasznosak, különösen a mérnöki munkában és a tudományokban, hogy az R a komplex számokat is szabványos atomi típusként kezeli, az integer, double, logical, character és raw típusok mellett.
Az R-ben a complex szám egyetlen érték.
A gyakorlatban viszont felfoghatjuk két szám párjaként.
Ezeket sajnálatos történelmi okokból „valós” és „képzetes” résznek nevezik.
Ismét csak a lényegi egyszerűségre érdemes összpontosítani, nem a furcsa nevekre.
Ahhoz, hogy két valós számból komplex számot hozzunk létre, egyszerűen csak fűzzük az i utótagot a képzetes részhez.
2+3i
#> [1] 2+3i
typeof(2+3i)
#> [1] "complex"
Ha valós változókból szeretnénk komplex számot létrehozni, a fenti szintaxis nem működik.
Ha r + imi-t írunk, az összezavarja a parsert: azt hiszi, hogy az imi egy (nem létező) változónév.
Vagy szorozzuk meg a képzetes részt 1i-vel, vagy használjuk a [complex()][ref-complex] függvényt:
r <- 2
im <- 3
r + im * 1i
#> [1] 2+3i
# must include the `real` and `imaginary` keywords
complex(real = r, imaginary = im)
#> [1] 2+3i
Felmerülhet benned a kérdés, miért i és nem j?
A legtöbb mérnök a j-t részesíti előnyben.
A legtöbb tudós és matematikus az i matematikai jelölést kedveli a képzetes jelentésben, ez a jelölés azonban ütközik azzal, hogy az elektrotechnikában az i az áramot jelöli.
Az R az i-t választotta, a Python a j-t, a Julia pedig kikerülte a vitát azzal, hogy az im-et választotta.
Légy óvatos, amikor a [STEM][wiki-STEM] programozási nyelvek között váltasz.
A komplex szám részeihez külön-külön így férhetsz hozzá:
z <- 2+3i
Re(z) # real part
#> [1] 2
Im(z) # imaginary part
#> [1] 3
Bármelyik rész lehet nulla, és a matematikusok ilyenkor „teljesen valós” vagy „teljesen képzetes” számról beszélnek. Az R-ben azonban ez továbbra is komplex szám.
1.2 + 0i
#> [1] 1.2+0i
typeof(1.2 + 0i)
#> [1] "complex"
2i
#> [1] 0+2i
typeof(2i)
#> [1] "complex"
Talán hallottad már, hogy „az i (vagy j) a -1 négyzetgyöke”.
Egyelőre ez csak annyit jelent, hogy a képzetes rész definíció szerint kielégíti a következő egyenlőséget:
1i * 1i == -1 # more precisely, 1i * 1i == -1 + 0i
#> [1] TRUE
Ez egyszerű gondolat, de érdekes következményekhez vezet.
A lebegőpontos és egész számokkal használt operátorok többsége komplex számokkal is működik:
z1 = 1.5 + 2i
z2 = 2 + 1.5i
z1 + z2 # addition
#> [1] 3.5+3.5i
z1 * z2 # multiplication
#> [1] 0+6.25i
z1 / z2 # division
#> [1] 0.96+0.28i
z1^2 # exponentiation
#> [1] -1.75+6i
2^z1 # another exponentiation
#> [1] 0.518895+2.780422i
A matematikai függvények többsége komplex bemenettel is működik.
A Re() és Im() mellett több olyan függvény is van, amely különösen fontos a komplex számok szempontjából.
Conj() egyszerűen megfordítja egy komplex szám képzetes részének előjelét (pluszból mínusz lesz, vagy fordítva).
abs(<complex number>) garantáltan olyan valós számot ad vissza, amelynek nincs képzetes része (ez a szám „nagysága”), a Mod(<complex number>) pedig a szinonimája.Arg(<complex number>) radiánban adja vissza a fázisszöget.z1
#> [1] 1.5+2i
abs(z1)
#> [1] 2.5
Mod(z1) # same as previous
#> [1] 2.5
Conj(z1) # flip sign
#> [1] 1.5-2i
Arg(z1)
#> [1] 0.9272952
Épp most vettek fel egy új taxiszolgálathoz, amely megpróbál kitűnni a többi szolgáltató közül egy már telített piacon. Hogy ezt elérje, a vezérigazgató úgy döntött, hogy ultraluxus szolgáltatást indít Manhattanben, ahol minden kereszteződésben segítők várják az utasokat, hogy az utazás előtt és után is kéznél legyenek. Most olyan kódot kell írnod, amely segít a szolgáltatás működtetésében.
A vezérigazgató úgy döntött, hogy mivel Manhattan utcahálózata nagyrészt rácsos elrendezésű, a komplex számok kényelmes módot kínálnak az utcák kereszteződéseinek ábrázolására. A pozitív és negatív valós számok a keletet, illetve a nyugatot, a pozitív és negatív képzetes számok pedig az északot, illetve a délt jelölik.
Mivel egy komplex szám létrehozása R-ben kicsit, öö... sajátos, azt a feladatot kaptad, hogy implementálj egy egyszerű komplexszám-függvényt.
Implementáld a simplex(a, b) függvényt, amely az a és b egész számokat kapja paraméterként.
Add vissza az a+bi komplex számot.
simplex(1, 1)
#> 1+1i
simplex(-3, 4)
#> -3+4i
Amikor egy ügyfél megadja a célkereszteződést, a sofőrjeid megkapják az odavezető útvonalat. Az útvonal egy komplex szám formájában érkezik, amelynek a valós része azt mutatja meg, hány háztömböt kell észak/dél felé haladni, a képzetes része pedig a kelet/nyugat irányú távolságot. Hogy illeszkedjen a szokványos iránytűhöz, a projektmenedzsered úgy döntött, hogy az észak a pozitív képzetes irányba esik, a dél pedig a negatív képzetes irányba. Ugyanígy a kelet a pozitív valós irányba esik, a nyugat pedig a negatív valós irányba.
Implementáld a driver_directions(start, end) függvényt, amely a start kiindulási és az end célkereszteződés koordinátáit veszi át.
Add vissza azt a komplex számot, amely megmutatja, hány háztömböt kell a sofőrnek kelet/nyugat és észak/dél felé megtennie.
driver_directions(0+0i, 7+5i)
#> 7+5i
driver_directions(-2+3i, 4-5i)
#> 6-8i
Az ügyféltől díjat számítanak fel azért a távolságért, amelyet a taxinak meg kell tennie. Mivel Manhattan utcahálózata rácsos elrendezésű, a taxik csak ezeken az útvonalakon közlekedhetnek. Ez a felépítés olyan távolságmértékhez vezet, amely a rácsvonalakhoz igazodik. A távolságot úgy kapjuk meg, hogy összeadjuk vagy a bejárt vonalak számát, vagy az elért kereszteződések számát (azaz a kiindulási kereszteződést nem számítva). Ezt a mértéket általában Manhattan-távolságnak vagy L1-normának nevezik.
Implementáld a manhattan(start, end) függvényt, amely a start és end kereszteződéseket veszi át.
Add vissza a start és end kereszteződések közötti Manhattan-távolságot.
manhattan(0+0i, 3+4i)
#> 7
manhattan(-2-3i, -1+1i)
#> 5
A vezérigazgatónak sikerült befektetési bankokat is megnyernie azzal, hogy kiemelte: a szolgáltatás nemcsak ultraluxus, hanem zöld is, mert kiképzett varjakat használ, hogy üzeneteket szállítsanak a kereszteződésekben álló segítők között (akik az utasokra vonatkozó információkat továbbítják egy személyre szabott élmény érdekében). Úgy tűnik, egyetlen befektetési bankár sem vette a fáradságot, hogy kellő alapossággal utánajárjon, pontosan miért is környezetbarát ez, sőt, még annak sem, hogy milyen vezérigazgató az, aki szabadidejében varjakat idomít, mert a befektetési pénzek csak özönlenek.
Ez a szolgáltatás is a megtett távolság alapján számol fel díjat. Mivel azonban a varjak tudnak repülni, nem kell követniük az utak rácsos hálózatát, és a legrövidebb utat választhatják. Persze ez nem biztos, hogy így van, ha hatalmas felhőkarcolók állják az utat, de a vezérigazgató a kansasi Manhattanbe (más néven „The Little Apple”) helyezi ezt a szolgáltatást, ahol a varjak könnyedén átrepülnek az alacsony épületek felett. Hogy mekkora igény lenne egy ilyen szolgáltatásra a kansasi Manhattanben, és hogy a helyi gyalogosok mit szólnak majd a fejük felett repkedő madarak sokaságához, az egy másik napra tartozó kérdés.
Implementáld az as_crow_flies(start, end) függvényt, amely a start és end kereszteződéseket veszi át.
Add vissza a kettő közötti légvonalbeli távolságot.
as_crow_flies(0+0i, 3+4i)
#> 5
A vezérigazgató megtanította a varjakat, hogy a sofőrökéhez hasonló útvonalakat kövessenek. A vezérigazgatónak azonban a déli félteke a kedvence, ezért a varjakat egy másik iránytűvel idomította, mint amit a projektmenedzsered a rendszer többi részében használ. A vezérigazgatódról kiderül, hogy elég különc figura. Az ő iránytűjénél az észak a negatív képzetes irányba, a dél pedig a pozitív képzetes irányba esik. Ez pont az ellentéte a sofőrök észak/dél irányainak, a kelet/nyugat viszont ugyanaz marad.
Implementáld a crows_directions(start, end) függvényt, amely a start és end kereszteződéseket veszi át.
Add vissza a sofőréhez hasonló komplex számot, csak az észak/dél irány felcserélésével.
driver_directions(0+0i, 7+5i)
#> 7-5i
driver_directions(-2+3i, 4-5i)
#> 6+8i
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) R nyelvet 21 fogalom111 feladat segítségével, valódi emberi mentorálással, mindez ingyen.