分数阶累加的Python实现

分数阶累加是分数阶差分的逆运算,它不仅可用于分数阶差分方程的分析 ,也可以用于建立分数阶灰色模型。然而许多初学者在动手实现分数阶灰色模型时经常发现非常困难,究其原因其实是对定义公式的分析不够,对相应程序语言的特性不熟悉。

本文将从分数阶累加的定义出发,深入分析其计算过程,结合Python语言的特性,详细讲解其实现过程。

1、 分数阶累加的定义

对任意原始序列 x(0)(1),x(0)(2),...,x(0)(n)x^{(0)}(1),x^{(0)}(2),...,x^{(0)}(n)x(0)(1),x(0)(2),...,x(0)(n),其分数阶累加定义为:
x(r)(k)=∑i=1k(k−i+r−1k−i)x(0)(i)(1)x^{(r)}(k)=\sum_{i=1}^{k}\left(\begin{array}{c} k-i+r-1 \\ k-i \end{array}\right) x^{(0)}(i) \tag{1} x(r)(k)=i=1∑k​(k−i+r−1k−i​)x(0)(i)(1)

其中:
(k−i+r−1k−i)=(r+k−i−1)(r+k−i−2)⋯(r+1)r(k−i)!(2)\left(\begin{array}{c} k-i+r-1 \\ k-i \end{array}\right)=\frac{(r+k-i-1)(r+k-i-2) \cdots(r+1) r}{(k-i) !} \tag{2} (k−i+r−1k−i​)=(k−i)!(r+k−i−1)(r+k−i−2)⋯(r+1)r​(2)

通俗地讲,分数阶累加实际上就是一种加权求和,而在具体实现时关键是求出其加权系数 (2),该系数称为广义二项式系数广义牛顿二项式系数。通常初学者在看到该定义的第一反应即是用循环来实现,这种方式直接简单,但效率较低。尤其在使用类似Python这类脚本语言时其速度非常之慢。

2、广义牛顿二项式系数的计算

要实现分数阶累加的快速算法,关键的问题就在于如何快速算出其加权系数。对于一些不常用科学计算类程序的人而言,通常不太容易想到简单的解决方法。事实上,Python中提供了一个函数binom正好可以解决该问题。

binom函数是Scipy库中的一个函数。在Scipy的官方文档中对该函数并没有过多的介绍,那么我们先来简单写几个测试看看它的用法:

from scipy.special import binom# integers
print(binom(10,3))# decimals
print(binom(10,0.3))# array_like data
print(binom([5,8,10],[0.1,2,3.1]))

运行结果:

120.0
2.246507496036618
[  1.24554362  28.         129.20102313]

从上述代码中不难看出,binom函数支持的输入是十分简单的,第一个变量是二项式系数中的n,第二个变量是k,即是n中选出k个的组合数。同时它也支持小数和数组,这为我们进一步简化计算过程提供了极大的便利。

3、分数阶累加的矩阵形式及向量计算

本文既然是要讨论快速算法,那么自然就会尽量避免循环。虽然在目前看来,完全可以直接使用binom函数对其进行计算,但这样仍然要使用2层循环,并且计算n(n+1)2\frac{n(n+1)}{2}2n(n+1)​次。试想假设我们有10个点要计算,那么就得调用5050次,这个量级对于Python的循环是很低效的。

实际上Python中的numpy库是具有十分完善的矩阵计算功能,其计算效率非常高。我们要想办法利用这一特性,那么很自然地就需要引入它的矩阵定义:

[x(r)(1),x(r)(2),⋯,x(r)(n)]=[x(0)(1),x(0)(2),⋯,x(0)(n)][1(r1)⋯(r+n−3n−2)(r+n−2n−1)01⋯(r+n−4n−3)(r+n−3n−2)⋮⋮⋮⋮⋮00⋯1(r1)00⋯01](3)\left[ \begin{matrix} x^{(r)}(1), x^{(r)}(2), \cdots, x^{(r)}(n) \end{matrix} \right] =\left[ \begin{matrix} x^{(0)}(1), x^{(0)}(2),\cdots , x^{(0)}(n)\end{matrix} \right] \left[\begin{matrix} 1 & \left(\begin{matrix} r \\ 1 \end{matrix}\right) & \cdots & \left(\begin{matrix} r+n-3 \\ n-2 \end{matrix}\right) & \left(\begin{matrix} r+n-2 \\ n-1 \end{matrix}\right) \\ 0 & 1 & \cdots & \left(\begin{matrix} r+n-4 \\ n-3 \end{matrix}\right) & \left(\begin{matrix} r+n-3 \\ n-2 \end{matrix}\right) \\ \vdots & \vdots & \vdots & \vdots & \vdots \\ 0 & 0 & \cdots & 1 & \left(\begin{matrix} r \\ 1 \end{matrix}\right)\\ 0 & 0 & \cdots & 0 &1 \end{matrix}\right] \tag{3} [x(r)(1),x(r)(2),⋯,x(r)(n)​]=[x(0)(1),x(0)(2),⋯,x(0)(n)​]⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​10⋮00​(r1​)1⋮00​⋯⋯⋮⋯⋯​(r+n−3n−2​)(r+n−4n−3​)⋮10​(r+n−2n−1​)(r+n−3n−2​)⋮(r1​)1​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​(3)

