{"id":15763279,"url":"https://github.com/shigma/assignment-interpolation","last_synced_at":"2025-03-31T10:15:59.364Z","repository":{"id":103500552,"uuid":"177438629","full_name":"shigma/assignment-interpolation","owner":"shigma","description":"四种插值算法的 C 语言实现","archived":false,"fork":false,"pushed_at":"2019-03-24T16:15:43.000Z","size":6,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-05T11:41:30.556Z","etag":null,"topics":[],"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/shigma.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":"2019-03-24T16:15:37.000Z","updated_at":"2019-03-24T16:43:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"5eeea3e2-4d59-4925-bf68-09141803126c","html_url":"https://github.com/shigma/assignment-interpolation","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shigma%2Fassignment-interpolation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shigma%2Fassignment-interpolation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shigma%2Fassignment-interpolation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shigma%2Fassignment-interpolation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shigma","download_url":"https://codeload.github.com/shigma/assignment-interpolation/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246450474,"owners_count":20779421,"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":[],"created_at":"2024-10-04T11:41:21.779Z","updated_at":"2025-03-31T10:15:59.311Z","avatar_url":"https://github.com/shigma.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Assignment: Interpolation\n\n数值计算方法第一次作业。\n\n## 实现功能\n\n设在区间 $[0, 6]$ 上有函数 $f(x)=e^{-2x}$。把区间 $n$ 等分，给定各结点上的函数值。利用三种不同的插值算法：\n\n1. 全区间上的 $n​$ 阶 Lagrange 插值多项式；\n2. 分段线性插值式；\n3. 三次样条插值式（采用第 1 种边界条件）；\n\n对 $n=20$ 和 $n=30$，分别计算\n\n$$\nx_{k-\\frac{1}{2}}=\\frac{6(k-\\frac{1}{2})}{n} (1\\le k\\le n)\n$$\n\n除此以外，本人还采用了 $n$ 阶 Newton 插值公式进行计算。\n\n\n\n## 算法分析\n\n### Lagrange 插值多项式\n\n根据 $n$ 次 Lagrange 插值公式：\n$$\n\\varphi_n(x_j)=\\sum _{i=0}^n \\frac{w_n(x_j)y_i}{(x_j-x_i)w'_n(x_i)}\n$$\n\n定义\n$$\n\\begin{aligned}\nfrac(n)\u0026=n\\cdot(n-1)\\cdots 1\\\\\nfrac2(n)\u0026=(n-0.5)\\cdot(n-1.5)\\cdots 0.5\\\\\n\\end{aligned}\n$$\n\n我们可以在 $O(n)$ 时间复杂度内完成上述两个函数的全部计算，再带入上式中，即可得到对应的结果。总体算法复杂度为 $O(n^2)$。\n\n### Newton 插值多项式\n\nNewton 插值采用递推的思路简化了计算，因此不需要做额外的优化就可以实现 $O(n^2)$ 复杂度的求值。做法完全同课本。总体算法复杂度为 $O(n^2)$。\n\n### 分段线性插值\n\n直接两两取平均即可。总体算法复杂度为 $O(n)$。\n\n### 样条插值\n\n首先计算出 $\\alpha_i, \\beta_i$ 的结果：\n``` c++\na[0] = 0; b[0] = -4;\na[N] = 1; b[N] = -4 * target[N];\nlong double coefb = 1.5 / unit;\nfor (int i = 1; i \u003c N; ++i) {\n    a[i] = 0.5;\n    b[i] = (source[i + 1] - source[i - 1]) * coefb;\n}\n```\n\n再依次求出 $A_i, B_i$：\n``` c++\nA[0] = 0; B[0] = -2;\nfor (int i = 1; i \u003c= N; ++i) {\nlong double deno = 2 + (1 - a[i]) * A[i - 1];\n    A[i] = -a[i] / deno;\n    B[i] = (b[i] - (1 - a[i]) * B[i - 1]) / deno;\n}\n```\n\n之后反向求出 $m_i$，并利用\n$$\n\\varphi_i=\\frac{y_i+y_{i+1}}{2}+\\frac{d(m_i-m_{i+1})}{8}\n$$\n\n得到最终的值。总体算法复杂度为 $O(n^2)$。\n\n## 实验结果\n\n环境：Windows 10，Sublime Text 3，TDM-GCC 6.8.1 64-bit\n\n可以参考下面的三个文件中的数据：\n\n1. `out_20.csv`: $n=20$ 时四种方法在每个测试点处的绝对误差；\n2. `out_30.csv`: $n=30$ 时四种方法在每个测试点处的绝对误差；\n3. `errors.csv`: $n=10, 20, \\cdots, 90$ 时四种方法的最大误差比较。\n\n## 数据分析\n\n### out_20.csv\n\n分析：线性插值误差最大，样条插值其次，Newton/Lagrange 插值最小且它们几乎相等（因为它们本来就应该相等）。可见数据量较小时 Newton/Lagrange 插值体现出了非常大的优势。\n\n### out_30.csv\n\n分析：线性插值略微优化，样条插值显著优化，Newton/Lagrange 插值显著优化。\n\n### errors.csv\n\n分析：数据量继续增大时，Newton/Lagrange 插值的误差开始增大，直至线性插值和样条插值；线性插值优化不明显，样条插值的效果得到了不错的提升。\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshigma%2Fassignment-interpolation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshigma%2Fassignment-interpolation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshigma%2Fassignment-interpolation/lists"}