{"id":13710467,"url":"https://github.com/autodiff/autodiff","last_synced_at":"2025-05-14T08:07:39.740Z","repository":{"id":34315360,"uuid":"141541151","full_name":"autodiff/autodiff","owner":"autodiff","description":"automatic differentiation made easier for C++","archived":false,"fork":false,"pushed_at":"2025-01-27T07:45:25.000Z","size":1986,"stargazers_count":1753,"open_issues_count":97,"forks_count":177,"subscribers_count":43,"default_branch":"main","last_synced_at":"2025-04-11T02:51:58.716Z","etag":null,"topics":["auto-differentiation","autodiff","autodifferentiation","automatic-differentiation","derivatives","differentiation","numerical-derivation"],"latest_commit_sha":null,"homepage":"https://autodiff.github.io","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/autodiff.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-07-19T07:28:38.000Z","updated_at":"2025-04-10T17:01:11.000Z","dependencies_parsed_at":"2024-05-01T23:55:10.407Z","dependency_job_id":"e3b83208-b1ea-4ae3-b4fa-9d988328ffb4","html_url":"https://github.com/autodiff/autodiff","commit_stats":{"total_commits":545,"total_committers":36,"mean_commits":15.13888888888889,"dds":0.4917431192660551,"last_synced_commit":"28efeb6c3e64dff00d0335c6e4e6fa6fa6c4b5ce"},"previous_names":[],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autodiff%2Fautodiff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autodiff%2Fautodiff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autodiff%2Fautodiff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autodiff%2Fautodiff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/autodiff","download_url":"https://codeload.github.com/autodiff/autodiff/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101557,"owners_count":22014908,"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","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":["auto-differentiation","autodiff","autodifferentiation","automatic-differentiation","derivatives","differentiation","numerical-derivation"],"created_at":"2024-08-02T23:00:56.946Z","updated_at":"2025-05-14T08:07:34.729Z","avatar_url":"https://github.com/autodiff.png","language":"C++","funding_links":[],"categories":["Math","Machine Learning Framework","C++","进程间通信"],"sub_categories":["General Purpose Framework","数学"],"readme":"\u003ca href=\"https://autodiff.github.io\" target=\"_blank\"\u003e\n    \u003cimg src='art/autodiff-header.svg' width='100%'\u003e\n\u003c/a\u003e\n\n![Linux build status](https://github.com/autodiff/autodiff/workflows/linux/badge.svg?branch=master)\n![macOS build status](https://github.com/autodiff/autodiff/workflows/osx/badge.svg?branch=master)\n![Windows build status](https://github.com/autodiff/autodiff/workflows/windows/badge.svg?branch=master)\n\n# Overview\n\n**autodiff** is a C++17 library that uses modern and advanced programming\ntechniques to enable automatic computation of derivatives in an efficient, easy,\nand intuitive way.\n\n## Demonstration\n\nConsider the following function *f(x, y, z)*:\n\n```c++\ndouble f(double x, double y, double z)\n{\n    return (x + y + z) * exp(x * y * z);\n}\n```\n\nwhich we use use to evaluate the variable *u = f(x, y, z)*:\n\n```c++\ndouble x = 1.0;\ndouble y = 2.0;\ndouble z = 3.0;\ndouble u = f(x, y, z);\n```\n\nHow can we minimally transform this code so that not only *u*, but also its\nderivatives *∂u/∂x*, *∂u/∂y*, and *∂u/∂z*, can be computed?\n\nThe next two sections present how this can be achieved using two automatic\ndifferentiation algorithms implemented in **autodiff**: **forward mode** and\n**reverse mode**.\n\n### Forward mode\n\nIn a *forward mode automatic differentiation* algorithm, both output variables\nand one or more of their derivatives are computed together. For example, the\nfunction evaluation *f(x, y, z)* can be transformed in a way that it will not\nonly produce the value of *u*, *the output variable*, but also one or more of\nits derivatives *(∂u/∂x,  ∂u/∂y, ∂u/∂z)* with respect to the *input\nvariables* *(x, y, z)*.\n\nEnabling forward automatic differentiation for the calculation of derivatives\nusing **autodiff** is relatively simple. For our previous function *f*, we only\nneed to replace the floating-point type `double` with `autodiff::dual` for both\ninput and output variables:\n\n```c++\ndual f(const dual\u0026 x, const dual\u0026 y, const dual\u0026 z)\n{\n    return (x + y + z) * exp(x * y * z);\n}\n```\n\nWe can now compute the derivatives *∂u/∂x*,  *∂u/∂y*, and *∂u/∂z* as follows:\n\n```c++\ndual x = 1.0;\ndual y = 2.0;\ndual z = 3.0;\ndual u = f(x, y, z);\n\ndouble dudx = derivative(f, wrt(x), at(x, y, z));\ndouble dudy = derivative(f, wrt(y), at(x, y, z));\ndouble dudz = derivative(f, wrt(z), at(x, y, z));\n```\n\nThe auxiliary function `autodiff::wrt`, an acronym for **with respect to**,\nis used to indicate which input variable *(x, y, z)* is the selected one to\ncompute the partial derivative of *f*. The auxiliary function `autodiff::at`\nis used to indicate where (at which values of its parameters) the derivative\nof *f* is evaluated.\n\n### Reverse mode\n\nIn a *reverse mode automatic differentiation* algorithm, the output variable of\na function is evaluated first. During this function evaluation, all\nmathematical operations between the input variables are *\"recorded\"* in an\n*expression tree*. By traversing this tree from top-level (output variable as\nthe root node) to bottom-level (input variables as the leaf nodes), it is\npossible to compute the contribution of each branch on the derivatives of the\noutput variable with respect to input variables.\n\n\u003cimg\n    src='art/expression-tree-diagram.svg'\n    style='max-width:100%;'\n    title='Expression tree diagram.'\u003e\n\nThus, a single pass in a reverse mode calculation **computes all derivatives**,\nin contrast with forward mode, which requires one pass for each input variable.\nNote, however, that it is possible to change the behavior of a forward pass so\nthat many (perhaps even all) derivatives of an output variable are computed\nsimultaneously (e.g., in a single forward pass, *∂u/∂x*,  *∂u/∂y*, and *∂u/∂z*\nare evaluated together with *u*, in contrast with three forward passes, each\none computing the individual derivatives).\n\nSimilar as before, we can use **autodiff** to enable reverse automatic\ndifferentiation for our function *f* by simply replacing type `double` with\n`autodiff::var` as follows:\n\n```c++\nvar f(var x, var y, var z)\n{\n    return (x + y + z) * exp(x * y * z);\n}\n```\n\nThe code below demonstrates how the derivatives *∂u/∂x*,  *∂u/∂y*, and *∂u/∂z*\ncan be calculated:\n\n```c++\nvar x = 1.0;\nvar y = 2.0;\nvar z = 3.0;\nvar u = f(x, y, z);\n\nDerivatives dud = derivatives(u);\n\ndouble dudx = dud(x);\ndouble dudy = dud(y);\ndouble dudz = dud(z);\n```\n\nThe function `autodiff::derivatives` will traverse the expression tree stored\nin variable `u` and compute all its derivatives with respect to the input\nvariables *(x, y, z)*, which are then stored in the object `dud`. The\nderivative of `u` with respect to input variable `x` (i.e., *∂u/∂x*) can then\nbe extracted from `dud` using `dud(x)`. The operations `dud(x)`, `dud(y)`,\n`dud(z)` involve no computations! Just extraction of derivatives previously\ncomputed with a call to function `autodiff::derivatives`.\n\n## Documentation\n\nCheck the documentation website for more details:\n\n\u003ca href=\"https://autodiff.github.io\" target=\"_blank\"\u003e\n    \u003cimg src='art/autodiff.github.io.svg' width='100%'\u003e\n\u003c/a\u003e\n\n# License\n\nMIT License\n\nCopyright © 2018–2024 Allan Leal\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n[issues]: https://github.com/autodiff/autodiff/issues/new\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautodiff%2Fautodiff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautodiff%2Fautodiff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautodiff%2Fautodiff/lists"}