这里有一个特别要注意的点:处在同一右对角线上的所有元素都相等。进一步我们可以发现一个更直接有利于我们编程的事实:从右向左的每一列都相当于其右列去掉最后一个元素,再向左移动一位。那么我们容易得出一个非常简单且有用的结论:我们在编程实现时只需要计算最后一列。 此时的时间复杂度已经从O(n2)O(n^2)O(n2)降到了线性时间复杂度O(n)O(n)O(n),同时,其内存消耗也由原来的n2n^2n2单位变成了nnn个单位。

要计算最后一列系数,实际上只需要考虑定义式 (3) 中k=nk=nk=n的情形,利用Python的向量计算格式,可以很容易实现这一目的:

import numpy as np
from scipy.special import binomr = 0.1
k = 10
i = np.linspace(1,k,k)fnum = k - i + r -1
ki = k - icoefs = binom(fnum,ki)print(coefs)

运行结果:

[0.01447564 0.01608405 0.01812287 0.02079674 0.02446675 0.02983750.0385     0.055      0.1        1.        ]
4、分数阶累加的实现

结合上述分析,这里我们得到的系数coefs实际上是矩阵式 (3) 中的第一行。再次观察矩阵式注意到在计算累加时是采用原序列的行左乘矩阵的列的方式进行。从编程的角度考虑则不难发现要计算第kkk个分数阶累加值,即是将前kkk个原序列点中的值组成的向量对应乘以系数的倒数前kkk个值再求和。这一步实现的时候就需要用到一层循环了。

x = np.random.rand(10)
xr = np.zeros(10)
for k in range(10):xr[k] = sum(x[:k+1]*coefs[-(k+1):])print(x)
print(xr)

运行结果:

[0.42343781 0.53237537 0.75292602 0.32316064 0.6931979  0.496077060.74748506 0.3630722  0.29325613 0.95218414]
[0.42343781 0.57471915 0.82945264 0.44403624 0.80005567 0.638403230.89195739 0.5386026  0.45048115 1.09707706]
5、分数阶累加的完整代码

最后为方便使用,我们将该方法封装为完整的函数

from scipy.special import binom
import numpy as np# compute the r-order accumulation
def fago(x,r):n = len(x)i = np.linspace(1,n,n)coefs = binom(n - i + r -1,n - i)xr = np.zeros(10)for k in range(10):xr[k] = sum(x[:k+1]*coefs[-(k+1):])return xr

简单测试一下这个函数:

import time t1 = time.time()
print(fago(x,0.1))
t2 = time.time()print('Runtime:',t2-t1,'s')

运行结果:

array([0.42343781, 0.57471915, 0.82945264, 0.44403624, 0.80005567,0.63840323, 0.89195739, 0.5386026 , 0.45048115, 1.09707706])
Runtime: 0.0010225772857666016 s

可以看到和刚才的结果一模一样,运行时间只有0.001秒。

更多关于分数阶累加的应用可查看相应论文:

  1. A_novel_fractional_grey_system_model_and_its_application
  2. A novel fractional time delayed grey model with Grey Wolf Optimizer and its applications in forecasting the natural gas and coal consumption in Chongqing China
  3. The novel fractional discrete multivariate grey system model and its applications

