{"id":17646820,"url":"https://github.com/sbozzolo/array","last_synced_at":"2026-02-11T12:01:26.783Z","repository":{"id":144541994,"uuid":"573666055","full_name":"Sbozzolo/arRay","owner":"Sbozzolo","description":"A General-Relativistic Ray-Tracing code in Dyalog APL","archived":false,"fork":false,"pushed_at":"2022-12-03T23:44:03.000Z","size":74,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-12T00:19:04.523Z","etag":null,"topics":["apl","array-methods","black-holes","dyalog-apl","general-relativity","ray-tracing","schwarzschild"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sbozzolo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-03T03:16:53.000Z","updated_at":"2023-08-31T05:12:02.000Z","dependencies_parsed_at":"2023-07-14T13:31:02.927Z","dependency_job_id":null,"html_url":"https://github.com/Sbozzolo/arRay","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Sbozzolo/arRay","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sbozzolo%2FarRay","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sbozzolo%2FarRay/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sbozzolo%2FarRay/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sbozzolo%2FarRay/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sbozzolo","download_url":"https://codeload.github.com/Sbozzolo/arRay/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sbozzolo%2FarRay/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29332711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T06:13:03.264Z","status":"ssl_error","status_checked_at":"2026-02-11T06:12:55.843Z","response_time":97,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apl","array-methods","black-holes","dyalog-apl","general-relativity","ray-tracing","schwarzschild"],"created_at":"2024-10-23T11:07:59.551Z","updated_at":"2026-02-11T12:01:26.749Z","avatar_url":"https://github.com/Sbozzolo.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/Sbozzolo/arRay/raw/main/logo.png\" height=\"120\"\u003e\n\u003c/p\u003e\n\n`arRay` will be a General-Relativistic Ray-Tracing code in Dyalog APL.\n\n## Why?\n\n[APL](https://en.wikipedia.org/wiki/APL_(programming_language)) (A Programming\nLanguage) is an array programming language. This is a completely different (and\nfor the most part obscure) paradigm compared to most other languages out there.\nAPL shines in producing terse and efficient code when used for manipulations of\nmatrices. I think that problem of General-Relativistic Ray-Tracing can be cast\nin these terms, so I wanted to see what it could come out.\n\nNote: I started learning APL last in December 2022, so this code will likely be\nterrible.\n\n## General-Relativistic Ray-Tracing\n\nAccording to General Relativity, light does not travel on straight lines and its\nmotion is influenced by massive bodies (such as [our\nSun](https://en.wikipedia.org/wiki/Solar_eclipse_of_May_29,_1919)). Light rays\ntravel on __null geodesics__, which are special curves in spacetime.\nGeneral-relativistic ray-tracing consists in finding such curves given the\ninitial position of the camera.\n\n#### In equations\n\nLet $x^\\mu(\\lambda)$ be the four-position of a photon with $\\lambda$ affine\nparameter. We define its momentum as\n\n$$ k^\\mu = \\frac{d x^\\mu}{d \\lambda}.$$\n\n$k^\\mu$ is also function of $\\lambda$. Given that we are describing a null\ngeodesic, $k^\\mu$ has to be null, so $k^\\mu k_\\mu = 0$. Performing ray-tracing\nmeans solving the geodesic equation:\n\n$$ \\frac{d k^\\mu}{d \\lambda} = -\\Gamma^\\mu_{\\alpha\\beta} k^\\alpha k^\\beta . $$\n\n$\\Gamma^\\mu_{\\alpha\\beta}$ are the Christoffel symbols and depend on the\nspacetime and the four-position in the spacetime. The geodesic equation is a set\nof ordinary differential equations (ODEs) in $\\lambda$, which have to be coupled\nwith the definition of the four-momentum to find the position of the photon. So,\nwe have to solve eight ODEs (four of which are trivial). We represent each\nphoton with a 8-element vector, where the first four element is $x^\\mu$, and the\nlast 4 are $k^\\mu$. Then, starting from some initial data on our camera, we\nsolve the ODEs until we reach the black hole or some outer domain.\n\n#### Initial data\n\nFirst, we need to generate the initial data. Our initial data will consist of a\ngrid of photons initially on our camera. Then, we integrate the photons backward\nin time towards the black hole. Each photon is described by the 8-element state\nthat contains its four-position and four-momentum.\n\nFor the initial data, we need to specify five parameters: `d`, the distance from\nthe black hole, `i` and `j`, the inclination and azimuthal angle of the camera,\n`N` and `F` are the number of pixels and the field-of-view (we assume a square\ncamera). From these variables, we define a Cartesian coordinate system $(\\alpha,\n\\beta)$ onto the camera.\n\nFor a given $(\\alpha, \\beta)$, the initial four-position will be\n\n\n#### Evolution\n\nIn this first implementation, we solve the ODEs with a forward Euler's method,\nwhich is the simplest way to solve an ODE. With this method, we move from the\n$i$-th step $x^\\mu(\\lambda_i), k^\\mu(\\lambda_i)$ at $\\lambda = \\lambda_i$ to the\nfollowing at $\\lambda_{i+1} = \\lambda + \\Delta \\lambda$ with\n\n$$ x^\\mu(\\lambda_{i + 1}) = x^\\mu(\\lambda_{i}) + \\Delta \\lambda k^\\mu(\\lambda_{i}), $$\n\n$$ k^\\mu(\\lambda_{i + 1}) = k^\\mu(\\lambda_{i}) -\\Delta \\lambda \\Gamma^\\mu_{\\alpha\\beta}(\\lambda_{i}) k^\\alpha(\\lambda_{i}) k^\\beta(\\lambda_{i}). $$\n\nIn this, we defined $ \\Gamma^\\mu_{\\alpha\\beta}(\\lambda_{i}) =  \\Gamma^\\mu_{\\alpha\\beta}(x^\\mu(\\lambda_{i})) $.\n\n#### Stopping criterion\n\nFor each photon, we set two termination conditions: either the photon gets very\nclose to the horizon, or it goes too far. So, we define two parameters that\ncontrol whether to continue the integration or not depending on the spatial\nposition of the photon with respect to the horizon.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbozzolo%2Farray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsbozzolo%2Farray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbozzolo%2Farray/lists"}