پل زدن نسبیت عددی و تمایز خودکار با استفاده از JAX

Summarize this content to 400 words in Persian Lang
مقدمه
نظریه نسبیت عام آلبرت انیشتین موفق ترین تصویری است که تا به امروز از نحوه عملکرد گرانش داریم. این زیربنای درک فعلی ما از فیزیک ستارگان، کهکشان ها و خود جهان است. این تئوری پیشبینیهای صوتی و قابل آزمایشی مانند امواج گرانشی، سیاهچالهها، انفجار بزرگ و اتساع زمان گرانشی ایجاد کرده است، پیشبینیهایی که در آزمون زمان ایستادهاند و بارها و بارها بهطور تجربی تأیید شدهاند.
این پیشبینیها همچنین به توسعه برنامههای کاربردی و واقعی مانند بهبود قابلیتهای GPS به دلیل توانایی درک اثرات گرانش زمین بر زمانسنجی و همگامسازی برای ماهوارههایی که در مجاورت فضای نزدیک به زمین کار میکنند، هدایت کرده است.
در قلب ریاضیات نسبیت عام، زبان حساب تانسور و هندسه دیفرانسیل وجود دارد که نسخه ای برای تمایز دلخواه ساختارهای چند خطی در منیفولدهای صاف و نیمه ریمانی ارائه می دهد.
تصادفاً، تانسورها همچنین روشی هستند که دادهها در هوش مصنوعی و یادگیری عمیق مدلسازی میشوند و ساختاری مناسب برای مدیریت دادهها در انواع شکلها و اندازهها فراهم میکنند. نیاز به حل مسائل بهینهسازی کارآمد و تا حداکثر دقت ماشین به منظور یادگیری ویژگیها و الگوها از دادهها تا بهترین حد ممکن، منجر به توسعه تکنیک تمایز خودکار، روشی قویتر برای محاسبه مشتقات به صورت عددی شد. تمایز خودکار برای تانسورهای شکلها و اندازههای دلخواه از آن زمان در کتابخانههای یادگیری عمیق روزانه مانند PyTorch و JAX اصلاح و پیادهسازی شده است تا در درجه اول برای ساخت معماری شبکههای عصبی مورد استفاده قرار گیرد.
در این قطعه، من از JAX و تکنیک تمایز خودکار برای کشف این پل بین ریاضیات نسبیت عام و یادگیری عمیق استفاده میکنم تا این همافزایی را به پیش ببرم و روشها و ابزارهای عالی ساخت شبکههای عصبی را به نسبیت عددی برسانم. محاسبات علمی
تمایز خودکار چیست؟
تمایز خودکار تکنیکی برای محاسبه مشتق یک تابع بسیار کارآمد و با دقت عددی دقیق است. دو ادعایی که نمی توان برای تمایز عددی و نمادین مطرح کرد، که در حال حاضر روش های غالب برای محاسبه مشتقات در محاسبات علمی هستند.
تمایز نمادین شامل دستکاری خودکار نمادها و در عین حال رعایت قوانین جبر و ریاضیات برای استخراج عبارات دقیق برای مشتقات است. این شکل از تمایز معمولاً به یک CAS (سیستم جبر رایانه ای) نیاز دارد که دانش نحوه انجام تمایز با دست با استفاده از قواعد حساب دیفرانسیل و انتگرال و جبر را داشته باشد. در حالی که تمایز نمادین به واسطه تولید عبارات دقیق مشتقات، نتایج دقیقی را ارائه میدهد، از نظر محاسباتی گرانترین شکل تمایز است که در حوزههای سرعت و کارایی فاقد آن است. نمونه هایی از نرم افزار تمایز نمادین عبارتند از Mathematica، SageMath و SymPy.
تمایز عددی مشتقات را با استفاده از روش تفاوت های متناهی برای تقریب تعریف حد تمایز با اصول اول محاسبه می کند. در حالی که سریعتر از تمایز نمادین است، اما با مسائل مربوط به دقت و ثبات ناشی از محاسبات ممیز شناور مواجه است. نقاط درد رایج شامل ناپایداری عددی به دلیل تقسیم بر اعداد بسیار کوچک است که باعث انفجار عبارات می شود، نقطه شناور میانی خطاهایی را که در بین عبارات جمع می شود و منجر به واگرایی از مشتق واقعی می شود، و محدودیت های دقت ممیز شناور و ذخیره سازی در کلاسیک امروزی است. محاسبات
تمایز خودکار قصد دارد با ردیابی تمام عملیات تعریف شده و ساخت یک DAG (گراف غیر چرخه ای جهت دار) برای تابع هدف، و محاسبه گرادیان برای هر متغیر با ردیابی به عقب در نمودار از طریق قانون زنجیره، همه این مسائل را دور بزند. این اساساً نحوه بهینهسازی شبکههای عصبی عمیق، از طریق چیزی به نام انتشار پسانداز – نوعی تمایز خودکار – انجام میشود. Autodiff در قلب یادگیری ماشین مدرن و کتابخانههای یادگیری عمیق است tensorflow، pytorch و jax. PyTorch torch.autograd ماژول روش هایی را برای اجرای autodiff روی تانسورهای PyTorch ارائه می دهد که برای آموزش شبکه های عصبی به منظور به حداقل رساندن افت پیش بینی (خطا) و بهبود دقت خروجی ها استفاده می شود.
برای توضیح بصری تمایز خودکار، بررسی کنید: https://www.youtube.com/watch?v=wG_nF1awSSY&t=2s
برای پیاده سازی تمایز خودکار خودتان، این آموزش ساخت را بررسی کنید micrograd، یک موتور کوچک خودکار، توسط آندری کارپاتی باهوش، مقدمه املای شبکه های عصبی و انتشار پس زمینه: ساخت میکروگراد. این آموزش همچنین به عنوان یک مقدمه عملی عالی برای دنیای مدرن ماشینی/یادگیری عمیق و چارچوب های درگیر مانند tensorflow و pytorch زیرا شما اساساً نسخه کوچکتری از آنها می سازید.
JAX چیست؟
jax یک کتابخانه یادگیری ماشینی و محاسبات علمی با کارایی بالا برای جبر چند خطی، تمایز خودکار، و برای نوشتن کد عددی عملکردی است که میتواند روی CPUها و همچنین شتابدهندههایی مانند GPU و TPU برای افزایش سرعت سودآور اجرا شود.
به طور خلاصه، jax است numpy با پشتیبانی از autodiff (تمایز خودکار). این را می گویم چون jax's API مطابقت 1-1 با numpy دارد که باعث می شود jax جایگزینی برای numpy.
در مقایسه با سایر کتابخانه های یادگیری ماشینی مانند tensorflow و pytorch که تقریباً با همه چیزهایی که برای انجام یادگیری ماشینی در هر مقیاسی نیاز دارید، همراه است، jax با طراحی لاغرتر و ساده تر، که با اندازه کوچکتر نشان داده می شود، فلسفه “ساده زیباست” را می پذیرد (jax 9 مگابایت است در حالی که کتابخانه های دیگر دوست دارند pytorch و tensorflow هنگام نصب با پشتیبانی CUDA از 1 گیگابایت فراتر رود). jax می تواند بیشتر توسط کتابخانه هایی مانند flox و equinox برای تقویت قابلیت های خود برای انجام کارهایی مانند ساخت و آموزش شبکه های عصبی، قرار دادن اسماً آن با کتابخانه های بزرگتر مانند tensorflow و pytorch.
این چه ربطی به نسبیت عام دارد؟
اولا، GR به زبان تانسورها و جبر چند خطی فرموله شده است. تانسور یک آرایه چند بعدی از اعداد است که به عنوان تعمیم بردارها و ماتریس ها به ابعاد بالاتر عمل می کند. مانند بردارها و ماتریسها، میتوانیم حساب دیفرانسیل و انتگرال را روی تانسورها انجام دهیم، که بخش بزرگی از محاسباتی است که در GR انجام میدهیم (محاسبات نمادهای کریستوفل و غیره).
تانسورها همچنین زبان شبکه های عصبی و یادگیری عمیق هستند. دادههای ورودی و خروجی، و پارامترهایی مانند وزنها و بایاسهای شبکه عصبی، بهعنوان تانسور ذخیره میشوند تا در هنگام نمایش دادهها با اشکال و اندازههای مختلف، انعطافپذیری ایجاد شود. همچنین برای آموزش شبکه های عصبی باید بتوانیم مشتقات تانسورها را محاسبه کرده و بر روی آنها محاسبات انجام دهیم. همانطور که ممکن است جمع آوری شود، این بدان معنی است که یک تقاطع طبیعی بین GR و یادگیری عمیق در مورد زبانی که آنها برای نمایش و دستکاری داده ها استفاده می کنند وجود دارد. البته، تفاوتهای مفهومی فراوانی وجود دارد که هنگام تلاش برای درک این همافزایی باید در نظر داشت. به عنوان مثال، ریاضیات نسبیت عام (و حساب تانسوری به طور کلی) یک کمیت نمایه شده را به عنوان یک تانسور بر اساس ویژگی های تبدیل آن تعریف می کند، در حالی که هر کمیت نمایه شده (مثلاً نمادهای کریستوفل) به عنوان یک تانسور در یادگیری عمیق واجد شرایط است. با این حال، چنین جزئیاتی نکات فنی هستند که با اعمال نظارت کافی می توان آنها را در نظر داشت و در نظر گرفت.
پیشرفت های سریع در زمینه هوش مصنوعی در چند دهه گذشته منجر به ایجاد روش ها و ابزارهای کارآمد و دقیق برای جبر تانسور و حساب دیفرانسیل و انتگرال شده است. تفکیک خودکار و jax تنها برخی از این روش ها و ابزارهای بسیار هستند، اما به دلیل کاربردهای بالقوه آنها در زمینه فیزیک، برجسته هستند. با این حال، من متوجه شدهام که استفاده از این ابزارها و روشهایی که برای AI/ML برای حل مشکلات محاسباتی و بهبود محاسبات انجامشده در فیزیک مدرن ساخته و اصلاح شدهاند، وجود ندارد. من تا حدودی این را به ماهیت بدیع خود ابزارها نسبت میدهم، و مطمئن هستم که با توجه به زمان و تلاش کافی، پذیرش گستردهای از آنها در بسیاری از زیرشاخههای مختلف فیزیک وجود خواهد داشت.
در واقع، چنین پذیرشی قبلاً با کاربردهای یافتن تمایز خودکار در دینامیک سیالات و حل معادلات دیفرانسیل آغاز شده است. با این حال، از جستجوی من در interweb و arxiv، حوزه نسبیت عام، و به طور خاص نسبیت عددی، که با محاسبه عددی مقادیر و حل معادلات نظریه نسبیت عام اینشتین سروکار دارد، چنین پذیرشی نداشته است، که من معتقدم. زمان تغییر است
ما چه کار می کنیم؟
در این تمرین استفاده خواهم کرد jax برای نشان دادن قدرت autodiff با کاوش پتانسیل و کاربرد آن در زمینه نسبیت عددی.
با توجه به یک متریک و برخی مختصات، نحوه محاسبه مشتقات تانسور متریک (نمادهای کریستوفل) و سایر تانسورها و کمیت های مرتبط، مانند تانسورهای ریمان و ریچی، انحنای اسکالر ریچی و ثابت کرچمان را بررسی خواهیم کرد تا در نهایت تانسور اینشتین و تانسور تنش-انرژی- تکانه را محاسبه کنید.
ما از ویژگی های مدرن پایتون مانند تایپ اشاره، که در نسخه های اخیر پایتون (3.11، 3.12، …) معرفی شد و به ما اجازه می دهد تا به صراحت انواع داده های متغیرهایی را که در کد خود استفاده می کنیم مشخص کنیم تا خوانایی بهتر و ایمنی تایپ را فعال کنیم، و دکوراتورهاکه توابع مرتبه بالاتری هستند که رفتار توابع داده شده به آنها را به عنوان ورودی تغییر می دهند/افزایش می دهند تا ورودی/خروجی توابع را برای یک هدف خاص تغییر دهند.
توجه: برای سهولت در تفسیر محاسبات هنگام استخراج مقادیر عددی مقادیر، ما منحصراً در واحدهای SI کار خواهیم کرد و نه واحدهای طبیعی.
راه اندازی
ما با وارد کردن وابستگی ها از کتابخانه تایپ برای پشتیبانی از نوع اشاره و وارد کردن شروع می کنیم jax + نوع ناقص آن jax.numpy.
ما پیکربندی می کنیم jax برای اینکه تمام اعداد ممیز شناور را مجبور کنیم تا با دقت 64 بیتی برای دقت بالاتر در نتایج ما باشند.
ما همچنین یک تابع دکوراتور کاربردی را تعریف می کنیم close_to_zero برای کمک به گرد کردن مقادیر نزدیک به صفر و زیر یک تلورانس دلخواه انتخاب شده در تانسورهای ما به منظور کاهش خطاهای ممیز شناور ناشی از مسائل مربوط به دقت عددی ترکیبی در مراحل محاسبه حسابی میانی.
from typing import Callable
import jax
import jax.numpy as jnp
jax.config.update(“jax_enable_x64”, True)
TOLERANCE = 1e-8
def close_to_zero(func):
def wrapper(*args, **kwargs) -> jnp.ndarray:
result: jnp.ndarray = func(*args, **kwargs)
return jnp.where(jnp.abs(result) < TOLERANCE, 0.0, result)
return wrapper
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
تعریف معیارهای رایج
ما برخی از معیارهای رایج را تعریف می کنیم که به عنوان نمونه های بی اهمیت برای بقیه آموزش استفاده می شوند.
# while the minkowski metric is a constant tensor that is not coordinate dependent,
# we still need to take in some “dummy” coordinates in order to make this function play nice with JAX’s autodiff mechanism
def minkowski_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
“””Returns the Minkowski metric in float64 precision with the (-1, 1, 1, 1) metric signature”””
return jnp.diag(jnp.array([-1, 1, 1, 1], dtype=jnp.float64))
# this is the standard metric for a 2-sphere.
@close_to_zero
def spherical_polar_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
r, theta, phi = coordinates
return jnp.diag(jnp.array([1, r**2, r**2 * jnp.sin(theta)**2], dtype=jnp.float64))
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
نمادهای کریستوفل
با توجه به یک متریک
gمنjg_{ij} gijرا
نمادهای کریستوفل از نوع دوم (که اتصال افین یا ضرایب اتصال نیز نامیده می شود) به عنوان مشتقاتی از متریک منقبض شده با تانسور متریک معکوس تعریف می شوند.
gمنjg^{ij} gij
:
سیکلj=12gjمتر(∂gمترک∂xل+∂gلمتر∂xک-∂gکل∂xمتر)\Gamma_{kl}^{j} = \frac{1}{2} g^{jm} \left( \frac{\partial g_{mk} }{\partial x^l } + \frac{\partial g_ {lm} }{\partial x^k } – \frac{\partial g_{kl} }{\partial x^m } \right) سیکلjرا=21راgjm(∂xل∂gmkرارا+∂xک∂gلمتررارا-∂xمتر∂gکلرارا)
نکته: این تعریف و تعریف های بعدی از آن گرفته شده است روش های ریاضی برای دانشجویان رشته فیزیک و رشته های مرتبط توسط صدری حسنی و از تمام شاخص های رومی استفاده می کند. ما همین کار را انجام خواهیم داد و از تمام شاخصهای رومی در طول این آموزش استفاده خواهیم کرد، حتی زمانی که با کمیتهای فضازمان سروکار داریم و نه فقط کمیتهای دکارتی، به دلیل سهولت آنها هنگام مشخص کردن آنها در کد. نمادهای یونانی در مورد نمایش یونیکد زیربنایی آنها بی اهمیت هستند، و این پیچیدگی است که فعلاً می خواهم از آن اجتناب کنم.
نمادهای کریستوفل نشان دهنده میدان گرانشی در یک فضازمان معین هستند، که مشتقاتی از متریک هستند که مشابه پتانسیل گرانشی در گرانش نیوتنی هستند.
اکنون یک تابع پایتون برای محاسبه نمادهای کریستوفل تعریف می کنیم. تابع در coordinates برای محاسبه نمادهای کریستوفل در، و metric تابع برای محاسبه نمادهای کریستوفل، و اجرای آن به طور کلی به شرح زیر است:
ما تابع متریک را ارزیابی می کنیم تا متریک را در داده شده بدست آوریم coordinates و با استفاده از تانسور متریک معکوس در طول مسیر محاسبه کنید jnp.linalg.inv.
استفاده می کنیم jax.jacfwd برای محاسبه “ژاکوبین” متریک، یعنی مشتقات جزئی آن با توجه به مختصات داده شده، با استفاده از تمایز خودکار رو به جلو. این است
∂gکل∂xمتر\frac{\partial g_{kl} }{\partial x^m }∂xمتر∂gکلرارا
، همچنین به عنوان نشان داده شده است
gکل;مترg_{kl;m} gکل;متررا
. من “ژاکوبین” را در نقل قول می نویسم زیرا به طور دقیق، ژاکوبین به عنوان ماتریس مشتقات جزئی یک تابع با مقدار برداری با توجه به ورودی های آن تعریف می شود، اما آنچه ما داریم یک تابع با مقدار تانسور به شکل متریک است. . من از هیچ کمیت ریاضی که برای توصیف تانسور با رتبه بالاتر مرتبط با مشتقات یک تابع با مقدار تانسور استفاده می شود، آگاه نیستم، از این رو در اینجا از کلمه “ژاکوبین” بی استفاده استفاده می کنم.
استفاده می کنیم jnp.einsum، یک زیربرنامه بسیار راحت و عملکردی که تانسورهای محاسباتی و سایر اشیاء نمایه شده را با استفاده از نماد شاخص استاندارد دستکاری می کند تا نمادهای کریستوفل را مطابق معادله بالا محاسبه کند.
@close_to_zero # this ensures that any values of our Christoffel symbols are rounded off if they’re close to 0
def christoffel_symbols(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
# evaluate the metric tensor at the coordinates
g = metric(coordinates)
# compute the inverse metric tensor
g_inv = jnp.linalg.inv(g)
# obtain and evaluate the “jacobian” of the metric tensor at the coordinates
jacobian = jax.jacfwd(metric)(coordinates) # this is kl;m
return 0.5 * jnp.einsum(‘jm, klm -> jkl’, g_inv, jnp.einsum(‘klm -> mkl’, jacobian) + jnp.einsum(‘klm -> lmk’, jacobian) – jacobian)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
تانسور پیچشی
تانسور پیچشی به عنوان قسمت ضد متقارن یک اتصال افین عمومی تعریف می شود
سیساعتکل\Gamma^l_{hk} سیhkلرا
:
سیساعتکل-سیکساعتل\Gamma^l_{hk} – \Gamma^l_{kh} سیhkلرا-سیkhلرا
اگر تانسور پیچشی در یک سیستم مختصات ناپدید شود، در تمام سیستم های مختصات ناپدید می شود (تانسور صفر در همه سیستم های مختصات صفر است). بنابراین، تانسور پیچشی یک اتصال افین کلی صفر است اگر و فقط اگر اتصال متقارن باشد، به عنوان مثال،
سیساعتکل=سیکساعتل\Gamma^l_{hk} = \Gamma^l_{kh} سیhkلرا=سیkhلرا
از آنجایی که ما فقط با نمادهای کریستوفل از نوع دوم سروکار داریم که یک و منحصر به فرد است متقارن اتصال affine مشتق شده از تانسور متریک، تمام تانسورهای پیچشی که در این کاوش محاسبه خواهیم کرد باید صفر باشند، و زیربرنامه زیر برای تأیید آن استفاده خواهد شد.
@close_to_zero
def torsion_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
christoffels = christoffel_symbols(coordinates, metric)
return christoffels – jnp.einsum(‘ijk -> ikj’, christoffels)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
تانسور انحنای ریمان و تغییر ناپذیر کرچمان
تانسور ریمان
آرکلمترjR^j_{klm} آرکلمترjرا
انحنای ذاتی منیفولد ریمانی (یا نیمه ریمانی) تولید شده توسط هر متریک معین را رمزگذاری می کند. این به عنوان مشتقات نمادهای کریستوفل تعریف می شود
سیکلj\Gamma^j_{kl} سیکلjرا
به عنوان:
آرکلمترj=∂مترسیکلj-∂لسیکمترj+سیrمترjسیکلr-سیrلjسیکمترrR^j_{klm} = \partial_m \Gamma^j_{kl} – \partial_l \Gamma^j_{km} + \Gamma^j_{rm} \Gamma^r_{kl} – \Gamma^j_{rl} \ گاما^r_{km} آرکلمترjرا=∂مترراسیکلjرا-∂لراسیکیلومترjرا+سیrمترjراسیکلrرا-سیrلjراسیکیلومترrرا
ما یک تابع پایتون تعریف می کنیم که:
از قبلی استفاده می کند christoffel_symbols تابع برای به دست آوردن نمادهای کریستوفل برای یک مجموعه معین از متریک و مختصات.
“ژاکوبین” نمادهای کریستوفل را محاسبه می کند تا به دست آید
سیکل;مترj\Gamma^j_{kl;m} سیکل;مترjرا
.
این تانسور “ژاکوبین” و محصولات نمادهای کریستوفل را با استفاده از دستکاری می کند jnp.einsum برای به دست آوردن تانسور ریمان
ما همچنین یک تابع پایتون را برای محاسبه ثابت کرچمان از تانسور ریمان تعریف می کنیم، یک اسکالر که برای جستجو استفاده می شود. درست است تکینگی های فیزیکی (تکینگی های گرانشی) در منیفولدهای خاص مستقل از انتخاب مختصات:
آرjکلمترآرjکلمترR^{jklm} R_{jklm} آرjkلمترآرjkلمتررا
ما بعداً در این آموزش از ثابت کرچمن استفاده خواهیم کرد تا بررسی کنیم که آیا اجرای تانسور ریمان که در زیر داریم درست است یا نه هنگام استفاده از متریک شوارتزچیلد به عنوان مطالعه موردی برای تأیید صحت این زیر روالها.
@close_to_zero
def riemann_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
christoffels = christoffel_symbols(coordinates, metric)
jacobian = jax.jacfwd(christoffel_symbols)(coordinates, metric) # computes jkl;m
return jacobian – jnp.einsum(‘jklm -> jkml’, jacobian) + jnp.einsum(‘jrm, rkl -> jklm’, christoffels, christoffels) – jnp.einsum(‘jrl, rkm -> jklm’, christoffels, christoffels)
@close_to_zero
def kretschmann_invariant(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
riemann = riemann_tensor(coordinates, metric)
g = metric(coordinates)
g_inv = jnp.linalg.inv(g)
riemann_upper = jnp.einsum(‘pj, qk, rl, ijkl -> ipqr’, g_inv, g_inv, g_inv, riemann) # computes R^{jklm} by contracting with three inverse metric tensors
riemann_lower = jnp.einsum(‘pi, ijkl -> pjkl’, g, riemann) # computes R_{jklm} by contracting with one metric tensor
return jnp.einsum(‘ijkl, ijkl ->’, riemann_upper, riemann_lower)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
تانسور ریچی و انحنای اسکالر ریچی
تانسور ریچی
آرکلR_{kl} آرکلرا
کمیت دیگر مربوط به انحنا است که به عنوان جزء ردیابی تانسور ریمان تعریف می شود.
آرکلمترjR^j_{klm} آرکلمترjرا
. تانسور ریچی با انقباض تنها شاخص متضاد تانسور ریمان با آخرین شاخص کوواریانت آن به دست میآید:
آرکل=آرکلjjR_{kl} = R^j_{klj} آرکلرا=آرکلjjرا
از نظر فیزیکی، تانسور ریچی اطلاعاتی در مورد چگونگی تغییر حجم ها در حضور نیروهای جزر و مدی رمزگذاری می کند.
با بالا بردن یکی از شاخص های تانسور ریچی و انقباض، انحنای اسکالر ریچی را به دست می آوریم.
آر=آرلل=gکلآرکلR = R^l_l = g^{kl}R_{kl} آر=آرللرا=gکلآرکلرا
ما زیر روال های پایتون را برای انجام محاسباتی با استفاده از آن پیاده سازی می کنیم jnp.einsum دوباره برای دستکاری شاخص ها و انجام انقباضات.
@close_to_zero
def ricci_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
riemann = riemann_tensor(coordinates, metric)
return jnp.einsum(‘jklj -> kl’, riemann) # contracting the first and last indices
@close_to_zero
def ricci_scalar(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.float32:
g = metric(coordinates)
g_inv = jnp.linalg.inv(g)
ricci = ricci_tensor(coordinates, metric)
return jnp.einsum(‘kl, kl -> ‘, g_inv, ricci) # trace of the ricci tensor
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
تانسور اینشتین و تانسور تنش-انرژی- تکانه
تانسور اینشتین، جواهر تاج نظریه نسبیت عام، تمام اطلاعات مربوط به انحنای یک منیفولد فضازمان را رمزگذاری می کند و بر اساس تانسور ریچی، تانسور متریک و انحنای اسکالر ریچی به صورت زیر تعریف می شود:
جیمنj≡آرمنj-12gمنjآرG_{ij} \equiv R_{ij} – \frac{1}{2} g_{ij} R جیijرا≡آرijرا-21راgijراآر
سمت چپ معادلات میدان انیشتین (EFEs) را تشکیل میدهد، مجموعهای از 16 معادله دیفرانسیل جزئی جفت شده که انحنای یک منیفولد فضازمان را به محتوای جرم-انرژی موجود در آن مرتبط میکند:
جیمنj=8صجیج4تیمنjG_{ij} = \frac{8 \pi G}{c^4} T_{ij} جیijرا=ج48صجیراتیijرا
سمت راست
تیمنjT_{ij} تیijرا
تانسور تنش-انرژی-تکانه است که اطلاعات مربوط به تمام جرم-انرژی موجود در منیفولد فضا-زمان را رمزگذاری می کند.
توابع پایتون را مینویسیم تا زیرروالهای اجرا شده قبلی را فراخوانی کنیم تا تانسور انیشتین و تانسور تنش-انرژی- تکانه را با استفاده از معادلاتی که قبلاً توضیح دادیم محاسبه کنیم.
@close_to_zero
def einstein_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
g = metric(coordinates)
rt = ricci_tensor(coordinates, metric)
rs = ricci_scalar(coordinates, metric)
return rt – 0.5 * g * rs
@close_to_zero
def stress_energy_momentum_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
G = einstein_tensor(coordinates, metric)
kappa = (8 * jnp.pi * 6.67e-11) / ((299792458)**4)
return G / kappa
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مطالعه موردی 1: متریک 2 کره
با استفاده از تمام توابع پایتون که قبلا تعریف کرده ایم، بیایید محاسبات را در آن انجام دهیم float64 دقت برای متریک 2 کره در مختصات قطبی کروی
(r،من،ϕ)(r، \تتا، \phi) (r،من،ϕ)
به عنوان:
gمنj=دیگ(1،r2،r2گناه2(من))g_{ij} = \text{diag}(1, r^2, r^2 \sin^2(\theta)) gijرا=دیگ(1،r2،r2گناه2(من))
ما از مقادیر مختصات زیر برای محاسبات استفاده می کنیم که به صورت دلخواه انتخاب شده اند
من=ص/3\تتا = \pi/3 من=ص/3
ϕ=ص/2\phi = \p/2 ϕ=ص/2
coordinates = jnp.array([5, jnp.pi/3, jnp.pi/2], dtype=jnp.float64)
metric = spherical_polar_metric
print(f”Christoffel symbols: {christoffel_symbols(coordinates, metric)}”)
print(f”Torsion tensor: {torsion_tensor(coordinates, metric)}”)
print(f”Riemann tensor: {riemann_tensor(coordinates, metric)}”)
print(f”Ricci tensor: {ricci_tensor(coordinates, metric)}”)
print(f”Ricci scalar: {ricci_scalar(coordinates, metric)}”)
print(f”Einstein tensor: {einstein_tensor(coordinates, metric)}”)
print(f”Stress-energy-momentum tensor: {stress_energy_momentum_tensor(coordinates, metric)}”)
print(f”Kretschmann invariant: {kretschmann_invariant(coordinates, metric)}”)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
با اجرای این، دریافت می کنیم
Christoffel symbols: [[[ 0. 0. 0. ] [ 0. -5. 0. ] [ 0. 0. -3.75 ]]
[[ 0. 0.2 0. ] [ 0.2 0. 0. ] [ 0. 0. -0.4330127 ]]
[[ 0. 0. 0.2 ] [ 0. 0. 0.57735027] [ 0.2 0.57735027 0. ]]] Torsion tensor: [[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]] Riemann tensor: [[[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]]
[[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]]
[[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.] [0. 0. 0.] [0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]]
Ricci tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Ricci scalar: 0.0
Einstein tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Stress-energy-momentum tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Kretschmann invariant: 0.0
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
ما تمام نمادهای کریستوفل را برای این متریک به دست می آوریم. علاوه بر این، همانطور که انتظار میرفت، تانسور ریمان، تانسور ریچی، اسکالر ریچی، تانسور انیشتین و تانسور تنش-انرژی-تکانه همگی ناپدید میشوند زیرا این متریک فضازمان مسطح را بدون انحنا و محتوای جرم-انرژی توصیف میکند. تانسور پیچشی نیز همانطور که از ماهیت متقارن نمادهای کریستوفل انتظار می رود صفر است.
مطالعه موردی 2: متریک شوارتزشیلد
اکنون به یک مطالعه موردی جالبتر میرسیم، متریک شوارتزشیلد، که فضازمان یک جسم متقارن بدون بار، غیرچرخش و کروی در خلاء را توصیف میکند. متریک شوارتزشیلد در مختصات فضای زمان قطبی کروی سنتی
(تی،r،من،ϕ)(t، r، \تتا، \phi) (تی،r،من،ϕ)
به صورت زیر داده می شود:
gمنj=دیگ(-(1-rسr)ج2،1(1-rسr)،r2،r2گناه2(من))g_{ij} = \text{diag}\left(- \left( 1 – \frac{r_s}{r} \right) c^2, \frac{1}{\left(1 – \frac{r_s} {r} \right)}, r^2, r^2 \sin^2(\theta) \right) gijرا=دیگ(-(1-rrسرارا)ج2،(1-rrسرارا)1را،r2،r2گناه2(من))
کجا
rسr_s rسرا
شعاع شوارتزشیلد جسم عظیم است، ضریب مقیاسی که با جرم آن مرتبط است
مم م
توسط:
rس=2جیمج2r_s = \frac{2 GM}{c^2} rسرا=ج22جنرال موتورزرا
ما دقیقاً مانند مطالعه موردی قبلی انجام میدهیم و همه مقادیر را محاسبه میکنیم float64 دقت برای جسمی با جرم 4.3 میلیون خورشیدی با استفاده از مختصات قطبی کروی فضازمان انتخاب شده زیر
من=ص/3\تتا = \pi/3 من=ص/3
ϕ=ص/2\phi = \p/2 ϕ=ص/2
G = 6.67e-11
c = 299792458.0
M = 4.297e+6 * 1.989e+30 # 4.3 million solar masses, mass of Sgr A*
# schwarzschild radius
rs = (2 * G * M) / c**2
@close_to_zero
def schwarzschild_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
t, r, theta, phi = coordinates
return jnp.diag(jnp.array([-(1 – (rs / r)) * c**2, 1/(1 – (rs/r)), r**2, r**2 * jnp.sin(theta)**2], dtype=jnp.float64))
coordinates = jnp.array([3600, 3000, jnp.pi/3, jnp.pi/2], dtype=jnp.float64)
metric = schwarzschild_metric
print(f”Christoffel symbols: {christoffel_symbols(coordinates, metric)}”)
print(f”Torsion tensor: {torsion_tensor(coordinates, metric)}”)
print(f”Riemann tensor: {riemann_tensor(coordinates, metric)}”)
print(f”Ricci tensor: {ricci_tensor(coordinates, metric)}”)
print(f”Ricci scalar: {ricci_scalar(coordinates, metric)}”)
print(f”Einstein tensor: {einstein_tensor(coordinates, metric)}”)
print(f”Stress-energy-momentum tensor: {stress_energy_momentum_tensor(coordinates, metric)}”)
print(f”Kretschmann invariant: {kretschmann_invariant(coordinates, metric)}”)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
اجرای این خروجی ها
Christoffel symbols: [[[ 0.00000000e+00 -1.66666706e-04 0.00000000e+00 0.00000000e+00] [-1.66666706e-04 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[-2.67840757e+26 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 1.66666706e-04 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 1.26857006e+10 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 9.51427546e+09]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 3.33333333e-04 0.00000000e+00] [ 0.00000000e+00 3.33333333e-04 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -4.33012702e-01]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 3.33333333e-04] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.77350269e-01] [ 0.00000000e+00 3.33333333e-04 5.77350269e-01 0.00000000e+00]]] Torsion tensor: [[[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]
[[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]
[[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]
[[0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.] [0. 0. 0. 0.]]] Riemann tensor: [[[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 1.11111137e-07 0.00000000e+00 0.00000000e+00] [-1.11111137e-07 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 2.11428394e+06 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [-2.11428394e+06 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.58571295e+06] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [-1.58571295e+06 0.00000000e+00 0.00000000e+00 0.00000000e+00]]]
[[[ 0.00000000e+00 1.78560505e+23 0.00000000e+00 0.00000000e+00] [-1.78560505e+23 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 2.11428394e+06 0.00000000e+00] [ 0.00000000e+00 -2.11428394e+06 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.58571295e+06] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -1.90734863e-06] [ 0.00000000e+00 -1.58571295e+06 1.90734863e-06 0.00000000e+00]]]
[[[ 0.00000000e+00 0.00000000e+00 -8.92802525e+22 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 8.92802525e+22 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 5.55555687e-08 0.00000000e+00] [ 0.00000000e+00 -5.55555687e-08 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -3.17142590e+06] [ 0.00000000e+00 0.00000000e+00 3.17142590e+06 0.00000000e+00]]]
[[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -8.92802525e+22] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 8.92802525e+22 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.55555687e-08] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 -5.55555687e-08 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.22856787e+06] [ 0.00000000e+00 0.00000000e+00 -4.22856787e+06 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]]]
Ricci tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Ricci scalar: 0.0
Einstein tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Stress-energy-momentum tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Kretschmann invariant: 2.649005370647907
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
مانند قبل، نمادهای کریستوفل خود را برای متریک شوارتزشیلد به دست آوردهایم و تانسور پیچشی همانطور که انتظار میرفت صفر است.
علاوه بر این، از آنجایی که متریک شوارتزشیلد یک راه حل خلاء برای معادلات میدان انیشتین است، تانسور ریچی، اسکالر ریچی، تانسور اینشتین و تانسور تنش-انرژی- تکانه همگی صفر هستند.
با این حال، توجه کنید که تانسور ریمان صفر نیست. در واقع، برخی از اجزای آن از نظر قدر بسیار بزرگ هستند. ما همچنین مقداری برای ثابت کرچمن از انقباض تانسور ریمان بدست می آوریم. برای تأیید این موضوع و در نتیجه تأیید اینکه آیا اجزای تانسور ریمان محاسبه شده ما صحیح هستند یا نه، میتوانیم ثابت کریچمن را مستقیماً با استفاده از یک فرمول اسکالر نسبتاً بیاهمیت محاسبه کنیم:
آرjکلمترآرjکلمتر=48جی2م2ج4r6R^{jklm} R_{jklm} = \frac{48 G^2 M^2}{c^4 r^6} آرjkلمترآرjkلمتررا=ج4r648جی2م2را
G = 6.67e-11
M = 4.297e+6 * 1.989e+30 # 4.3 million solar masses, mass of Sgr A*
c = 299792458.0
r = 3000
kr = (48 * G**2 * M**2) / (c**4 * r**6)
print(“Kretschmann invariant is”, kr)
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
با اجرای این، خروجی را دریافت می کنیم
Kretschmann invariant is 2.649005370647906
وارد حالت تمام صفحه شوید
از حالت تمام صفحه خارج شوید
که با نتیجه ای که با انقباض همه شاخص های تانسور ریمان تا 15 رقم اعشار به دست آوردیم مطابقت دارد!
در این کاوش، قدرت تمایز خودکار را در محاسبات مشتق از همه کمیت ها تا حداکثر دقت ماشین از نظر دقت ممیز شناور، شاهد بودیم.
ما اثربخشی و سادگی JAX را دیدیم jax.jacfwd برای محاسبه ژاکوبین ها/مشتقات تانسورها در تمایز خودکار حالت رو به جلو.
ما همچنین مزایای JAX را دیده ایم jnp.einsum با توانایی آن در انجام دستکاری شاخص و انجام محاسبات در سطح بالا، به فرد اجازه می دهد تا عملیات حساب تانسور را به شیوه ای راحت و کارآمد انجام دهد. زبان تانسورها و حساب تانسوری در سایر موضوعات و زمینه های فیزیک نظری مانند الکترومغناطیس کوواریانت و نظریه میدان کوانتومی فراگیر است. دست کم، کشف یک رویکرد مشابه با استفاده از کتابخانهها و چارچوبهای مدرن AI/ML به منظور انجام محاسبات تانسور برای محاسبات ناشی از این زمینهها، تمرین جالبی خواهد بود.
قابلیتهای JAX به ما این امکان را میدهد که همه این کدها را موازی کنیم و آن را بر روی شتابدهندههایی مانند GPU و TPU بدون هیچ تغییری در کد اصلی اجرا کنیم تا محاسبات برای محاسبات عددی سنگین و شبیهسازیهایی که نیاز به موازیسازی، سرعت و کارایی دارند، سرعت ببخشیم. ما آن جنبه را به طور خاص در این نمایش بررسی نکردهایم، و همه محاسبات روی CPU انجام شدهاند، زیرا هیچ یک از محاسبات یا موارد استفاده به استفاده از موازیسازی و شتابدهندهها نیاز ندارد، اما با این وجود، این قابلیتها وجود دارد و میتوان در صورت استفاده خاص از آن استفاده کرد. آن را می طلبد.
توضیحات، اسکریپت ها و نتایج این کاوش نیز به راحتی در این دفترچه یادداشت Jupyter که در Google Colab میزبانی شده است، مستند شده است، که می توانید از آن برای بازتولید و ایجاد ایده های ارائه شده در اینجا استفاده کنید.
کار آینده
برخی از ایده ها و برنامه های کاربردی در این جهت کلی که ارزش بررسی دارند:
همین محاسبات را برای سایر معیارهای برجسته مانند معیارهای Kerr و Kerr-Newmann انجام دهید.
توابعی را برای محاسبه تانسور ویل و متغیر ویل، دیگر کمیت های مهم مرتبط با انحنا بنویسید.
در اینجا پیاده سازی های جایگزین اما معادل PyTorch و Tensorflow را برای پیاده سازی JAX ارائه دهید.
استفاده کنید @jax.jit دکوراتور در زیر روال های مربوطه برای استفاده از کامپایل JIT به منظور سرعت بخشیدن به محاسبات.
نگاه کنید jax.jacrev برای تمایز خودکار حالت معکوس و سعی کنید آن را با آن ترکیب کنید jax.jacfwd برای سرعت و دقت بهینه
این کد را طوری پیکربندی کنید که روی GPU ها و سایر شتاب دهنده ها اجرا شود.
آموزش یک شبکه عصبی برای پارامترسازی تانسور متریک و حل یک مسئله بهینه سازی به منظور یافتن اجزای تانسور متریک از داده ها.
نمادهای کریستوفل را برای یک متریک محاسبه کنید و معادله ژئودزیکی را حل کنید تا EOM را با استفاده از حلکنندههای معادلات دیفرانسیل قدرت تفکیک خودکار، مانند diffrax
این روش شناسی را به جنبه ها و محاسبات دیگر نسبیت عددی گسترش دهید، به ویژه آنهایی که توسط کتابخانه های پایتون نسبیت عام رایج مانند EinsteinPy
مقدمه
نظریه نسبیت عام آلبرت انیشتین موفق ترین تصویری است که تا به امروز از نحوه عملکرد گرانش داریم. این زیربنای درک فعلی ما از فیزیک ستارگان، کهکشان ها و خود جهان است. این تئوری پیشبینیهای صوتی و قابل آزمایشی مانند امواج گرانشی، سیاهچالهها، انفجار بزرگ و اتساع زمان گرانشی ایجاد کرده است، پیشبینیهایی که در آزمون زمان ایستادهاند و بارها و بارها بهطور تجربی تأیید شدهاند.
این پیشبینیها همچنین به توسعه برنامههای کاربردی و واقعی مانند بهبود قابلیتهای GPS به دلیل توانایی درک اثرات گرانش زمین بر زمانسنجی و همگامسازی برای ماهوارههایی که در مجاورت فضای نزدیک به زمین کار میکنند، هدایت کرده است.
در قلب ریاضیات نسبیت عام، زبان حساب تانسور و هندسه دیفرانسیل وجود دارد که نسخه ای برای تمایز دلخواه ساختارهای چند خطی در منیفولدهای صاف و نیمه ریمانی ارائه می دهد.
تصادفاً، تانسورها همچنین روشی هستند که دادهها در هوش مصنوعی و یادگیری عمیق مدلسازی میشوند و ساختاری مناسب برای مدیریت دادهها در انواع شکلها و اندازهها فراهم میکنند. نیاز به حل مسائل بهینهسازی کارآمد و تا حداکثر دقت ماشین به منظور یادگیری ویژگیها و الگوها از دادهها تا بهترین حد ممکن، منجر به توسعه تکنیک تمایز خودکار، روشی قویتر برای محاسبه مشتقات به صورت عددی شد. تمایز خودکار برای تانسورهای شکلها و اندازههای دلخواه از آن زمان در کتابخانههای یادگیری عمیق روزانه مانند PyTorch و JAX اصلاح و پیادهسازی شده است تا در درجه اول برای ساخت معماری شبکههای عصبی مورد استفاده قرار گیرد.
در این قطعه، من از JAX و تکنیک تمایز خودکار برای کشف این پل بین ریاضیات نسبیت عام و یادگیری عمیق استفاده میکنم تا این همافزایی را به پیش ببرم و روشها و ابزارهای عالی ساخت شبکههای عصبی را به نسبیت عددی برسانم. محاسبات علمی
تمایز خودکار چیست؟
تمایز خودکار تکنیکی برای محاسبه مشتق یک تابع بسیار کارآمد و با دقت عددی دقیق است. دو ادعایی که نمی توان برای تمایز عددی و نمادین مطرح کرد، که در حال حاضر روش های غالب برای محاسبه مشتقات در محاسبات علمی هستند.
تمایز نمادین شامل دستکاری خودکار نمادها و در عین حال رعایت قوانین جبر و ریاضیات برای استخراج عبارات دقیق برای مشتقات است. این شکل از تمایز معمولاً به یک CAS (سیستم جبر رایانه ای) نیاز دارد که دانش نحوه انجام تمایز با دست با استفاده از قواعد حساب دیفرانسیل و انتگرال و جبر را داشته باشد. در حالی که تمایز نمادین به واسطه تولید عبارات دقیق مشتقات، نتایج دقیقی را ارائه میدهد، از نظر محاسباتی گرانترین شکل تمایز است که در حوزههای سرعت و کارایی فاقد آن است. نمونه هایی از نرم افزار تمایز نمادین عبارتند از Mathematica
، SageMath
و SymPy
.
تمایز عددی مشتقات را با استفاده از روش تفاوت های متناهی برای تقریب تعریف حد تمایز با اصول اول محاسبه می کند. در حالی که سریعتر از تمایز نمادین است، اما با مسائل مربوط به دقت و ثبات ناشی از محاسبات ممیز شناور مواجه است. نقاط درد رایج شامل ناپایداری عددی به دلیل تقسیم بر اعداد بسیار کوچک است که باعث انفجار عبارات می شود، نقطه شناور میانی خطاهایی را که در بین عبارات جمع می شود و منجر به واگرایی از مشتق واقعی می شود، و محدودیت های دقت ممیز شناور و ذخیره سازی در کلاسیک امروزی است. محاسبات
تمایز خودکار قصد دارد با ردیابی تمام عملیات تعریف شده و ساخت یک DAG (گراف غیر چرخه ای جهت دار) برای تابع هدف، و محاسبه گرادیان برای هر متغیر با ردیابی به عقب در نمودار از طریق قانون زنجیره، همه این مسائل را دور بزند. این اساساً نحوه بهینهسازی شبکههای عصبی عمیق، از طریق چیزی به نام انتشار پسانداز – نوعی تمایز خودکار – انجام میشود. Autodiff در قلب یادگیری ماشین مدرن و کتابخانههای یادگیری عمیق است tensorflow
، pytorch
و jax
. PyTorch torch.autograd
ماژول روش هایی را برای اجرای autodiff روی تانسورهای PyTorch ارائه می دهد که برای آموزش شبکه های عصبی به منظور به حداقل رساندن افت پیش بینی (خطا) و بهبود دقت خروجی ها استفاده می شود.
برای توضیح بصری تمایز خودکار، بررسی کنید: https://www.youtube.com/watch?v=wG_nF1awSSY&t=2s
برای پیاده سازی تمایز خودکار خودتان، این آموزش ساخت را بررسی کنید micrograd
، یک موتور کوچک خودکار، توسط آندری کارپاتی باهوش، مقدمه املای شبکه های عصبی و انتشار پس زمینه: ساخت میکروگراد. این آموزش همچنین به عنوان یک مقدمه عملی عالی برای دنیای مدرن ماشینی/یادگیری عمیق و چارچوب های درگیر مانند tensorflow
و pytorch
زیرا شما اساساً نسخه کوچکتری از آنها می سازید.
JAX چیست؟
jax
یک کتابخانه یادگیری ماشینی و محاسبات علمی با کارایی بالا برای جبر چند خطی، تمایز خودکار، و برای نوشتن کد عددی عملکردی است که میتواند روی CPUها و همچنین شتابدهندههایی مانند GPU و TPU برای افزایش سرعت سودآور اجرا شود.
به طور خلاصه، jax
است numpy
با پشتیبانی از autodiff (تمایز خودکار). این را می گویم چون jax
's API مطابقت 1-1 با numpy دارد که باعث می شود jax
جایگزینی برای numpy
.
در مقایسه با سایر کتابخانه های یادگیری ماشینی مانند tensorflow
و pytorch
که تقریباً با همه چیزهایی که برای انجام یادگیری ماشینی در هر مقیاسی نیاز دارید، همراه است، jax
با طراحی لاغرتر و ساده تر، که با اندازه کوچکتر نشان داده می شود، فلسفه “ساده زیباست” را می پذیرد (jax
9 مگابایت است در حالی که کتابخانه های دیگر دوست دارند pytorch
و tensorflow
هنگام نصب با پشتیبانی CUDA از 1 گیگابایت فراتر رود). jax
می تواند بیشتر توسط کتابخانه هایی مانند flox
و equinox
برای تقویت قابلیت های خود برای انجام کارهایی مانند ساخت و آموزش شبکه های عصبی، قرار دادن اسماً آن با کتابخانه های بزرگتر مانند tensorflow
و pytorch
.
این چه ربطی به نسبیت عام دارد؟
اولا، GR به زبان تانسورها و جبر چند خطی فرموله شده است. تانسور یک آرایه چند بعدی از اعداد است که به عنوان تعمیم بردارها و ماتریس ها به ابعاد بالاتر عمل می کند. مانند بردارها و ماتریسها، میتوانیم حساب دیفرانسیل و انتگرال را روی تانسورها انجام دهیم، که بخش بزرگی از محاسباتی است که در GR انجام میدهیم (محاسبات نمادهای کریستوفل و غیره).
تانسورها همچنین زبان شبکه های عصبی و یادگیری عمیق هستند. دادههای ورودی و خروجی، و پارامترهایی مانند وزنها و بایاسهای شبکه عصبی، بهعنوان تانسور ذخیره میشوند تا در هنگام نمایش دادهها با اشکال و اندازههای مختلف، انعطافپذیری ایجاد شود. همچنین برای آموزش شبکه های عصبی باید بتوانیم مشتقات تانسورها را محاسبه کرده و بر روی آنها محاسبات انجام دهیم. همانطور که ممکن است جمع آوری شود، این بدان معنی است که یک تقاطع طبیعی بین GR و یادگیری عمیق در مورد زبانی که آنها برای نمایش و دستکاری داده ها استفاده می کنند وجود دارد. البته، تفاوتهای مفهومی فراوانی وجود دارد که هنگام تلاش برای درک این همافزایی باید در نظر داشت. به عنوان مثال، ریاضیات نسبیت عام (و حساب تانسوری به طور کلی) یک کمیت نمایه شده را به عنوان یک تانسور بر اساس ویژگی های تبدیل آن تعریف می کند، در حالی که هر کمیت نمایه شده (مثلاً نمادهای کریستوفل) به عنوان یک تانسور در یادگیری عمیق واجد شرایط است. با این حال، چنین جزئیاتی نکات فنی هستند که با اعمال نظارت کافی می توان آنها را در نظر داشت و در نظر گرفت.
پیشرفت های سریع در زمینه هوش مصنوعی در چند دهه گذشته منجر به ایجاد روش ها و ابزارهای کارآمد و دقیق برای جبر تانسور و حساب دیفرانسیل و انتگرال شده است. تفکیک خودکار و jax
تنها برخی از این روش ها و ابزارهای بسیار هستند، اما به دلیل کاربردهای بالقوه آنها در زمینه فیزیک، برجسته هستند. با این حال، من متوجه شدهام که استفاده از این ابزارها و روشهایی که برای AI/ML برای حل مشکلات محاسباتی و بهبود محاسبات انجامشده در فیزیک مدرن ساخته و اصلاح شدهاند، وجود ندارد. من تا حدودی این را به ماهیت بدیع خود ابزارها نسبت میدهم، و مطمئن هستم که با توجه به زمان و تلاش کافی، پذیرش گستردهای از آنها در بسیاری از زیرشاخههای مختلف فیزیک وجود خواهد داشت.
در واقع، چنین پذیرشی قبلاً با کاربردهای یافتن تمایز خودکار در دینامیک سیالات و حل معادلات دیفرانسیل آغاز شده است. با این حال، از جستجوی من در interweb و arxiv، حوزه نسبیت عام، و به طور خاص نسبیت عددی، که با محاسبه عددی مقادیر و حل معادلات نظریه نسبیت عام اینشتین سروکار دارد، چنین پذیرشی نداشته است، که من معتقدم. زمان تغییر است
ما چه کار می کنیم؟
در این تمرین استفاده خواهم کرد jax
برای نشان دادن قدرت autodiff با کاوش پتانسیل و کاربرد آن در زمینه نسبیت عددی.
با توجه به یک متریک و برخی مختصات، نحوه محاسبه مشتقات تانسور متریک (نمادهای کریستوفل) و سایر تانسورها و کمیت های مرتبط، مانند تانسورهای ریمان و ریچی، انحنای اسکالر ریچی و ثابت کرچمان را بررسی خواهیم کرد تا در نهایت تانسور اینشتین و تانسور تنش-انرژی- تکانه را محاسبه کنید.
ما از ویژگی های مدرن پایتون مانند تایپ اشاره، که در نسخه های اخیر پایتون (3.11، 3.12، …) معرفی شد و به ما اجازه می دهد تا به صراحت انواع داده های متغیرهایی را که در کد خود استفاده می کنیم مشخص کنیم تا خوانایی بهتر و ایمنی تایپ را فعال کنیم، و دکوراتورهاکه توابع مرتبه بالاتری هستند که رفتار توابع داده شده به آنها را به عنوان ورودی تغییر می دهند/افزایش می دهند تا ورودی/خروجی توابع را برای یک هدف خاص تغییر دهند.
توجه: برای سهولت در تفسیر محاسبات هنگام استخراج مقادیر عددی مقادیر، ما منحصراً در واحدهای SI کار خواهیم کرد و نه واحدهای طبیعی.
راه اندازی
ما با وارد کردن وابستگی ها از کتابخانه تایپ برای پشتیبانی از نوع اشاره و وارد کردن شروع می کنیم jax
+ نوع ناقص آن jax.numpy
.
ما پیکربندی می کنیم jax
برای اینکه تمام اعداد ممیز شناور را مجبور کنیم تا با دقت 64 بیتی برای دقت بالاتر در نتایج ما باشند.
ما همچنین یک تابع دکوراتور کاربردی را تعریف می کنیم close_to_zero
برای کمک به گرد کردن مقادیر نزدیک به صفر و زیر یک تلورانس دلخواه انتخاب شده در تانسورهای ما به منظور کاهش خطاهای ممیز شناور ناشی از مسائل مربوط به دقت عددی ترکیبی در مراحل محاسبه حسابی میانی.
from typing import Callable
import jax
import jax.numpy as jnp
jax.config.update("jax_enable_x64", True)
TOLERANCE = 1e-8
def close_to_zero(func):
def wrapper(*args, **kwargs) -> jnp.ndarray:
result: jnp.ndarray = func(*args, **kwargs)
return jnp.where(jnp.abs(result) < TOLERANCE, 0.0, result)
return wrapper
تعریف معیارهای رایج
ما برخی از معیارهای رایج را تعریف می کنیم که به عنوان نمونه های بی اهمیت برای بقیه آموزش استفاده می شوند.
# while the minkowski metric is a constant tensor that is not coordinate dependent,
# we still need to take in some "dummy" coordinates in order to make this function play nice with JAX's autodiff mechanism
def minkowski_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
"""Returns the Minkowski metric in float64 precision with the (-1, 1, 1, 1) metric signature"""
return jnp.diag(jnp.array([-1, 1, 1, 1], dtype=jnp.float64))
# this is the standard metric for a 2-sphere.
@close_to_zero
def spherical_polar_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
r, theta, phi = coordinates
return jnp.diag(jnp.array([1, r**2, r**2 * jnp.sin(theta)**2], dtype=jnp.float64))
نمادهای کریستوفل
با توجه به یک متریک
نمادهای کریستوفل از نوع دوم (که اتصال افین یا ضرایب اتصال نیز نامیده می شود) به عنوان مشتقاتی از متریک منقبض شده با تانسور متریک معکوس تعریف می شوند.
:
نکته: این تعریف و تعریف های بعدی از آن گرفته شده است روش های ریاضی برای دانشجویان رشته فیزیک و رشته های مرتبط توسط صدری حسنی و از تمام شاخص های رومی استفاده می کند. ما همین کار را انجام خواهیم داد و از تمام شاخصهای رومی در طول این آموزش استفاده خواهیم کرد، حتی زمانی که با کمیتهای فضازمان سروکار داریم و نه فقط کمیتهای دکارتی، به دلیل سهولت آنها هنگام مشخص کردن آنها در کد. نمادهای یونانی در مورد نمایش یونیکد زیربنایی آنها بی اهمیت هستند، و این پیچیدگی است که فعلاً می خواهم از آن اجتناب کنم.
نمادهای کریستوفل نشان دهنده میدان گرانشی در یک فضازمان معین هستند، که مشتقاتی از متریک هستند که مشابه پتانسیل گرانشی در گرانش نیوتنی هستند.
اکنون یک تابع پایتون برای محاسبه نمادهای کریستوفل تعریف می کنیم. تابع در coordinates
برای محاسبه نمادهای کریستوفل در، و metric
تابع برای محاسبه نمادهای کریستوفل، و اجرای آن به طور کلی به شرح زیر است:
-
ما تابع متریک را ارزیابی می کنیم تا متریک را در داده شده بدست آوریم
coordinates
و با استفاده از تانسور متریک معکوس در طول مسیر محاسبه کنیدjnp.linalg.inv
. -
استفاده می کنیم
jax.jacfwd
برای محاسبه “ژاکوبین” متریک، یعنی مشتقات جزئی آن با توجه به مختصات داده شده، با استفاده از تمایز خودکار رو به جلو. این است
، همچنین به عنوان نشان داده شده است
. من “ژاکوبین” را در نقل قول می نویسم زیرا به طور دقیق، ژاکوبین به عنوان ماتریس مشتقات جزئی یک تابع با مقدار برداری با توجه به ورودی های آن تعریف می شود، اما آنچه ما داریم یک تابع با مقدار تانسور به شکل متریک است. . من از هیچ کمیت ریاضی که برای توصیف تانسور با رتبه بالاتر مرتبط با مشتقات یک تابع با مقدار تانسور استفاده می شود، آگاه نیستم، از این رو در اینجا از کلمه “ژاکوبین” بی استفاده استفاده می کنم.
-
استفاده می کنیم
jnp.einsum
، یک زیربرنامه بسیار راحت و عملکردی که تانسورهای محاسباتی و سایر اشیاء نمایه شده را با استفاده از نماد شاخص استاندارد دستکاری می کند تا نمادهای کریستوفل را مطابق معادله بالا محاسبه کند.
@close_to_zero # this ensures that any values of our Christoffel symbols are rounded off if they're close to 0
def christoffel_symbols(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
# evaluate the metric tensor at the coordinates
g = metric(coordinates)
# compute the inverse metric tensor
g_inv = jnp.linalg.inv(g)
# obtain and evaluate the "jacobian" of the metric tensor at the coordinates
jacobian = jax.jacfwd(metric)(coordinates) # this is kl;m
return 0.5 * jnp.einsum('jm, klm -> jkl', g_inv, jnp.einsum('klm -> mkl', jacobian) + jnp.einsum('klm -> lmk', jacobian) - jacobian)
تانسور پیچشی
تانسور پیچشی به عنوان قسمت ضد متقارن یک اتصال افین عمومی تعریف می شود
:
اگر تانسور پیچشی در یک سیستم مختصات ناپدید شود، در تمام سیستم های مختصات ناپدید می شود (تانسور صفر در همه سیستم های مختصات صفر است). بنابراین، تانسور پیچشی یک اتصال افین کلی صفر است اگر و فقط اگر اتصال متقارن باشد، به عنوان مثال،
از آنجایی که ما فقط با نمادهای کریستوفل از نوع دوم سروکار داریم که یک و منحصر به فرد است متقارن اتصال affine مشتق شده از تانسور متریک، تمام تانسورهای پیچشی که در این کاوش محاسبه خواهیم کرد باید صفر باشند، و زیربرنامه زیر برای تأیید آن استفاده خواهد شد.
@close_to_zero
def torsion_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
christoffels = christoffel_symbols(coordinates, metric)
return christoffels - jnp.einsum('ijk -> ikj', christoffels)
تانسور انحنای ریمان و تغییر ناپذیر کرچمان
تانسور ریمان
انحنای ذاتی منیفولد ریمانی (یا نیمه ریمانی) تولید شده توسط هر متریک معین را رمزگذاری می کند. این به عنوان مشتقات نمادهای کریستوفل تعریف می شود
به عنوان:
ما یک تابع پایتون تعریف می کنیم که:
- از قبلی استفاده می کند
christoffel_symbols
تابع برای به دست آوردن نمادهای کریستوفل برای یک مجموعه معین از متریک و مختصات. - “ژاکوبین” نمادهای کریستوفل را محاسبه می کند تا به دست آید
.
- این تانسور “ژاکوبین” و محصولات نمادهای کریستوفل را با استفاده از دستکاری می کند
jnp.einsum
برای به دست آوردن تانسور ریمان
ما همچنین یک تابع پایتون را برای محاسبه ثابت کرچمان از تانسور ریمان تعریف می کنیم، یک اسکالر که برای جستجو استفاده می شود. درست است تکینگی های فیزیکی (تکینگی های گرانشی) در منیفولدهای خاص مستقل از انتخاب مختصات:
ما بعداً در این آموزش از ثابت کرچمن استفاده خواهیم کرد تا بررسی کنیم که آیا اجرای تانسور ریمان که در زیر داریم درست است یا نه هنگام استفاده از متریک شوارتزچیلد به عنوان مطالعه موردی برای تأیید صحت این زیر روالها.
@close_to_zero
def riemann_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
christoffels = christoffel_symbols(coordinates, metric)
jacobian = jax.jacfwd(christoffel_symbols)(coordinates, metric) # computes jkl;m
return jacobian - jnp.einsum('jklm -> jkml', jacobian) + jnp.einsum('jrm, rkl -> jklm', christoffels, christoffels) - jnp.einsum('jrl, rkm -> jklm', christoffels, christoffels)
@close_to_zero
def kretschmann_invariant(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
riemann = riemann_tensor(coordinates, metric)
g = metric(coordinates)
g_inv = jnp.linalg.inv(g)
riemann_upper = jnp.einsum('pj, qk, rl, ijkl -> ipqr', g_inv, g_inv, g_inv, riemann) # computes R^{jklm} by contracting with three inverse metric tensors
riemann_lower = jnp.einsum('pi, ijkl -> pjkl', g, riemann) # computes R_{jklm} by contracting with one metric tensor
return jnp.einsum('ijkl, ijkl ->', riemann_upper, riemann_lower)
تانسور ریچی و انحنای اسکالر ریچی
تانسور ریچی
کمیت دیگر مربوط به انحنا است که به عنوان جزء ردیابی تانسور ریمان تعریف می شود.
. تانسور ریچی با انقباض تنها شاخص متضاد تانسور ریمان با آخرین شاخص کوواریانت آن به دست میآید:
از نظر فیزیکی، تانسور ریچی اطلاعاتی در مورد چگونگی تغییر حجم ها در حضور نیروهای جزر و مدی رمزگذاری می کند.
با بالا بردن یکی از شاخص های تانسور ریچی و انقباض، انحنای اسکالر ریچی را به دست می آوریم.
ما زیر روال های پایتون را برای انجام محاسباتی با استفاده از آن پیاده سازی می کنیم jnp.einsum
دوباره برای دستکاری شاخص ها و انجام انقباضات.
@close_to_zero
def ricci_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
riemann = riemann_tensor(coordinates, metric)
return jnp.einsum('jklj -> kl', riemann) # contracting the first and last indices
@close_to_zero
def ricci_scalar(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.float32:
g = metric(coordinates)
g_inv = jnp.linalg.inv(g)
ricci = ricci_tensor(coordinates, metric)
return jnp.einsum('kl, kl -> ', g_inv, ricci) # trace of the ricci tensor
تانسور اینشتین و تانسور تنش-انرژی- تکانه
تانسور اینشتین، جواهر تاج نظریه نسبیت عام، تمام اطلاعات مربوط به انحنای یک منیفولد فضازمان را رمزگذاری می کند و بر اساس تانسور ریچی، تانسور متریک و انحنای اسکالر ریچی به صورت زیر تعریف می شود:
سمت چپ معادلات میدان انیشتین (EFEs) را تشکیل میدهد، مجموعهای از 16 معادله دیفرانسیل جزئی جفت شده که انحنای یک منیفولد فضازمان را به محتوای جرم-انرژی موجود در آن مرتبط میکند:
سمت راست
تانسور تنش-انرژی-تکانه است که اطلاعات مربوط به تمام جرم-انرژی موجود در منیفولد فضا-زمان را رمزگذاری می کند.
توابع پایتون را مینویسیم تا زیرروالهای اجرا شده قبلی را فراخوانی کنیم تا تانسور انیشتین و تانسور تنش-انرژی- تکانه را با استفاده از معادلاتی که قبلاً توضیح دادیم محاسبه کنیم.
@close_to_zero
def einstein_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
g = metric(coordinates)
rt = ricci_tensor(coordinates, metric)
rs = ricci_scalar(coordinates, metric)
return rt - 0.5 * g * rs
@close_to_zero
def stress_energy_momentum_tensor(coordinates: jnp.ndarray, metric: Callable[[jnp.ndarray], jnp.ndarray]) -> jnp.ndarray:
G = einstein_tensor(coordinates, metric)
kappa = (8 * jnp.pi * 6.67e-11) / ((299792458)**4)
return G / kappa
مطالعه موردی 1: متریک 2 کره
با استفاده از تمام توابع پایتون که قبلا تعریف کرده ایم، بیایید محاسبات را در آن انجام دهیم float64
دقت برای متریک 2 کره در مختصات قطبی کروی
به عنوان:
ما از مقادیر مختصات زیر برای محاسبات استفاده می کنیم که به صورت دلخواه انتخاب شده اند
coordinates = jnp.array([5, jnp.pi/3, jnp.pi/2], dtype=jnp.float64)
metric = spherical_polar_metric
print(f"Christoffel symbols: {christoffel_symbols(coordinates, metric)}")
print(f"Torsion tensor: {torsion_tensor(coordinates, metric)}")
print(f"Riemann tensor: {riemann_tensor(coordinates, metric)}")
print(f"Ricci tensor: {ricci_tensor(coordinates, metric)}")
print(f"Ricci scalar: {ricci_scalar(coordinates, metric)}")
print(f"Einstein tensor: {einstein_tensor(coordinates, metric)}")
print(f"Stress-energy-momentum tensor: {stress_energy_momentum_tensor(coordinates, metric)}")
print(f"Kretschmann invariant: {kretschmann_invariant(coordinates, metric)}")
با اجرای این، دریافت می کنیم
Christoffel symbols: [[[ 0. 0. 0. ]
[ 0. -5. 0. ]
[ 0. 0. -3.75 ]]
[[ 0. 0.2 0. ]
[ 0.2 0. 0. ]
[ 0. 0. -0.4330127 ]]
[[ 0. 0. 0.2 ]
[ 0. 0. 0.57735027]
[ 0.2 0.57735027 0. ]]]
Torsion tensor: [[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]
Riemann tensor: [[[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]
[[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]
[[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]]]
Ricci tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Ricci scalar: 0.0
Einstein tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Stress-energy-momentum tensor: [[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Kretschmann invariant: 0.0
ما تمام نمادهای کریستوفل را برای این متریک به دست می آوریم. علاوه بر این، همانطور که انتظار میرفت، تانسور ریمان، تانسور ریچی، اسکالر ریچی، تانسور انیشتین و تانسور تنش-انرژی-تکانه همگی ناپدید میشوند زیرا این متریک فضازمان مسطح را بدون انحنا و محتوای جرم-انرژی توصیف میکند. تانسور پیچشی نیز همانطور که از ماهیت متقارن نمادهای کریستوفل انتظار می رود صفر است.
مطالعه موردی 2: متریک شوارتزشیلد
اکنون به یک مطالعه موردی جالبتر میرسیم، متریک شوارتزشیلد، که فضازمان یک جسم متقارن بدون بار، غیرچرخش و کروی در خلاء را توصیف میکند. متریک شوارتزشیلد در مختصات فضای زمان قطبی کروی سنتی
به صورت زیر داده می شود:
کجا
شعاع شوارتزشیلد جسم عظیم است، ضریب مقیاسی که با جرم آن مرتبط است
توسط:
ما دقیقاً مانند مطالعه موردی قبلی انجام میدهیم و همه مقادیر را محاسبه میکنیم float64
دقت برای جسمی با جرم 4.3 میلیون خورشیدی با استفاده از مختصات قطبی کروی فضازمان انتخاب شده زیر
G = 6.67e-11
c = 299792458.0
M = 4.297e+6 * 1.989e+30 # 4.3 million solar masses, mass of Sgr A*
# schwarzschild radius
rs = (2 * G * M) / c**2
@close_to_zero
def schwarzschild_metric(coordinates: jnp.ndarray) -> jnp.ndarray:
t, r, theta, phi = coordinates
return jnp.diag(jnp.array([-(1 - (rs / r)) * c**2, 1/(1 - (rs/r)), r**2, r**2 * jnp.sin(theta)**2], dtype=jnp.float64))
coordinates = jnp.array([3600, 3000, jnp.pi/3, jnp.pi/2], dtype=jnp.float64)
metric = schwarzschild_metric
print(f"Christoffel symbols: {christoffel_symbols(coordinates, metric)}")
print(f"Torsion tensor: {torsion_tensor(coordinates, metric)}")
print(f"Riemann tensor: {riemann_tensor(coordinates, metric)}")
print(f"Ricci tensor: {ricci_tensor(coordinates, metric)}")
print(f"Ricci scalar: {ricci_scalar(coordinates, metric)}")
print(f"Einstein tensor: {einstein_tensor(coordinates, metric)}")
print(f"Stress-energy-momentum tensor: {stress_energy_momentum_tensor(coordinates, metric)}")
print(f"Kretschmann invariant: {kretschmann_invariant(coordinates, metric)}")
اجرای این خروجی ها
Christoffel symbols: [[[ 0.00000000e+00 -1.66666706e-04 0.00000000e+00 0.00000000e+00]
[-1.66666706e-04 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[-2.67840757e+26 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 1.66666706e-04 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 1.26857006e+10 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 9.51427546e+09]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 3.33333333e-04 0.00000000e+00]
[ 0.00000000e+00 3.33333333e-04 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -4.33012702e-01]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 3.33333333e-04]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.77350269e-01]
[ 0.00000000e+00 3.33333333e-04 5.77350269e-01 0.00000000e+00]]]
Torsion tensor: [[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]]
Riemann tensor: [[[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 1.11111137e-07 0.00000000e+00 0.00000000e+00]
[-1.11111137e-07 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 2.11428394e+06 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[-2.11428394e+06 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.58571295e+06]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[-1.58571295e+06 0.00000000e+00 0.00000000e+00 0.00000000e+00]]]
[[[ 0.00000000e+00 1.78560505e+23 0.00000000e+00 0.00000000e+00]
[-1.78560505e+23 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 2.11428394e+06 0.00000000e+00]
[ 0.00000000e+00 -2.11428394e+06 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.58571295e+06]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -1.90734863e-06]
[ 0.00000000e+00 -1.58571295e+06 1.90734863e-06 0.00000000e+00]]]
[[[ 0.00000000e+00 0.00000000e+00 -8.92802525e+22 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 8.92802525e+22 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 5.55555687e-08 0.00000000e+00]
[ 0.00000000e+00 -5.55555687e-08 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -3.17142590e+06]
[ 0.00000000e+00 0.00000000e+00 3.17142590e+06 0.00000000e+00]]]
[[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 -8.92802525e+22]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 8.92802525e+22 0.00000000e+00 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 5.55555687e-08]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 -5.55555687e-08 0.00000000e+00 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 4.22856787e+06]
[ 0.00000000e+00 0.00000000e+00 -4.22856787e+06 0.00000000e+00]]
[[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00]]]]
Ricci tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Ricci scalar: 0.0
Einstein tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Stress-energy-momentum tensor: [[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Kretschmann invariant: 2.649005370647907
مانند قبل، نمادهای کریستوفل خود را برای متریک شوارتزشیلد به دست آوردهایم و تانسور پیچشی همانطور که انتظار میرفت صفر است.
علاوه بر این، از آنجایی که متریک شوارتزشیلد یک راه حل خلاء برای معادلات میدان انیشتین است، تانسور ریچی، اسکالر ریچی، تانسور اینشتین و تانسور تنش-انرژی- تکانه همگی صفر هستند.
با این حال، توجه کنید که تانسور ریمان صفر نیست. در واقع، برخی از اجزای آن از نظر قدر بسیار بزرگ هستند. ما همچنین مقداری برای ثابت کرچمن از انقباض تانسور ریمان بدست می آوریم. برای تأیید این موضوع و در نتیجه تأیید اینکه آیا اجزای تانسور ریمان محاسبه شده ما صحیح هستند یا نه، میتوانیم ثابت کریچمن را مستقیماً با استفاده از یک فرمول اسکالر نسبتاً بیاهمیت محاسبه کنیم:
G = 6.67e-11
M = 4.297e+6 * 1.989e+30 # 4.3 million solar masses, mass of Sgr A*
c = 299792458.0
r = 3000
kr = (48 * G**2 * M**2) / (c**4 * r**6)
print("Kretschmann invariant is", kr)
با اجرای این، خروجی را دریافت می کنیم
Kretschmann invariant is 2.649005370647906
که با نتیجه ای که با انقباض همه شاخص های تانسور ریمان تا 15 رقم اعشار به دست آوردیم مطابقت دارد!
در این کاوش، قدرت تمایز خودکار را در محاسبات مشتق از همه کمیت ها تا حداکثر دقت ماشین از نظر دقت ممیز شناور، شاهد بودیم.
ما اثربخشی و سادگی JAX را دیدیم jax.jacfwd
برای محاسبه ژاکوبین ها/مشتقات تانسورها در تمایز خودکار حالت رو به جلو.
ما همچنین مزایای JAX را دیده ایم jnp.einsum
با توانایی آن در انجام دستکاری شاخص و انجام محاسبات در سطح بالا، به فرد اجازه می دهد تا عملیات حساب تانسور را به شیوه ای راحت و کارآمد انجام دهد. زبان تانسورها و حساب تانسوری در سایر موضوعات و زمینه های فیزیک نظری مانند الکترومغناطیس کوواریانت و نظریه میدان کوانتومی فراگیر است. دست کم، کشف یک رویکرد مشابه با استفاده از کتابخانهها و چارچوبهای مدرن AI/ML به منظور انجام محاسبات تانسور برای محاسبات ناشی از این زمینهها، تمرین جالبی خواهد بود.
قابلیتهای JAX به ما این امکان را میدهد که همه این کدها را موازی کنیم و آن را بر روی شتابدهندههایی مانند GPU و TPU بدون هیچ تغییری در کد اصلی اجرا کنیم تا محاسبات برای محاسبات عددی سنگین و شبیهسازیهایی که نیاز به موازیسازی، سرعت و کارایی دارند، سرعت ببخشیم. ما آن جنبه را به طور خاص در این نمایش بررسی نکردهایم، و همه محاسبات روی CPU انجام شدهاند، زیرا هیچ یک از محاسبات یا موارد استفاده به استفاده از موازیسازی و شتابدهندهها نیاز ندارد، اما با این وجود، این قابلیتها وجود دارد و میتوان در صورت استفاده خاص از آن استفاده کرد. آن را می طلبد.
توضیحات، اسکریپت ها و نتایج این کاوش نیز به راحتی در این دفترچه یادداشت Jupyter که در Google Colab میزبانی شده است، مستند شده است، که می توانید از آن برای بازتولید و ایجاد ایده های ارائه شده در اینجا استفاده کنید.
کار آینده
برخی از ایده ها و برنامه های کاربردی در این جهت کلی که ارزش بررسی دارند:
- همین محاسبات را برای سایر معیارهای برجسته مانند معیارهای Kerr و Kerr-Newmann انجام دهید.
- توابعی را برای محاسبه تانسور ویل و متغیر ویل، دیگر کمیت های مهم مرتبط با انحنا بنویسید.
- در اینجا پیاده سازی های جایگزین اما معادل PyTorch و Tensorflow را برای پیاده سازی JAX ارائه دهید.
- استفاده کنید
@jax.jit
دکوراتور در زیر روال های مربوطه برای استفاده از کامپایل JIT به منظور سرعت بخشیدن به محاسبات. - نگاه کنید
jax.jacrev
برای تمایز خودکار حالت معکوس و سعی کنید آن را با آن ترکیب کنیدjax.jacfwd
برای سرعت و دقت بهینه - این کد را طوری پیکربندی کنید که روی GPU ها و سایر شتاب دهنده ها اجرا شود.
- آموزش یک شبکه عصبی برای پارامترسازی تانسور متریک و حل یک مسئله بهینه سازی به منظور یافتن اجزای تانسور متریک از داده ها.
- نمادهای کریستوفل را برای یک متریک محاسبه کنید و معادله ژئودزیکی را حل کنید تا EOM را با استفاده از حلکنندههای معادلات دیفرانسیل قدرت تفکیک خودکار، مانند
diffrax
- این روش شناسی را به جنبه ها و محاسبات دیگر نسبیت عددی گسترش دهید، به ویژه آنهایی که توسط کتابخانه های پایتون نسبیت عام رایج مانند
EinsteinPy