{"id":18501569,"url":"https://github.com/const-ae/diffgeo","last_synced_at":"2025-10-06T00:57:08.339Z","repository":{"id":82391791,"uuid":"602155311","full_name":"const-ae/diffgeo","owner":"const-ae","description":"Working with manifolds in R","archived":false,"fork":false,"pushed_at":"2023-02-16T09:16:33.000Z","size":144,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-10T05:34:14.139Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/const-ae.png","metadata":{"files":{"readme":"README.Rmd","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":"2023-02-15T16:00:53.000Z","updated_at":"2023-02-15T16:01:21.000Z","dependencies_parsed_at":"2023-04-19T23:32:01.088Z","dependency_job_id":null,"html_url":"https://github.com/const-ae/diffgeo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/const-ae/diffgeo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Fdiffgeo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Fdiffgeo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Fdiffgeo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Fdiffgeo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/const-ae","download_url":"https://codeload.github.com/const-ae/diffgeo/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/const-ae%2Fdiffgeo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278542674,"owners_count":26004061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-05T02:00:06.059Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-11-06T13:54:18.408Z","updated_at":"2025-10-06T00:57:08.317Z","avatar_url":"https://github.com/const-ae.png","language":"R","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n\n# diffgeo\n\n\u003c!-- badges: start --\u003e\n\u003c!-- badges: end --\u003e\n\nThe `diffgeo` R package provides functions to work with six common manifolds:\n\n* Euclidean arrays\n* Spheres (in $n$ dimensions)\n* Rotation matrices (also called special orthogonal manifolds $\\text{SO}(n)$)\n* Stiefel manifold (matrices with orthogonal columns)\n* Grassmann manifold (matrices with orthogonal columns but they are only considered different if they span separate spaces)\n* Symmetric positive definite (SPD) matrices (symmetric matrices with positive eigenvalues)\n\n## Installation\n\nYou can install `diffgeo` from [Github](https://github.com/const-ae/diffgeo) with:\n\n``` r\ndevtools::install_github(\"const-ae/diffgeo\")\n```\n\n## Principles\n\nFor each manifold, `diffgeo` provides:\n\n* Random points\n* Random tangents\n* Exponential map (a way to go along the manifold from one point to another)\n* Logarithm (the inverse exponential map, that is a way calculate the direction between points on the manifold)\n\n\n\n## Examples\n\nTo demonstrate the functionality of the package, I will show the functions for the rotation matrices. All functions work analoguously for the other manifolds.\n\n```{r}\nlibrary(diffgeo)\nset.seed(1)\n```\n\n\nTo begin, I create a random rotation matrix in 2D\n\n```{r}\nrotation \u003c- rotation_random_point(2)\n```\n\nWe can visualize it's effect on a random set of points\n```{r rotation_visualization_2d}\npoints \u003c- rbind(rnorm(n = 20), rnorm(20))\nrotated_points \u003c- rotation %*% points\nplot(t(points), pch = 16, col = \"black\", asp = 1, xlim = c(-3, 3), ylim = c(-2, 2))\npoints(t(rotated_points), pch = 16, col = \"red\")\nsegments(points[1,], points[2,], rotated_points[1,], rotated_points[2,])\n```\n\nWe can also create high-dimensional rotations and check the formal conditions for the rotation manifold\n\n```{r}\nrotation2 \u003c- rotation_random_point(5)\n# Determinant is 1\nMatrix::det(rotation2)\n# All columns are orthogonal\nround(t(rotation2) %*% rotation2, 3)\n```\n\nAn important concept in differential geometry are geodesics, i.e. are lines on the manifold. To find the\nline that connects two rotations we use the `rotation_log` function. These directions are from the tangent space\nof the manifold. The tangent space of the rotation manifold is the set of skew-symmetric matrices.\n\n```{r}\nrotation3 \u003c- rotation_random_point(5)\ndirection \u003c- rotation_log(base_point = rotation2, target_point = rotation3)\nround(direction, 3)\n```\n\nWe can also reverse the operation and go from a base-point in the direction of a tangent vector (\"exponential map\"). If we do this \nusing the `direction` we will land exactly at `rotation3` again.\n\n```{r}\nrotation3\nrotation_map(v = direction, base_point = rotation2)\n```\n\nLastly, it is important to understand that the Sphere, the Grassmann, the Stiefel, and the Rotation manifold have a non-infinite injectivity radius. \nThe injectivity radius is furthest we can go along a manifold and still guarantee that $\\log(p, \\exp_p(v))$ returns the original tangent vector $v$. \nThe concept is clearest for a 1-Sphere (aka a circle): if we go further than 180° ($\\pi$ radians), we end up at a point for which there exist a shorter path to\nthe starting point than the original direction.\n\n```{r circle_injectivity_radius}\n# Create a random vector with two elements on a circle\nsp \u003c- sphere_random_point(1)\n# Make a tangent vector with norm 1\ntang \u003c- sphere_random_tangent(sp)\ntang \u003c- tang / sqrt(sum(tang^2))\n\n# Plot different step lengths along the direction and \n# highlight the starting point in red and the point at the injectivity radius in green\nplot(t(do.call(cbind, lapply(seq(0, 2 * pi, l = 31), \\(t) sphere_map(t * tang, sp)))), asp = 1)\npoints(t(sp), col = \"red\")\npoints(t(sphere_map(sphere_injectivity_radius() * tang, sp)), col = \"green\")\n```\n\n# Alternatives\n\nThis package is heavily inspired and builds on the [Manifolds](https://juliamanifolds.github.io/Manifolds.jl/latest/index.html) and [Manopt.jl](https://manoptjl.org/stable/) packages developed by Ronny Bergmann et al.. The Manopt.jl package in turn is inspired by the [Manopt](https://www.manopt.org/) toolbox for Matlab.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconst-ae%2Fdiffgeo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconst-ae%2Fdiffgeo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconst-ae%2Fdiffgeo/lists"}