فاز 1 · درس 19

اعداد مختلط در هوش مصنوعی: از فرمول اویلر تا امبدینگ RoPE

نوع
مفهومی
زمان
حدود 60 دقیقه
زبان‌ها
Python
یک دایره‌ی واحد با برداری چرخان روی صفحه‌ی دوبعدی که امواج سینوسی و کسینوسی را در راستای محورهای افقی و عمودی نشان می‌دهد.
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. عدد مختلط چیست؟
  5. محاسبات اعداد مختلط
  6. صفحه‌ی مختلط
  7. فرم قطبی
  8. فرمول اویلر
  9. چرا فرمول اویلر برای یادگیری ماشین مهم است؟
  10. ارتباط با چرخش‌های دوبعدی
  11. فازورها و سیگنال‌های چرخشی
  12. ریشه‌های واحد
  13. ارتباط با DFT
  14. چرا i موهومی نیست؟
  15. مقایسه‌ی توابع نمایی مختلط و توابع مثلثاتی
  16. ارتباط با ترنسفورمرها
  17. پیاده‌سازی گام‌به‌گام
  18. گام 1: کلاس Complex
  19. گام 2: تبدیل قطبی و فرمول اویلر
  20. گام 3: چرخش
  21. گام 4: پیاده‌سازی DFT با محاسبات مختلط
  22. گام 5: تبدیل DFT معکوس
  23. گام 6: ریشه‌های واحد
  24. استفاده‌ی عملی
  25. خروجی
  26. تمرین‌ها
  27. راهنمایی‌ها
  28. اصطلاحات کلیدی
  29. برای مطالعه‌ی بیشتر

هنگام مطالعه‌ی مقالات پیشرفته‌ی یادگیری عمیق، پردازش صدا و پردازش زبان طبیعی، خیلی زود به نمادهای اعداد مختلط و توابع سینوسی و کسینوسی با فرکانس‌های گوناگون برمی‌خورید. اغلب مهندسان، اعداد مختلط را صرفاً مبحثی دانشگاهی و انتزاعی در نظر می‌گیرند؛ اما واقعیت این است که در معماری‌های مدرن نظیر ترنسفورمرها و کدگذاری‌های مکانی چرخشی (RoPE)، محاسبات مختلط طبیعی‌ترین ابزار برای مدل‌سازی چرخش و فاز هستند.

درک سازوکار داخلی تبدیل‌های فوریه (مانند DFT و FFT) و همچنین نحوه‌ی عملکرد لایه‌های اتنشن در مدل‌های زبانی امروزی، بدون تسلط بر جبر مختلط و هندسه‌ی فرمول اویلر عملاً ناممکن است. این درس پایه‌های نظری اعداد مختلط را به تصویر و هندسه متصل می‌کند تا درک کنید چرا ضرب در واحد موهومی معادل با یک چرخش 90 درجه است و چطور این مفهوم ساده ستون فقرات مدل‌های مدرن را تشکیل می‌دهد.

تمام کدهای این درس با پایتون خالص و محاسبات پایه پیاده‌سازی می‌شوند؛ بنابراین اجرای آن‌ها کاملاً سبک بوده و به هیچ‌گونه کارت گرافیک یا ابزار ابری وابسته نیست و روی CPU کامپیوتر شخصی‌تان بدون مشکل اجرا می‌شود.

ریشه‌ی دوم 1- موهومی نیست؛ بلکه کلید چرخش‌ها، فرکانس‌ها و نیمی از پردازش سیگنال است.

