{"id":34955881,"url":"https://github.com/parsiad/mlinterp","last_synced_at":"2025-12-26T22:02:48.761Z","repository":{"id":62800648,"uuid":"94718006","full_name":"parsiad/mlinterp","owner":"parsiad","description":"Fast arbitrary dimension linear interpolation in C++","archived":false,"fork":false,"pushed_at":"2023-03-10T17:31:45.000Z","size":213,"stargazers_count":79,"open_issues_count":0,"forks_count":29,"subscribers_count":6,"default_branch":"master","last_synced_at":"2023-08-12T18:49:32.033Z","etag":null,"topics":["c-plus-plus","cpp","interpolation","numerical-analysis","numerical-methods"],"latest_commit_sha":null,"homepage":"https://parsiad.ca/mlinterp","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parsiad.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}},"created_at":"2017-06-18T23:04:09.000Z","updated_at":"2023-06-25T17:36:43.000Z","dependencies_parsed_at":"2022-11-06T21:46:43.732Z","dependency_job_id":null,"html_url":"https://github.com/parsiad/mlinterp","commit_stats":null,"previous_names":[],"tags_count":2,"template":null,"template_full_name":null,"purl":"pkg:github/parsiad/mlinterp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiad%2Fmlinterp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiad%2Fmlinterp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiad%2Fmlinterp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiad%2Fmlinterp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parsiad","download_url":"https://codeload.github.com/parsiad/mlinterp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsiad%2Fmlinterp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28062336,"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-12-26T02:00:06.189Z","response_time":55,"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":["c-plus-plus","cpp","interpolation","numerical-analysis","numerical-methods"],"created_at":"2025-12-26T22:02:32.152Z","updated_at":"2025-12-26T22:02:48.756Z","avatar_url":"https://github.com/parsiad.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"mlinterp\" src=\"https://github.com/parsiad/mlinterp/blob/master/logo.png?raw=true\"\u003e\n\u003c/p\u003e\n\n![](https://github.com/parsiad/mlinterp/actions/workflows/build.yml/badge.svg)\n\u003ca href=\"https://github.com/parsiad/mlinterp\"\u003e\u003cimg alt=\"GitHub\" src=\"https://img.shields.io/badge/github-%23121011.svg?logo=github\"\u003e\u003c/a\u003e\n\n**mlinterp** is a fast C++ routine for linear interpolation in arbitrary dimensions (i.e., multilinear interpolation).\n\nmlinterp is written by [Parsiad Azimzadeh](http://parsiad.ca) and released under a permissive MIT License. The latest release can be [downloaded here](https://github.com/parsiad/mlinterp/releases/latest).\n\n## 👷 Including mlinterp in your project\n\n### Method 1: Quick and dirty\n\nmlinterp is a header-only library, meaning that the quickest (albeit dirtiest) way to get started is to copy the file ```mlinterp/mlinterp.hpp``` into your own project directory and include it using ```#include \"mlinterp.hpp\"```.\n\n### Method 2: Git submodule (preferred)\n\nIf you are working on a Git project, adding mlinterp as a submodule is preferred.\nDoing so makes it easy to distribute your code and pick up new versions of mlinterp when they are released.\n\nIf you are unfamiliar with submodules, you can [read about them in the online Git documentation](https://git-scm.com/book/en/v2/Git-Tools-Submodules).\n\n### Method 3: System-wide install\n\nRun the following commands (from the mlinterp project directory) to install it to your system:\n\n```\ncmake .\nsudo make install\n```\n\nYou can now include it using ```#include \u003cmlinterp\u003e```.\n\n## 🧑‍🏫 Examples\n\n### 1d\n\nLet's interpolate y = sin(x) on the interval [-pi, pi] using 15 evenly-spaced data points.\n\n```c++\nusing namespace mlinterp;\n\n// Boundaries of the interval [-pi, pi]\nconstexpr double b = 3.14159265358979323846, a = -b;\n\n// Subdivide the interval [-pi, pi] using 15 evenly-spaced points and\n// evaluate sin(x) at each of those points\nconstexpr int nxd = 15, nd[] = { nxd };\ndouble xd[nxd];\ndouble yd[nxd];\nfor(int n = 0; n \u003c nxd; ++n) {\n\txd[n] = a + (b - a) / (nxd - 1) * n;\n\tyd[n] = sin(xd[n]);\n}\n\n// Subdivide the interval [-pi, pi] using 100 evenly-spaced points\n// (these are the points at which we interpolate)\nconstexpr int ni = 100;\ndouble xi[ni];\nfor(int n = 0; n \u003c ni; ++n) {\n\txi[n] = a + (b - a) / (ni - 1) * n;\n}\n\n// Perform the interpolation\ndouble yi[ni]; // Result is stored in this buffer\ninterp(\n\tnd, ni, // Number of points\n\tyd, yi, // Output axis (y)\n\txd, xi  // Input axis (x)\n);\n\n// Print the interpolated values\ncout \u003c\u003c scientific \u003c\u003c setprecision(8) \u003c\u003c showpos;\nfor(int n = 0; n \u003c ni; ++n) {\n\tcout \u003c\u003c xi[n] \u003c\u003c \"\\t\" \u003c\u003c yi[n] \u003c\u003c endl;\n}\n```\n\n![](https://raw.githubusercontent.com/parsiad/mlinterp/master/images/1d.png)\n\nNote that the points **do not have to be evenly spaced**.\nTry modifying the above to use a non-uniform grid!\n\n### 2d\n\nLet's interpolate z = sin(x)cos(y) on the interval [-pi, pi] X [-pi, pi] using 15 evenly-spaced points along the x axis and 15 evenly-spaced points along the y axis.\n\n```c++\nusing namespace mlinterp;\n\n// Boundaries of the interval [-pi, pi]\nconstexpr double b = 3.14159265358979323846, a = -b;\n\n// Discretize the set [-pi, pi] X [-pi, pi] using 15 evenly-spaced\n// points along the x axis and 15 evenly-spaced points along the y axis\n// and evaluate sin(x)cos(y) at each of those points\nconstexpr int nxd = 15, nyd = 15, nd[] = { nxd, nyd };\ndouble xd[nxd];\nfor(int i = 0; i \u003c nxd; ++i) {\n\txd[i] = a + (b - a) / (nxd - 1) * i;\n}\ndouble yd[nyd];\nfor(int j = 0; j \u003c nyd; ++j) {\n\tyd[j] = a + (b - a) / (nyd - 1) * j;\n}\ndouble zd[nxd * nyd];\nfor(int i = 0; i \u003c nxd; ++i) {\n\tfor(int j = 0; j \u003c nyd; ++j) {\n\t\tconst int n = j + i * nyd;\n\t\tzd[n] = sin(xd[i]) * cos(yd[j]);\n\t}\n}\n\n// Subdivide the set [-pi, pi] X [-pi, pi] using 100 evenly-spaced\n// points along the x axis and 100 evenly-spaced points along the y axis\n// (these are the points at which we interpolate)\nconstexpr int m = 100, ni = m * m;\ndouble xi[ni];\ndouble yi[ni];\nfor(int i = 0; i \u003c m; ++i) {\n\tfor(int j = 0; j \u003c m; ++j) {\n\t\tconst int n = j + i * m;\n\t\txi[n] = a + (b - a) / (m - 1) * i;\n\t\tyi[n] = a + (b - a) / (m - 1) * j;\n\t}\n}\n\n// Perform the interpolation\ndouble zi[ni]; // Result is stored in this buffer\ninterp(\n\tnd, ni,        // Number of points\n\tzd, zi,        // Output axis (z)\n\txd, xi, yd, yi // Input axes (x and y)\n);\n\n// Print the interpolated values\ncout \u003c\u003c scientific \u003c\u003c setprecision(8) \u003c\u003c showpos;\nfor(int n = 0; n \u003c ni; ++n) {\n\tcout \u003c\u003c xi[n] \u003c\u003c \"\\t\" \u003c\u003c yi[n] \u003c\u003c \"\\t\" \u003c\u003c zi[n] \u003c\u003c endl;\n}\n```\n\n![](https://raw.githubusercontent.com/parsiad/mlinterp/master/images/2d.png)\n\nNote that the *x* and *y* axes **do not have to be identical**: they can each have any number of unequally spaced points.\nTry modifying the above to use different *x* and *y* axes!\n\n### Higher dimensions (3d, 4d, ...)\n\nIn general, if you have *k* dimensions with axes *x1*, *x2*, ..., *xk*, the `interp` routine is called as follows:\n\n```c++\ninterp(\n\tnd,  ni,                          // Number of points\n\tyd,  yi,                          // Output axis\n\tx1d, x1i, x2d, x2i, ..., xkd, xki // Input axes\n);\n```\n\n## 🦸 Advanced\n\n### Orders\n\nIn the 2d example, the `interp` routine assumes that the array ```zd``` is \"ordered\" in a certain way.\n\nIn particular, if ```i``` is the index associated with the x axis and ```j``` is the index associated with the y axis, ```n = j + i * nyd```  gives the index of the corresponding element in the ```zd``` array.\n\nThis is referred to as the *natural order*, and it generalizes to arbitrary dimensions. If instead we wanted ```n = i + j * nxd```, we would use the *reverse natural order*, which can be invoked by using instead\n\n```c++\ninterp\u003crnatord\u003e(nd, ni, zd, zi, xd, xi, yd, yi);\n```\n\nYou are free to define your own ordering scheme. To get a sense of how to do this, it's easiest to study the code for the natural order:\n\n```c++\nstruct natord {\n\ttemplate \u003ctypename Index, Index Dimension\u003e\n\tstatic Index mux(const Index *nd, const Index *indices) {\n\t\tIndex index = 0, product = 1, i = Dimension - 1;\n\t\twhile(true) {\n\t\t\tindex += indices[i] * product;\n\t\t\tif(i == 0) { break; }\n\t\t\tproduct *= nd[i--];\n\t\t}\n\t\treturn index;\n\t}\n};\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsiad%2Fmlinterp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparsiad%2Fmlinterp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsiad%2Fmlinterp/lists"}