分数阶累加的Python实现相关推荐

  1. Python 分数阶傅里叶变换

    Python 分数阶傅里叶变换 基于github上的开源库实现FRFT. https://github.com/nanaln/python_frft import frft import numpy ...

  2. 《C语言及程序设计》实践参考——分数的累加

    返回:贺老师课程教学链接  项目要求 [项目1:分数的累加] 编程序,输出1/3-3/5+5/7-7/9-+19/21的结果 提示:如果直接解决上面的问题有困难,可以设计一条"由易到难&qu ...

  3. 《C语言及程序设计》实践參考——分数的累加

    返回:贺老师课程教学链接  项目要求 [项目1:分数的累加] 编程序.输出1/3-3/5+5/7-7/9-+19/21的结果 提示:假设直接解决上面的问题有困难.能够设计一条"由易到难&qu ...

  4. 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第9章-不确定分数阶系统的包含控制

    第8章 回到目录 第10章 第9章-不确定分数阶系统的包含控制 9.1 引言 9.2 问题描述 9.3 不确定分数阶多智能体系统的包含控制分析 9.3.1 基于状态控制器的包含控制 9.3.2 基于输 ...

  5. 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第7章-不确定分数阶系统的多一致

    第6章 回到目录 第8章 第7章-不确定分数阶系统的多一致 7.1 引言 7.2 问题描述 7.3 不确定分数阶系统的多一致分析 7.3.1 输出反馈控制器下的多一致 7.3.2 状态反馈控制器下的多 ...

  6. 【控制】《多智能体系统的动力学分析与设计》徐光辉老师-第4章-带有事件驱动控制的分数阶多智能体系统的一致性

    第3章 回到目录 第5章 第4章-带有事件驱动控制的分数阶多智能体系统的一致性 4.1 引言 4.2 预备知识与系统模型描述 4.2.1 Caputo 分数阶运算 4.2.2 系统模型 4.3 集中式 ...

  7. 分数阶simulink工具箱_CCDC 2021特别专题:分数阶微积分与分数阶系统

    点击蓝字,关注我们 征文通知 第33届中国控制与决策会议(CCDC 2021)将于2021年5月22日~24日在中国昆明举行.会议特别专题分数阶微积分与分数阶系统现向从事相关研究的广大专家.学者征稿. ...

  8. 基于分数阶的图像边缘细节检测

    1 分数阶微分理论 分数阶微分几乎和整数阶微分同时诞生,但由于一直没有常见的物理现象能够解释这一数学表达式的含义,所以其也未被广泛运用.几个世纪以来,虽然分数阶微分理论得到了长足的发展,但至今没有统一 ...

  9. matlab 分数阶混沌系统的完全同步控制

    1.内容简介 略 625-可以交流.咨询.答疑 2.内容说明 分数阶微积分这一重要的数学分支,其诞生在1695年,几乎和经典微积分同时出现.那一年,德国数学家Leibniz 和法国数学家L'Hopit ...

最新文章

  1. android 手机wifi重启,android – 如何通过重启来记住wifi配置和连接网络
  2. yaml语法--多行字符串可以使用|保留换行符,也可以使用>折叠换行
  3. Linux下的各文件夹的作用(转)
  4. 如何免费申请并使用SAP Marketing Cloud测试系统
  5. python基础课程7(看代码看注释)--matplotlib作图
  6. odbc驱动程序管理器连接未打开_Windows 10 怎么修复 Windows 中的 Wi-Fi 连接问题,我教你...
  7. php执行多个存储过程
  8. 编程语言对比 循环语句
  9. Flutter实战一Flutter聊天应用(十四)
  10. FFmpeg下载网络视频流
  11. 常见的几类矩阵(正交矩阵、酉矩阵、正规矩阵等)
  12. sprint tool suite启动tomcat
  13. An Introduction to Lock-Free Programming
  14. 【DDR3_Electrical Characteristics and AC Timing】_Data Setup,Hold and Slew Rate Derating
  15. MySQL day()函数
  16. 动态规划 最长公共子序列 过程图解
  17. android手机上的返回键和home键
  18. peewee mysql_peewee基本使用
  19. 【论文解读】HIN2Vec: Explore Meta-paths in Heterogeneous Information Networks for Representation Learning
  20. 【学习贴】Ps终极动画练习

热门文章

  1. 全国计算机二级公共基础知识练习,2020年全国计算机二级公共基础知识练习题(7)...
  2. *1408素数回文数的个数
  3. Unity使用陀螺仪控制Camera
  4. codeforces round 422 div2 补题 CF 822 A-F
  5. go map并发写错误问题
  6. 简化管理面向服务的应用程序的创建
  7. 微软嵌入式WEC2013产品研讨会(深圳站---2013.10.16)
  8. 如何才能写出一手高质量优美的代码
  9. Paging of Large Resultsets in ASP.NET中介绍的SET ROWCOUNT方式存储过程的问题
  10. 用YII实现多重查询(基于tag)