اهداف یادگیری

  • انجام محاسبات اعداد مختلط (جمع، ضرب، تقسیم و مزدوج‌گیری) در هر دو شکل دکارتی و قطبی
  • به‌کارگیری فرمول اویلر (Euler's formula) برای تبدیل توابع نمایی مختلط و توابع مثلثاتی به یکدیگر
  • پیاده‌سازی تبدیل فوریه‌ی گسسته (Discrete Fourier Transform یا DFT) با استفاده از ریشه‌های مختلط واحد
  • توضیح اینکه چگونه چرخش‌های مختلط، زیربنای RoPE و کدگذاری‌های مکانی سینوسی در ترنسفورمرها را می‌سازند

صورت مسئله

مقاله‌ای درباره‌ی تبدیل‌های فوریه باز می‌کنید و همه‌جا i می‌بینید. به کدگذاری‌های مکانی ترنسفورمر نگاه می‌اندازید و sin و cos را در فرکانس‌های مختلف مشاهده می‌کنید؛ یعنی همان بخش‌های حقیقی و موهومی توابع نمایی مختلط. درباره‌ی محاسبات کوانتومی مطالعه می‌کنید و می‌بینید همه‌چیز در فضاهای برداری مختلط بیان شده است.

اعداد مختلط در نگاه اول انتزاعی به نظر می‌رسند. دستگاه اعدادی که بر پایه‌ی ریشه‌ی دوم 1- بنا شده باشد، بیشتر شبیه یک ترفند ریاضی است؛ اما اصلاً ترفند نیست، بلکه زبان طبیعی چرخش‌ها و نوسان‌هاست. هر زمان چیزی بچرخد، بلرزد یا نوسان کند، اعداد مختلط ابزار دقیق آن کار هستند.

بدون درک اعداد مختلط، تبدیل فوریه‌ی گسسته (DFT) را نمی‌فهمید؛ تبدیل سریع فوریه (Fast Fourier Transform یا FFT) را متوجه نمی‌شوید؛ سازوکار RoPE (امبدینگ مکانی چرخشی یا Rotary Position Embedding) در مدل‌های زبانی امروزی برایتان مبهم می‌ماند؛ و سر در نمی‌آورید که چرا کدگذاری‌های مکانی سینوسی در مقاله‌ی اصلی ترنسفورمر از چنین فرکانس‌هایی استفاده می‌کنند.

در این درس، محاسبات مختلط را از پایه می‌سازیم، آن را به هندسه پیوند می‌زنیم و دقیقاً نشان می‌دهیم اعداد مختلط در کجای یادگیری ماشین حضور دارند.

مفاهیم پایه

عدد مختلط چیست؟

یک عدد مختلط از دو بخش تشکیل شده است: بخش حقیقی و بخش موهومی.

z = a + bi

where:
  a is the real part
  b is the imaginary part
  i is the imaginary unit, defined by i^2 = -1

همین و بس. شما محور اعداد را تا یک صفحه گسترش می‌دهید. اعداد حقیقی روی یک محور می‌نشینند و اعداد موهومی روی محور دیگر. هر عدد مختلط، نقطه‌ای در این صفحه است.

محاسبات اعداد مختلط

جمع. بخش‌های حقیقی را با هم و بخش‌های موهومی را با هم جمع کنید.

(a+bi)+(c+di)=(a+c)+(b+d)iExample: (3+2i)+(1+4i)=4+6i\begin{aligned} (a + bi) + (c + di) &= (a + c) + (b + d)i \\[4pt] \text{Example: } (3 + 2i) + (1 + 4i) &= 4 + 6i \end{aligned}

ضرب. از خاصیت توزیع‌پذیری استفاده کنید و یادتان باشد که i2=−1i^2 = -1.

(a+bi)(c+di)=ac+adi+bci+bdi2=ac+adi+bci−bd=(ac−bd)+(ad+bc)iExample: (3+2i)(1+4i)=3+12i+2i+8i2=3+14i−8=−5+14i\begin{aligned} (a + bi)(c + di) &= ac + adi + bci + bdi^2 \\ &= ac + adi + bci - bd \\ &= (ac - bd) + (ad + bc)i \\[8pt] \text{Example: } (3 + 2i)(1 + 4i) &= 3 + 12i + 2i + 8i^2 \\ &= 3 + 14i - 8 \\ &= -5 + 14i \end{aligned}

مزدوج. علامت بخش موهومی را برعکس کنید.

conjugate of (a+bi)=a−bi\text{conjugate of } (a + bi) = a - bi

حاصل‌ضرب یک عدد مختلط در مزدوجش همیشه عددی حقیقی است:

(a+bi)(a−bi)=a2+b2(a + bi)(a - bi) = a^2 + b^2

تقسیم. صورت و مخرج را در مزدوج مخرج ضرب کنید.

a+bic+di=(a+bi)(c−di)c2+d2\frac{a + bi}{c + di} = \frac{(a + bi)(c - di)}{c^2 + d^2}

این کار بخش موهومی را از مخرج حذف می‌کند و یک عدد مختلط شسته‌رفته تحویلتان می‌دهد.

صفحه‌ی مختلط

صفحه‌ی مختلط هر عدد مختلط را به یک نقطه‌ی دوبعدی نگاشت می‌کند. محور افقی، محور حقیقی و محور عمودی، محور موهومی است.

z = 3 + 2i  corresponds to the point (3, 2)
z = -1 + 0i corresponds to the point (-1, 0) on the real axis
z = 0 + 4i  corresponds to the point (0, 4) on the imaginary axis

یک عدد مختلط هم‌زمان هم یک نقطه است و هم یک بردار که از مبدأ شروع می‌شود. همین نگاه دوگانه است که اعداد مختلط را در هندسه این‌قدر کاربردی می‌کند.

فرم قطبی

هر نقطه در صفحه را می‌توان با فاصله‌اش از مبدأ و زاویه‌اش با محور مثبت حقیقی توصیف کرد.

z=r(cos⁡θ+isin⁡θ)where: r=∣z∣=a2+b2(magnitude, or modulus)θ=atan2(b,a)(phase, or argument)\begin{aligned} z &= r (\cos\theta + i \sin\theta) \\[4pt] \text{where: } r &= |z| = \sqrt{a^2 + b^2} \quad \text{(magnitude, or modulus)} \\ \theta &= \mathop{\mathrm{atan2}}(b, a) \quad \text{(phase, or argument)} \end{aligned}

فرم دکارتی (a+bi)(a + bi) برای جمع مناسب است؛ فرم قطبی (r,θ)(r, \theta) برای ضرب عالی است.

ضرب در فرم قطبی. اندازه‌ها را در هم ضرب کنید و زاویه‌ها را با هم جمع کنید.

z1=r1eiθ1z2=r2eiθ2z1z2=(r1r2) ei(θ1+θ2)\begin{aligned} z_1 &= r_1 e^{i\theta_1} \\ z_2 &= r_2 e^{i\theta_2} \\[4pt] z_1 z_2 &= (r_1 r_2) \, e^{i(\theta_1 + \theta_2)} \end{aligned}

به همین دلیل اعداد مختلط برای چرخش‌ها فوق‌العاده‌اند. ضرب در یک عدد مختلط با اندازه‌ی 1، یک چرخش خالص است.

فرمول اویلر

پل ارتباطی میان توابع نمایی مختلط و مثلثات:

eiθ=cos⁡θ+isin⁡θe^{i\theta} = \cos\theta + i \sin\theta

این مهم‌ترین رابطه‌ی این درس است. وقتی θ=π\theta = \pi باشد:

eiπ=cos⁡π+isin⁡π=−1+0i=−1Therefore: eiπ+1=0\begin{aligned} e^{i\pi} &= \cos\pi + i \sin\pi = -1 + 0i = -1 \\[4pt] \text{Therefore: } e^{i\pi} + 1 &= 0 \end{aligned}

پنج ثابت بنیادین ریاضی (ee، ii، π\pi، 1 و 0) در یک معادله به هم گره می‌خورند.

چرا فرمول اویلر برای یادگیری ماشین مهم است؟

فرمول اویلر می‌گوید با تغییر θ\theta، عبارت eiθe^{i\theta} دایره‌ی واحد را رسم می‌کند. در θ=0\theta = 0، در نقطه‌ی (1,0)(1, 0) هستید. در θ=π/2\theta = \pi/2، به (0,1)(0, 1) می‌رسید. در θ=π\theta = \pi، در نقطه‌ی (−1,0)(-1, 0) قرار دارید. در θ=3π/2\theta = 3\pi/2، به (0,−1)(0, -1) بازمی‌گردید. یک دور چرخش کامل برابر با θ=2π\theta = 2\pi است.

این یعنی توابع نمایی مختلط، خودِ چرخش هستند؛ و چرخش‌ها همه‌جای پردازش سیگنال و یادگیری ماشین حضور دارند.

ارتباط با چرخش‌های دوبعدی

ضرب عدد مختلط (x+yi)(x + yi) در eiθe^{i\theta}، نقطه‌ی (x,y)(x, y) را به اندازه‌ی زاویه‌ی θ\theta حول مبدأ می‌چرخاند.

Rotation via complex multiplication:(x+yi)(cos⁡θ+isin⁡θ)=(xcos⁡θ−ysin⁡θ)+(xsin⁡θ+ycos⁡θ)iRotation via matrix multiplication:[cos⁡θ−sin⁡θsin⁡θcos⁡θ][xy]=[xcos⁡θ−ysin⁡θxsin⁡θ+ycos⁡θ]\begin{aligned} &\text{Rotation via complex multiplication:} \\ &\quad (x + yi)(\cos\theta + i \sin\theta) = (x \cos\theta - y \sin\theta) + (x \sin\theta + y \cos\theta)i \\[8pt] &\text{Rotation via matrix multiplication:} \\ &\quad \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x \cos\theta - y \sin\theta \\ x \sin\theta + y \cos\theta \end{bmatrix} \end{aligned}

هر دو روش نتیجه‌ی یکسانی تولید می‌کنند. ضرب مختلط دقیقاً همان چرخش دوبعدی است. ماتریس دوران، چیزی جز همان ضرب مختلط با نمادگذاری ماتریسی نیست.

فرم ماتریسی معادلضرب اعداد مختلط = دوران دوبعدیضرب در e^(i*theta)ضرب در ماتریس دوراننتیجه یکسانz = x + yiنقطه (x, y)z' = z * e^(i*theta)نقطه دوران‌یافته به اندازه thetaبردار [x, y][x cos theta - y sin theta,x sin theta + y cos theta]

فازورها و سیگنال‌های چرخشی

یک تابع نمایی مختلط eiωte^{i\omega t} نقطه‌ای است که با بسامد زاویه‌ای ω\omega روی دایره‌ی واحد می‌چرخد. با افزایش tt، این نقطه مسیر دایره را طی می‌کند.

بخش حقیقی این نقطه‌ی در حال چرخش cos⁡(ωt)\cos(\omega t) است و بخش موهومی آن sin⁡(ωt)\sin(\omega t). یک سیگنال سینوسی، سایه‌ی یک عدد مختلطِ در حال چرخش است.

eiωt=cos⁡(ωt)+isin⁡(ωt)Real part: cos⁡(ωt)– a cosine waveImaginary part: sin⁡(ωt)– a sine wave\begin{aligned} e^{i\omega t} &= \cos(\omega t) + i \sin(\omega t) \\[4pt] \text{Real part: } & \cos(\omega t) \quad \text{-- a cosine wave} \\ \text{Imaginary part: } & \sin(\omega t) \quad \text{-- a sine wave} \end{aligned}

این همان نمایش فازور (phasor) است. به‌جای دنبال کردن یک موج سینوسی با نوسانات پی‌درپی، یک فلش چرخان و نرم را دنبال می‌کنید. تغییرات فاز به جابه‌جایی زاویه، تغییرات دامنه به تغییرات اندازه، و جمع سیگنال‌ها به جمع برداری تبدیل می‌شوند.

ریشه‌های واحد

ریشه‌های NN‌ام واحد، NN نقطه‌ با فاصله‌های یکسان روی دایره‌ی واحد هستند:

wk=e2πik/Nfor k=0,1,2,…,N−1w_k = e^{2\pi i k/N} \quad \text{for } k = 0, 1, 2, \ldots, N-1

برای N=4N = 4، ریشه‌ها عبارتند از: 1,i,−1,−i1, i, -1, -i (چهار جهت اصلی قطب‌نما). برای N=8N = 8، چهار جهت اصلی به‌همراه چهار جهت قطری را به دست می‌آورید.

ریشه‌های واحد، سنگ بنای تبدیل فوریه‌ی گسسته هستند. تبدیل DFT یک سیگنال را به مؤلفه‌هایی در همین NN فرکانس با فواصل مساوی تجزیه می‌کند.

ارتباط با DFT

تبدیل فوریه‌ی گسسته‌ی یک سیگنال x[0],x[1],…,x[N−1]x[0], x[1], \ldots, x[N-1] به این صورت تعریف می‌شود:

X[k]=∑n=0N−1x[n] e−2πikn/NX[k] = \sum_{n=0}^{N-1} x[n] \, e^{-2\pi i k n/N}

هر X[k]X[k] اندازه می‌گیرد که سیگنال تا چه حد با ریشه‌ی kk‌ام واحد همبستگی دارد؛ یعنی با یک موج سینوسی مختلط در فرکانس kk. تبدیل DFT یک سیگنال را به NN فازور چرخان می‌شکند و دامنه و فاز هرکدام را به شما می‌دهد.

چرا i موهومی نیست؟

واژه‌ی «موهومی» (imaginary) یک خطای تاریخی است. دکارت با لحنی تحقیرآمیز آن را به کار برد. اما ii اصلاً موهومی‌تر از اعداد منفی در زمان مقاومت اولیه در برابر آن‌ها نیست. اعداد منفی پاسخ به این پرسش بودند که «اگر 5 را از 3 کم کنیم به چه می‌رسیم؟»؛ واحد موهومی هم پاسخی است به اینکه «چه عددی را به توان 2 برسانیم تا 1- شود؟»

اگر کاربردی‌تر نگاه کنیم: ii یک عملگر چرخش 90 درجه است. اگر یک عدد حقیقی را یک بار در ii ضرب کنید، 90 درجه می‌چرخد و به محور موهومی می‌رسد. اگر دوباره آن را در ii ضرب کنید (i2i^2)، 90 درجه‌ی دیگر می‌چرخد؛ حالا رو به سمت منفی محور حقیقی ایستاده‌اید. به همین دلیل است که i2=−1i^2 = -1. هیچ رمزورازی در کار نیست؛ فقط یک نیم‌دور است که از دو چرخش ربع‌دایره‌ای ساخته شده.

علت کاربرد فراگیر اعداد مختلط در مهندسی همین است. هر پدیده‌ای که بچرخد — امواج الکترومغناطیسی، حالت‌های کوانتومی، نوسانات سیگنال یا کدگذاری‌های مکانی — به‌طبیعی‌ترین شکل با اعداد مختلط توصیف می‌شود.

مقایسه‌ی توابع نمایی مختلط و توابع مثلثاتی

پیش از فرمول اویلر، مهندسان سیگنال‌ها را به‌صورت Acos⁡(ωt+ϕ)A \cos(\omega t + \phi) می‌نوشتند: دامنه‌ی AA، فرکانس ω\omega و فاز ϕ\phi. این روش کار می‌کرد اما محاسبات را طاقت‌فرسا می‌ساخت؛ چرا که جمع دو موج کسینوسی با فازهای متفاوت به اتحادهای مثلثاتی نیاز داشت.

با توابع نمایی مختلط، همان سیگنال به‌شکل Aei(ωt+ϕ)A e^{i(\omega t + \phi)} درمی‌آید. جمع دو سیگنال صرفاً جمع دو عدد مختلط است. ضرب (مدولاسیون) هم فقط ضرب اندازه‌ها و جمع زاویه‌هاست. تغییر فاز به جمع زاویه و جابه‌جایی فرکانسی به ضرب در فازورها تبدیل می‌شود.

کل حوزه‌ی پردازش سیگنال به نمادگذاری نمایی مختلط روی آورد، چون ریاضیاتش بسیار سرراست‌تر است. «سیگنال واقعی» همیشه همان بخش حقیقیِ نمایش مختلط است. بخش موهومی هم مثل ثبت دفتری در محاسبات همراه آن کشیده می‌شود تا تمام عملیات جبری روان و طبیعی پیش بروند.

ارتباط با ترنسفورمرها

کدگذاری‌های مکانی سینوسی (مقاله‌ی اصلی ترنسفورمر):

PE(pos,2i)=sin⁡(pos/100002i/d)PE(pos,2i+1)=cos⁡(pos/100002i/d)\begin{aligned} PE(pos, 2i) &= \sin\left(pos / 10000^{2i/d}\right) \\ PE(pos, 2i+1) &= \cos\left(pos / 10000^{2i/d}\right) \end{aligned}

جفت‌های sin و cos، بخش‌های حقیقی و موهومی نمایی‌های مختلط در فرکانس‌های گوناگون هستند. هر فرکانس، تفکیک‌پذیری یا «وضوح» (resolution) متفاوتی برای کدگذاری موقعیت فراهم می‌کند. فرکانس‌های پایین به‌کندی تغییر می‌کنند (موقعیت کلی یا coarse) و فرکانس‌های بالا به‌سرعت جابه‌جا می‌شوند (موقعیت دقیق یا fine). این‌ها در کنار هم به هر موقعیت، یک ردپای فرکانسیِ یکتا می‌بخشند.

امبدینگ RoPE (Rotary Position Embedding) پا را از این هم فراتر می‌گذارد. این روش بردارهای query و key را صراحتاً در ماتریس‌های دوران مختلط ضرب می‌کند. فاصله‌ی نسبیِ میان دو توکن به یک زاویه‌ی چرخش تبدیل می‌شود. اتنشن بر اساس این بردارهای چرخانده‌شده محاسبه می‌شود و به لطف ضرب مختلط، مدل نسبت به موقعیت نسبی حساسیت پیدا می‌کند.

عملیات فرم جبری مفهوم هندسی
جمع (a+c)+(b+d)i(a+c) + (b+d)i جمع برداری در صفحه
ضرب (ac−bd)+(ad+bc)i(ac-bd) + (ad+bc)i چرخش و مقیاس‌بندی
مزدوج a−bia - bi بازتاب نسبت به محور حقیقی
اندازه a2+b2\sqrt{a^2 + b^2} فاصله از مبدأ
فاز atan2(b,a)\mathop{\mathrm{atan2}}(b, a) زاویه نسبت به محور مثبت حقیقی
تقسیم ضرب در مزدوج چرخش معکوس و تغییر مقیاس
توان rneinθr^n e^{in\theta} nn بار چرخش، تغییر مقیاس با ضریب rnr^n
کاربردهادایره مثلثاتی (واحد)e^(i*0) = 1e^(i*pi/2) = ie^(i*pi) = -1e^(i*3pi/2) = -iفرمول اویلر:e^(i*theta) = cos + i*sinDFT از ریشه‌های واحد استفاده می‌کند:e^(2*pi*i*k/N)RoPE از دوران استفاده می‌کند:q * e^(i*m*theta)
ریشه‌های واحدn را بکشید
ROOTS OF UNITYThe n complex nth-roots of unity are the solutions of z to the n equals one. They sit evenly around the unit circle at angles two pi k over n, one of them always at 1. These evenly spaced points are the sampling frequencies behind the discrete Fourier transform.
ریشه‌های n-ام مختلط واحد، جواب‌های معادله‌ی z به توان n برابر با یک هستند. این نقاط به‌طور یکنواخت در زوایای دو پی k بر n روی دایره‌ی واحد قرار دارند و یکی از آن‌ها همواره روی 1 است. این نقاط با فواصل یکسان، همان بسامدهای نمونه‌برداری پشت تبدیل فوریه‌ی گسسته هستند.

پیاده‌سازی گام‌به‌گام

گام 1: کلاس Complex

یک کلاس عدد مختلط (Complex) بسازید که از اعمال جبری، اندازه، فاز و تبدیل بین فرم‌های دکارتی و قطبی پشتیبانی کند.

import math

class Complex:
    def __init__(self, real, imag=0.0):
        self.real = real
        self.imag = imag

    def __add__(self, other):
        return Complex(self.real + other.real, self.imag + other.imag)

    def __mul__(self, other):
        r = self.real * other.real - self.imag * other.imag
        i = self.real * other.imag + self.imag * other.real
        return Complex(r, i)

    def __truediv__(self, other):
        denom = other.real ** 2 + other.imag ** 2
        r = (self.real * other.real + self.imag * other.imag) / denom
        i = (self.imag * other.real - self.real * other.imag) / denom
        return Complex(r, i)

    def magnitude(self):
        return math.sqrt(self.real ** 2 + self.imag ** 2)

    def phase(self):
        return math.atan2(self.imag, self.real)

    def conjugate(self):
        return Complex(self.real, -self.imag)

گام 2: تبدیل قطبی و فرمول اویلر

def to_polar(z):
    return z.magnitude(), z.phase()

def from_polar(r, theta):
    return Complex(r * math.cos(theta), r * math.sin(theta))

def euler(theta):
    return Complex(math.cos(theta), math.sin(theta))

بررسی صحت: خروجی euler(theta).magnitude() همیشه باید 1.0 باشد. خروجی euler(0) باید (1, 0) و خروجی euler(pi) باید (-1, 0) شود.

گام 3: چرخش

چرخاندن نقطه‌ی (x,y)(x, y) با زاویه‌ی θ\theta تنها با یک ضرب مختلط انجام می‌شود:

point = Complex(3, 4)
rotated = point * euler(math.pi / 4)

اندازه تغییری نمی‌کند؛ تنها چیزی که عوض می‌شود زاویه است.

گام 4: پیاده‌سازی DFT با محاسبات مختلط

def dft(signal):
    N = len(signal)
    result = []
    for k in range(N):
        total = Complex(0, 0)
        for n in range(N):
            angle = -2 * math.pi * k * n / N
            total = total + Complex(signal[n], 0) * euler(angle)
        result.append(total)
    return result

این همان DFT با مرتبه‌ی O(N2)O(N^2) است. هر خروجی X[k]X[k]، حاصل جمع نمونه‌های سیگنال است که در ریشه‌های واحد ضرب شده‌اند.

گام 5: تبدیل DFT معکوس

تبدیل DFT معکوس، سیگنال اصلی را از روی طیف آن بازسازی می‌کند. تنها تفاوت‌های آن با DFT مستقیم این است: علامت نما قرینه می‌شود و خروجی بر NN تقسیم می‌گردد.

def idft(spectrum):
    N = len(spectrum)
    result = []
    for n in range(N):
        total = Complex(0, 0)
        for k in range(N):
            angle = 2 * math.pi * k * n / N
            total = total + spectrum[k] * euler(angle)
        result.append(Complex(total.real / N, total.imag / N))
    return result

این کار یک بازسازی بی‌نقص انجام می‌دهد. تبدیل DFT و سپس IDFT را اجرا کنید تا سیگنال اصلی تا دقت محاسبات ماشین بازیابی شود. هیچ اطلاعاتی از دست نمی‌رود.

گام 6: ریشه‌های واحد

def roots_of_unity(N):
    return [euler(2 * math.pi * k / N) for k in range(N)]

این دو ویژگی را بیازمایید:

  • اندازه‌ی هر ریشه دقیقاً برابر با 1 است.
  • مجموع تمام NN ریشه برابر با صفر است (به دلیل تقارن یکدیگر را خنثی می‌کنند).

همین ویژگی‌ها هستند که DFT را بازگشت‌پذیر می‌کنند. ریشه‌های واحد یک پایه‌ی متعامد برای دامنه‌ی فرکانس می‌سازند.

استفاده‌ی عملی

زبان Python به‌طور درون‌ساخته از اعداد مختلط پشتیبانی می‌کند. حرف j نشان‌دهنده‌ی واحد موهومی است.

z = 3 + 2j
w = 1 + 4j

print(z + w)
print(z * w)
print(abs(z))

import cmath
print(cmath.phase(z))
print(cmath.exp(1j * cmath.pi))

در کار با آرایه‌ها، کتابخانه‌ی numpy اعداد مختلط را مستقیماً مدیریت می‌کند:

import numpy as np

z = np.array([1+2j, 3+4j, 5+6j])
print(np.abs(z))
print(np.angle(z))
print(np.conj(z))
print(np.real(z))
print(np.imag(z))

signal = np.sin(2 * np.pi * 5 * np.linspace(0, 1, 128))
spectrum = np.fft.fft(signal)
freqs = np.fft.fftfreq(128, d=1/128)

خروجی

فایل code/complex_numbers.py را اجرا کنید تا سند outputs/skill-complex-arithmetic.md ساخته شود.

تمرین‌ها

  1. محاسبات دستی با اعداد مختلط. مقدار (2+3i)(4−i)(2 + 3i)(4 - i) را دستی حساب کنید و با کد تطبیق دهید. سپس مقدار (5+2i)/(1−3i)(5 + 2i) / (1 - 3i) را به دست آورید. هر دو نتیجه را در صفحه‌ی مختلط رسم کنید و ببینید که عمل ضرب چطور عدد اول را چرخانده و مقیاس آن را تغییر داده است.

  2. دنباله‌ی چرخش. از نقطه‌ی (1,0)(1, 0) شروع کنید. 12 بار آن را در eiπ/6e^{i\pi/6} ضرب کنید. مطمئن شوید که پس از 12 بار ضرب، دوباره به (1,0)(1, 0) بازمی‌گردید. مختصات را در هر مرحله چاپ کنید و ببینید که چطور یک 12‌ضلعی منتظم رسم می‌شود.

  3. تبدیل DFT یک سیگنال مشخص. سیگنالی بسازید که حاصل‌جمع sin⁡(2π⋅3t)\sin(2\pi \cdot 3t) و 0.5sin⁡(2π⋅7t)0.5 \sin(2\pi \cdot 7t) با نمونه‌برداری در 32 نقطه باشد. تابع DFT خود را روی آن اجرا کنید. بررسی کنید که در طیف اندازه، قله‌هایی در فرکانس‌های 3 و 7 شکل بگیرد و ارتفاع قله در فرکانس 7 نصف ارتفاع قله در فرکانس 3 باشد.

  4. مصورسازی ریشه‌های واحد. ریشه‌های هشتم واحد را محاسبه کنید. بررسی کنید که مجموع آن‌ها برابر با صفر شود. همچنین بررسی کنید که با ضرب هر ریشه در ریشه‌ی اولیه e2πi/8e^{2\pi i/8}، ریشه‌ی بعدی حاصل شود.

  5. هم‌ارزی ماتریس دوران. به ازای 10 زاویه‌ی تصادفی و 10 نقطه‌ی تصادفی، بررسی کنید که ضرب مختلط نتیجه‌ای کاملاً یکسان با ضرب ماتریس در بردار (با ماتریس دوران 2x2) تولید می‌کند. بیشترین اختلاف عددی را چاپ کنید.

راهنمایی‌ها

تمرین 1. ضرب را با شرط i2=−1i^2 = -1 بسط دهید؛ سپس برای تقسیم، صورت و مخرج را در مزدوجِ مخرج 1+3i1 + 3i ضرب کنید. حاصل‌ضرب را با Complex(2, 3) * Complex(4, -1) بیازمایید: مقدار magnitude() آن باید با حاصل‌ضرب دو اندازه، و phase() آن با مجموع دو فاز برابر باشد.

تمرین 2. گام چرخش را با euler(math.pi / 6) بسازید و 12 بار ضرب را تکرار کنید. در هر مرحله مطمئن شوید که اندازه برابر با 1 باقی می‌ماند و زاویه 30 درجه زیاد می‌شود. نقطه‌ی نهایی باید حداکثر به اندازه‌ی 1e-12 با (1, 0) فاصله داشته باشد.

تمرین 3. نقاط زمانی را با t=n/32t = n/32 تولید کرده و dft را فراخوانی کنید. فقط بازه‌های 0 تا 15 را تحلیل کنید، چون نیمه‌ی بالایی آینه‌ی نیمه‌ی اول است. اندازه‌ی طیف در بازه‌ی kk برای یک موج سینوسی با دامنه‌ی AA برابر با AN/2AN/2 است؛ بنابراین انتظار مقداری نزدیک به 16 در بازه‌ی 3 و نزدیک به 8 در بازه‌ی 7 داشته باشید.

تمرین 4. تابع roots_of_unity(8) را فراخوانی کرده و ریشه‌ها را با هم جمع کنید: اندازه‌ی این مجموع باید بسیار نزدیک به 0 باشد. هر ریشه را بر ریشه‌ی قبلی تقسیم کنید و بررسی کنید که مقدار همه‌ی آن‌ها برابر با euler(2 * math.pi / 8) باشد.

تمرین 5. ماتریس دوران به‌صورت ‎[[cos t, -sin t], [sin t, cos t]]‎ است. برای هر زاویه و نقطه، حاصل euler(t) * Complex(x, y) و حاصل‌ضرب ماتریسی را حساب کنید؛ سپس بیشترین اختلاف قدرمطلق را یادداشت کنید. باید به عددی نزدیک به 10−1510^{-15} برسید.

اصطلاحات کلیدی

اصطلاح مفهوم
عدد مختلط (Complex number) عددی به‌شکل a+bia + bi که در آن aa بخش حقیقی، bb بخش موهومی و i2=−1i^2 = -1 است
واحد موهومی (Imaginary unit) عدد ii که با رابطه‌ی i2=−1i^2 = -1 تعریف می‌شود. از دیدگاه ریاضی یک موجودیت ناممکن نیست، بلکه یک عملگر چرخش است
صفحه‌ی مختلط (Complex plane) صفحه‌ای دوبعدی که در آن محور x حقیقی و محور y موهومی است؛ به آن صفحه‌ی آرگاند (Argand plane) هم می‌گویند
اندازه / قدر مطلق (Magnitude / modulus) فاصله از مبدأ مختصات: a2+b2\sqrt{a^2 + b^2}. به‌صورت ∣z∣\lvert z \rvert نوشته می‌شود
فاز / آرگومان (Phase / argument) زاویه نسبت به محور مثبت حقیقی: atan2(b,a)\mathop{\mathrm{atan2}}(b, a). به‌صورت arg⁡(z)\arg(z) نوشته می‌شود
مزدوج (Conjugate) تصویر آینه‌ای نسبت به محور حقیقی: مزدوج a+bia + bi برابر با a−bia - bi است
فرم قطبی (Polar form) نمایش zz به‌صورت reiθr e^{i\theta} به‌جای a+bia + bi که محاسبات ضرب را ساده می‌کند
فرمول اویلر (Euler's formula) رابطه‌ی eiθ=cos⁡θ+isin⁡θe^{i\theta} = \cos\theta + i \sin\theta که توابع نمایی را به مثلثات پیوند می‌زند
فازور (Phasor) یک عدد مختلط در حال چرخش eiωte^{i\omega t} که سیگنالی سینوسی را نمایش می‌دهد
ریشه‌های واحد (Roots of unity) تعداد NN عدد مختلط به‌شکل e2πik/Ne^{2\pi i k/N} به‌ازای k=0k = 0 تا N−1N-1؛ یعنی NN نقطه‌ی متساوی‌الفاصله روی دایره‌ی واحد
DFT تبدیل فوریه‌ی گسسته (Discrete Fourier Transform)؛ سیگنال را با استفاده از ریشه‌های واحد به مؤلفه‌های سینوسی مختلط تجزیه می‌کند
RoPE امبدینگ مکانی چرخشی (Rotary Position Embedding)؛ استفاده از ضرب مختلط برای کدگذاری موقعیت نسبی در مکانیزم اتنشن ترنسفورمر

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسواحد موهومی i چگونه تعریف می‌شود؟
  2. پیش از درسفرمول اویلر e^(i*theta) برابر با چیست؟
  3. پس از درسحاصل عبارت (3 + 2i)(1 + 4i) چیست؟
  4. پس از درسچرا در امبدینگ موقعیت دورانی (RoPE) برای ترنسفورمرها از اعداد مختلط استفاده می‌شود؟
  5. پس از درسریشه‌های N-ام واحد، N نقطه‌ی متقارن با فواصل یکسان روی دایره‌ی واحد هستند. مجموع آن‌ها چقدر است؟

سؤالات متداول

چرا واحد موهومی (i) در واقعیت یک ترفند خیالی نیست و چه کاربردی در یادگیری ماشین دارد؟

واحد موهومی از نظر هندسی یک عملگر چرخش 90 درجه در صفحه است. در مدل‌های هوش مصنوعی مانند RoPE در ترنسفورمرها و همچنین در تبدیل فوریه (DFT)، از این خاصیت چرخش برای کدگذاری موقعیت نسبی توکن‌ها و تحلیل نوسانات فرکانسی بدون نیاز به روابط پیچیده‌ی مثلثاتی استفاده می‌شود.

رابطه‌ی فرمول اویلر با تبدیل فوریه‌ی گسسته (DFT) چیست؟

فرمول اویلر توابع نمایی مختلط را به توابع سینوسی و کسینوسی تبدیل می‌کند و دایره‌ی واحد را می‌سازد. در الگوریتم DFT، با استفاده از ریشه‌های واحد (نقاط مساوی روی همین دایره)، سیگنال اصلی به مؤلفه‌های فازوری با فرکانس‌های مشخص تجزیه می‌شود.

امبدینگ مکانی RoPE در مدل‌های زبانی چه ارتباطی با اعداد مختلط دارد؟

روش RoPE با ضرب بردارهای query و key در ماتریس‌های دوران مختلط، موقعیت نسبی توکن‌ها را به زاویه‌ی چرخش تبدیل می‌کند. با این کار، فاصله‌ی نسبی میان کلمات مستقیماً از طریق ضرب مختلط در مکانیزم اتنشن مدل اثر می‌گذارد.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.