{"id":23888446,"url":"https://github.com/usmanmehmood55/numerical_calculus","last_synced_at":"2025-02-23T04:41:47.518Z","repository":{"id":170150176,"uuid":"646267654","full_name":"usmanmehmood55/numerical_calculus","owner":"usmanmehmood55","description":"Example and test code for calculating derivatives and integrals","archived":false,"fork":false,"pushed_at":"2023-05-28T19:53:29.000Z","size":25,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-04T09:04:37.721Z","etag":null,"topics":["c","differential","differential-equations","integral","integral-equations","numerical-analysis","numerical-computation","numerical-optimization"],"latest_commit_sha":null,"homepage":"","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/usmanmehmood55.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":"2023-05-27T20:34:49.000Z","updated_at":"2023-09-15T19:57:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"71572d4b-9d9f-4e64-8dcb-4c282ac0ac99","html_url":"https://github.com/usmanmehmood55/numerical_calculus","commit_stats":null,"previous_names":["usmanmehmood55/numerical_calculus"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usmanmehmood55%2Fnumerical_calculus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usmanmehmood55%2Fnumerical_calculus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usmanmehmood55%2Fnumerical_calculus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usmanmehmood55%2Fnumerical_calculus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/usmanmehmood55","download_url":"https://codeload.github.com/usmanmehmood55/numerical_calculus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240271521,"owners_count":19774859,"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":["c","differential","differential-equations","integral","integral-equations","numerical-analysis","numerical-computation","numerical-optimization"],"created_at":"2025-01-04T09:00:25.819Z","updated_at":"2025-02-23T04:41:47.510Z","avatar_url":"https://github.com/usmanmehmood55.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Numerical Calculus\n\nThis code shows how numerical integrals and derivatives are taken of a given \ndataset. It is used as an example and a testing place for a relatively more \ncomplicated application, the [PID Controller](https://github.com/usmanmehmood55/pid_controller).\n\n- [Numerical Calculus](#numerical-calculus)\n  - [Setup](#setup)\n  - [Explanation of General Code](#explanation-of-general-code)\n  - [Explanation of Calculating Functions](#explanation-of-calculating-functions)\n    - [Derivative](#derivative)\n    - [Integral](#integral)\n  - [Results](#results)\n\n## Setup\n\nTo get the code running, create a build folder, and go into it.\n```\nmkdir build\ncd build/\n```\n\nThen use [CMake](https://cmake.org/download/) to generate make files.\n```\ncmake ../CMakeLists.txt \n```\n\nAnd finally use make to build\n```\nmake .\n```\n\nThen launch the executable\n```\n./numerical_calc.exe\n```\n\n\n## Explanation of General Code\n\nThe code starts with initializing the number of samples in the dataset, and the\nresolution factor. The resolution factor dictates the time delta, and therefore\nthe accuracy of these calculations.\n\nIt then calculates the size for a ring buffer of an appropriate size.\n```c\nconst uint16_t sample_count      = 10;\nconst uint16_t resolution_factor = 3000; \nconst double   time_const        = 1.0 / (double)resolution_factor;\nconst uint16_t buffer_size       = (uint16_t)((double)sample_count / time_const);\n```\n\nIt should be noted that specifically using a ring buffer instead of a usual \nbuffer has no purpose in these calculations, but due to the application, it \nhas to be used int the PID Controller project so it is being used here as \nwell.\n\nA function $y=f(x)$ implemented as `double f (double x)` is also \ndeclared, upon which derivation and integration would be performed. In this \ncode example it is set to $y=x^3$\n\nThe ring buffer is then initialized, and filled with output values of the \nfunction `double f (double x)`, with inputs starting from 0 to `sample_count`.\n```c\nring_buffer rb;\nring_buffer_init(\u0026rb, buffer_size);\n\nfor (uint16_t i = 1; i \u003c= rb.size; i++)\n{\n    double number = (double)i * time_const;\n    ring_buffer_add(\u0026rb, f(number));\n}\n```\n\n## Explanation of Calculating Functions\n\n### Derivative\nDerivatives are taken using the simplest method possible\n\n$$ \\frac{d}{dt}x = \\frac{\\Delta x}{\\Delta t} = \\frac{x_t - x_{t-1}}{\\Delta t} $$\n\nThis is implemented as\n```c\ndouble calculate_derivative(const ring_buffer *rb, uint16_t index, double time_interval)\n{\n    double derivative = 0.0;\n\n    double x_this = ring_buffer_get_item(rb, index);\n    double x_last = ring_buffer_get_item(rb, index - 1);\n    double delta =  x_this - x_last;\n    derivative = delta / time_interval;\n\n    return derivative;\n}\n```\n\n### Integral\nIntegrals can be taken using the typical trapezoidal method.\n\n$$ \\int_{a}^{b}{f(x) \\space dx} = \\frac{\\Delta t}{2} \\\\{ f(a) + 2 \\sum_{i=a+1}^{b-1} f(x_i) + f(b) \\\\} $$\n\nThis is implemented as\n```c\ndouble trapezoidal(const ring_buffer *rb, double time_interval)\n{\n    double integral = 0.0;\n\n    double x_first = ring_buffer_get_item(rb, 0);\n\n    double x_sum_between = 0.0;\n    for (uint16_t i = 1; i \u003c rb-\u003esize; i++)\n    {\n        double x_this = ring_buffer_get_item(rb, i);\n        x_sum_between += x_this;\n    }\n\n    double x_last = ring_buffer_get_item(rb, rb-\u003esize);\n\n    integral = (time_interval / 2.0) * (x_first + (2.0 * x_sum_between) + x_last);\n\n    return integral;\n}\n```\n\nHowever a more accurate integral is taken using this modified method\n\n$$ \\int_{a}^{b}{f(x) \\space dx} = \\frac{\\Delta t}{2} \\space \\sum_{i=a}^{b} \\\\{  f(x_i) + f(x_{i-1}) \\\\} $$\n\nThis is implemented as\n```c\ndouble calculate_integral(const ring_buffer *rb, double time_interval)\n{\n    double integral = 0.0;\n    \n    for (uint16_t i = 0; i \u003c rb-\u003esize; i++)\n    {\n        double x_this = ring_buffer_get_item(rb, i);\n        double x_last = ring_buffer_get_item(rb, i - 1);\n        \n        integral += (x_this + x_last);\n    }\n\n    integral *= time_interval;\n    integral /= 2.0;\n    \n    return integral;\n}\n```\n\n## Results\n\nIn this code example, the input data set is 1 to 10\n\n$$ \\\\{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 \\\\} $$\n\nThe function used is\n\n$$ y = x^3 $$\n\nWhich makes the function output dataset used for calculations\n\n$$ \\\\{ 1, 8, 27, 64, 125, 216, 343, 512, 729, 1000 \\\\} $$\n\nThe exact integral should be $2500$, and the exact derivative using the \nequation $y=3x^2$ at each point should be:\n\n$$ \\\\{ 3, 12, 27, 48, 75, 108, 147, 192, 243, 300 \\\\} $$\n\nWhen the time delta is 1 unit, the numerical integral is $2524.500000$ and the \nnumerical derivative at each point is:\n\n$$ \\\\{ 1, 7, 19, 37, 61, 91, 127, 169, 217, 271 \\\\} $$\n\nWhen the time delta is reduced from 1 unit to 0.001 unit, the numerical \nintegral becomes 2500.000025 and the numerical derivative at each point \nbecomes:\n\n$$ \\\\{ 3, 11.99, 26.99, 47.99, 74.99, 107.98, 146.98, 191.98, 242.97, 299.97 \\\\} $$\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusmanmehmood55%2Fnumerical_calculus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fusmanmehmood55%2Fnumerical_calculus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusmanmehmood55%2Fnumerical_calculus/lists"}