信号与系统——离散时间系统的建模及仿真

摘要

在本次实验中,我们首先完成了对于固定金额利率,固定存取方式的建模仿真和计算,利用MATLAB得到了要求的余额变化图,并且对于此类模型的构建有了基本的了解。随后我们在问题的基础上对于非给定金额和存取方式的最大收益比进行了模拟,针对此类没有明确数学表达式的问题,我们采用了蒙特卡洛模拟的方法并且和我们经验结合,合理推论得到了最大化收益的方法。

关键词

存取款模型,MATLAB,蒙特卡洛模拟。

问题1------银行存款帐户余额每月变化情况的建模及仿真

考虑如下的问题:银行月息1%,起始金额1000元。前两年(24个月)每月存入
100元(该部分款项从下月开始计息),从第三年起不再存入,每月从账户中取出500元。
由此我们可以判断,这是一个DT系统,我们首先确定他的系统方程。

建立该离散时间系统的数学模型

在建模之前,我们首先做一些必要的假设和字符的说明:

  1. 设定利息在每月月末结算,当月存入的款项将从下月开始计算利息;

  2. 存取都在每月的月初进行;

  3. 我们设y[n]表示每月月末结算利之后的余额,用x[n]表示每月的存取。即前者是系统响应的结果,后者是系统的输入。

由上边的假设,我们可以得到式子: y [ n ] = 1.01 y [ n − 1 ] + x [ n ] y\lbrack n\rbrack = 1.01y\lbrack n - 1\rbrack + x\lbrack n\rbrack y[n]=1.01y[n1]+x[n],其中y[0]=1000。在 n ∈ [ 1 , 24 ] n \in \lbrack 1,24\rbrack n[1,24]时,x[n]=100。

在存款的时候,月初存入的要在下月开始计算利息,但是在取款的时候,月初取出的不应再计入当月的利息,所以在 n > 24 n > 24 n>24的时候 y [ n ] = 1.01 ( y [ n − 1 ] + x [ n ] ) y\lbrack n\rbrack = 1.01(y\lbrack n - 1\rbrack + x\lbrack n\rbrack) y[n]=1.01(y[n1]+x[n]),x[n]=-500。

综上所述,我们写出总的输入和系统函数:

x [ n ] = { 100   , n ∈ [ 1 , 24 ] − 500   , n > 25   x\lbrack n\rbrack = \left\{ \begin{array}{r} 100\ ,n \in \lbrack 1,24\rbrack \\ -500\ ,n > 25 \\ \end{array} \right.\ x[n]={100 ,n[1,24]500 ,n>25 

y [ n ] = { 1.01 y [ n − 1 ] + x [ n ]   , n ∈ [ 1 , 24 ] 1.01 ( y [ n − 1 ] + x [ n ] )   , n > 25   y\lbrack n\rbrack = \left\{ \begin{array}{r} 1.01y\lbrack n - 1\rbrack + x\lbrack n\rbrack\ ,n \in \lbrack 1,24\rbrack \\ 1.01(y\lbrack n - 1\rbrack + x\lbrack n\rbrack)\ ,n > 25 \\ \end{array} \right.\ y[n]={1.01y[n1]+x[n] ,n[1,24]1.01(y[n1]+x[n]) ,n>25 

利用MATALAB计算每月帐户余额变动情况并画图

根据总的输入和系统函数:

x [ n ] = { 100   , n ∈ [ 1 , 24 ] − 500   , n > 25   x\lbrack n\rbrack = \left\{ \begin{array}{r} 100\ ,n \in \lbrack 1,24\rbrack \\ -500\ ,n > 25 \\ \end{array} \right.\ x[n]={100 ,n[1,24]500 ,n>25 

y [ n ] = { 1.01 y [ n − 1 ] + x [ n ]   , n ∈ [ 1 , 24 ] 1.01 ( y [ n − 1 ] + x [ n ] )   , n > 25   y\lbrack n\rbrack = \left\{ \begin{array}{r} 1.01y\lbrack n - 1\rbrack + x\lbrack n\rbrack\ ,n \in \lbrack 1,24\rbrack \\ 1.01(y\lbrack n - 1\rbrack + x\lbrack n\rbrack)\ ,n > 25 \\ \end{array} \right.\ y[n]={1.01y[n1]+x[n] ,n[1,24]1.01(y[n1]+x[n]) ,n>25 

我们可以编写MATLAB程序如下:

y=[]; %账户
y(1)=1000; %初始账户为1000 y[0]=1000但是MATLAB索引只能从1开始
Rate=0.01; %设置月利息
for n=2:25
    y(n)=(1+Rate)*y(n-1)+100; %对应设定的y[n]=1.01y[n-1]+x[n]
    fprintf('第%d个月结束后,账户的余额是%f\n',(n-1),y(n)) 
%n-1修正月数
end
disp("存款结束")

for i=1:n
    plot(i-1,y(i),'.');
    hold on
end
xlabel('月数')
ylabel('账户余额')
title('月利率1%时 账户余额变化') 
n=26; 
%存款结束后是24月末 对应数组的y(25),则下一个应该是25月对应y(26)
while(1)
    if (1+Rate)*(y(n-1)-500)<0 
%当最后一个月不足500的时候,全部取出,让余额为0,结束循环
        y(n)=0;
        fprintf('第%d个月结束后,账户的余额是%f\n',(n-1),y(n))
        break
    else
        y(n)=(1+Rate)*(y(n-1)-500);
        fprintf('第%d个月结束后,账户的余额是%f\n',(n-1),y(n))
    end
    n=n+1;
end

for i=1:n
    plot(i-1,y(i),'.');
    hold on
end
xlabel('月数')
ylabel('账户余额')
title('月利率1%时 账户余额变化')

对应的输出如下:

我们可以很直观的看出,当在32月结束的时候,账户的余额只有111,在33月月初的时候,账户余额为0。

绘制图案

在前边的

x [ n ] = { 100   , n ∈ [ 1 , 24 ] − 500   , n > 25   x\lbrack n\rbrack = \left\{ \begin{array}{r} 100\ ,n \in \lbrack 1,24\rbrack \\ -500\ ,n > 25 \\ \end{array} \right.\ x[n]={100 ,n[1,24]500 ,n>25 

y [ n ] = { 1.01 y [ n − 1 ] + x [ n ]   , n ∈ [ 1 , 24 ] 1.01 ( y [ n − 1 ] + x [ n ] )   , n > 25   y\lbrack n\rbrack = \left\{ \begin{array}{r} 1.01y\lbrack n - 1\rbrack + x\lbrack n\rbrack\ ,n \in \lbrack 1,24\rbrack \\ 1.01(y\lbrack n - 1\rbrack + x\lbrack n\rbrack)\ ,n > 25 \\ \end{array} \right.\ y[n]={1.01y[n1]+x[n] ,n[1,24]1.01(y[n1]+x[n]) ,n>25 

假定月息为5%时,重新完成上述过程

在上述程序的基础上,我们只需要变更程序开始的Rate=0.05,即:

可以直观的看出,当51月的时候,账户余额为0。此外还可以对比两种情况:

问题2------账户利益比最大设计

问题简述和分析

针对上述银行存款问题,假定银行存款月息为1%,仍以24个月为限。
要求:设计一个帐户存取款方案,使得帐户收益比最大。(帐户收益比=取出资金总额/存入资金总额)

在这部分中,我们要考虑如何使得收益最大化。根据常识我们知道应当使得钱款尽可能早的存入账户,并且尽可能晚的取出账户。但我们仍然需要合理的证明来验证我们的思路。

蒙特卡罗模拟最大收益比

蒙特卡罗(Monte Carlo)方法,又称随机抽样或统计试验方法,针对某些问题,传统的经验方法由于不能逼近真实的物理过程,很难得到满意的结果,而蒙特卡罗方法通常采用随机数模拟的方法,能够真实地模拟实际物理过程,故解决问题与实际非常符合。[2]

模型和假设

为了方便的解决问题,我们做出一些假设:

  1. 每月只有存入或者取出;

  2. 1月的时候账户初始金额为0;

  3. 24月的时候不再存取,在月末取出所有的值。

在模型上我们仍然采用第一问的模型:

y [ n ] = { 1.01 y [ n − 1 ] + x [ n ]   ,   x [ n ] > 0 1.01 ( y [ n − 1 ] + x [ n ] ) ,   x [ n ] < 0   y\lbrack n\rbrack = \left\{ \begin{array}{r} 1.01y\lbrack n - 1\rbrack + x\lbrack n\rbrack\ ,\ x\lbrack n\rbrack > 0 \\ 1.01\left( y\lbrack n - 1\rbrack + x\lbrack n\rbrack \right),\ x\lbrack n\rbrack < 0 \\ \end{array} \right.\ y[n]={1.01y[n1]+x[n] , x[n]>01.01(y[n1]+x[n]), x[n]<0 

收益和存入金额的关系

首先考虑收益和每月存入的金额有无关系,由此我们有第二问的第一个程序:

syms y c q %设定 y c q分别是账户的余额 存入和取出 对应汉语拼音
syms x %总的金额是x
syms sum_c sum_q %总存入和总取出
syms scale %收益比
Rate=0.01;
y=0;%初始的y=0
sum_c=0;
sum_q=0;
flag=0;
c=rand*x;
y=y+rand*c;
sum_c=sum_c+c;
    for j=2:24
        c=rand*x;
        q=rand*x;
        sum_c=sum_c+c;
        sum_q=sum_q+q;
        y=(1+Rate)*(y-q)+c;
    end
    sum_q=sum_q+y;%更新取出的金额
    scale=vpa(sum_q/sum_c)

在这部分程序中,我们的金额是一个sym变量,我们通过这种方式来表示每月存取的金额是完全未知的,计算收益比scale发现,这是与x无关的一个变量,说明收益比和设置的初始金额是无关的。

蒙特卡洛模拟

收益比与设定的初始金额是无关的,于是在之前的基础上,我们修改初始金额为实数,方便我们进行比较和判断。

All=1000;  %定义金额
Rate=0.01; %定义月利率
Max_scale=0; %定义最大收益比
Real_time=0; %定义有效模拟次数
for i=1:10000000 %模拟次数
    y=0; %初始账户余额
    Sum_c=0; %总存入 每次开始模拟都清零
    Sum_q=0; %总取出 每次开始模拟都清零
    flag=0; %标记模拟是否有效
    first=rand*All; %第一个月只有存入 随机存入0-1000的值
    y=y+first;
    Sum_c=Sum_c+first;
    for j=2:24 %从第二个月开始
        x=(2*rand-1)*All; %随机产生存取金额 正的是存入 负的表示取出
        if y+x<0 %如果取金额大于账户余额 置flag为-1本次模拟无效
            flag=-1;
            break
        elseif x>0 %当存入的时候对应模型1.01y[n-1]+x[n]
            y=(1+Rate)*y+x;
            Sum_c=Sum_c+x;
        else %取出对应 1.01(y[n-1]+x[n])
            y=(1+Rate)*(y+x);
            Sum_q=Sum_q+abs(x);
        end
    end
    if flag==-1 %如果模拟无效 不做处理
        ;
    else %如果模拟有效
        Sum_q=Sum_q+y; %取出账户所有余额
        scale=vpa(Sum_q/Sum_c); %计算收益比
        if Max_scale<scale %更新收益比
            Max_scale=scale;
        end
    end
end
Max_scale %输出最大收益比
Real_time %输出有效模拟次数

在问题之初我们就根据常识做出假设,应当使尽早的存入账户,这种情况下的收益比应当是:

( 1 + 0.01 ) 23 = 1.2571 (1 + 0.01)^{23} = 1.2571 (1+0.01)23=1.2571

通过数次模拟,我们得到的最大收益比都小于1.2571,所以我们可以根据蒙特卡洛模拟思想得出结论,最佳的存取模式应当是一次将所有的全部存入,然后在24月末的时候一次性取出。

总结

一个系统可以看成一个过程,在其中输入信号被该系统所变换,或者说系统以某种方式对信号做出响应。[1]一个离散时间系统(discrete-time
system)就是将离散时间输人信号变换为离散时间输出信号:
x [ n ] → y [ n ] x\lbrack n\rbrack \rightarrow y\lbrack n\rbrack x[n]y[n]

来自各种应用领域的系统,它们的数学描述往往具有惊人的共性。就像我们设置月利率为1%或者5%的时候,我们只需要简单的改变月利率的设置就可以将我们的模型变的通用。

很多在实践中很重要的系统都可以准确地建模,但是像我们在问题二中见到的系统,尽管我们的系统特性是确定的,我们也可以用一下的方式求得系统的单位脉冲响应。

但是在输入不确定的情况下,我们仍然不能确定系统响应的结果。并且系统也不是我们熟悉的LTI系统,给我们的分析带来了很大的困难,但是由于确定了系统的特性,我们仍然可以采用极限模拟的方式来得到我们想要的结果。也由此明白一个特性确定的系统才是有研究的价值的。

参考文献

  1. 奥本海默.信号与系统[M].电子工业出版社:北京,2013:25.26

  2. 沈海军.蒙特卡罗模拟[EB/OL].https://baike.baidu.com/item/%E8%92%99%E7%89%B9%E5%8D%A1%E7%BD%97%E6%A8%A1%E6%8B%9F/5160083?fr=aladdin,2020-10-29.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
内容简介   本书从实践的角度出发,详细介绍3D游戏开发的高级技术,并具体描述了一个游戏引擎的构建过程。全书着重讨论三个主题:游戏开发的一般过程;实时渲染过程;角色动画。所有主题均围绕一个具体的游戏开发系统Fly3D SDK2.0加以介绍。   本书旨在为当今的三维游戏引擎技术提供一个综合的解决方案,使读者尽快地进入开发者角色,了解整个游戏的开发过程并初步具备游戏引擎开发能力。   本书适合作为高等院校相关专业的教学参考书,同时可供相关技术人员和游戏开发人员阅读。 编辑推荐   本书从实践的角度出发,详细介绍3D游戏开发的高级技术,并具体描述了一个游戏引擎的构建过程。全书着重讨论三个主题:游戏开发的一般过程;实时渲染过程;角色动画。所有主题均围绕一个具体的游戏开发系统Fly3D SDK2.0加以介绍。   本书旨在为当今的三维游戏引擎技术提供一个综合的解决方案,使读者尽快地进入开发者角色,了解整个游戏的开发过程并初步具备游戏引擎开发能力。   本书适合作为高等院校相关专业的教学参考书,同时可供相关技术人员和游戏开发人员阅读。 作者简介   Alan Watt 英国谢菲尔德大学计算机科学系讲师,是该校计算机图表学研究室主任,曾经编写过多本优秀著作,包括《3D计算机图形学》和《The Computer Lmage》。 Fabio Policarpo 工作在里约热内卢的软件开发者,他是Paralelo计算机公司的创始人,目前正致力于三维动作多玩家游戏的研究。 目录 出版者的话 专家指导委员会 译者序 前言 第一部分 高级游戏系统剖析 第1章 高级游戏系统剖析I:构造过程和静态光照 1.1 数据结构 1.1.1 顶点 1.1.2 面 1.1.3 包围盒 1.2 构造过程 1.2.1 从场景几何中创建BSP树 1.2.2 路径规划的凸体和PVS计算 1.2.3 处理复杂的地形 1.2.4 BSP叶节点中的面 1.2.5 寻找叶凸体 1.2.6 凸体和伪人口 1.2.7 潜在可视集 1.3 光照贴图的构造 1.3.1 生成光照贴图的坐标 1.3.2 光照贴图的打包 1.3.3 对光照贴图的解释 1.4 BSP管理 1.5 高级静态光照——辐射度 附录1.1 构造实践 附录1.2 辐射度理论基础 第2章 高级游戏系统剖析Ⅱ:实时处理 2.1 视见和BSP 2.1.1 生成视见约束体的面 2.1.2 远近裁剪面和视见约束体 2.2 照相机控制 2.3 使用BSP的基本碰撞检测和反弹 2.3.1 碰撞和BSP遍历 2.3.2 粒子,场景检测和反弹 2.4 特殊的碰撞检测和反弹 2.4.1 AABB的定义 2.4.2 AABB类的定义和静态成员的定义 2.4.3 碰撞检测和碰撞反弹 2.4.4 使用AABB的伪碰撞反弹 2.4.5 使用AABB的碰撞检测 2.4.6 AABB顶点与场景面相交 2.4.7 场景顶点与AABB面相交 2。4.8 AABB边与场景边相交 2.4.9 更精确的碰撞检测 2.4.10 使用碰撞阈值 2.5 基本的路径规划 附录2.1 实时处理的演示 第3章 高级游戏系统剖析Ⅲ:软件设计与应用编程 3.1 应用的种类 3.1.1 插件 3.1.2 前端 3.1.3 工具 3.2 Fly3D引擎体系结构 3.2.1 FlyMath 3.2.2 FlyDirectX 3.2.3 FlyRender 3.2.4 FlyEngine 附录3.1 编写一个插件 第二部分 实时渲染 第4章 实时渲染 4.1 简介 4.2 顶点、像素和贴图 4.2.1 基本的逐像素着色 4.2.2 着色和坐标空间 4.2.3 25年来主流的插值着色方法和颜色贴图 4.2.4 标量表示 4.3 因式分解法 4.3.1 使用因式分解着色模型的逐像素着色——各向同性模型 4.3.2 使用因式分解着色模型的逐像素着色——各向异性模型 4.4 BRDF和真实材质 4.5 使用BRDF进行逐像素着色 4.6 环境贴图参数化 4.6.1 环境贴图参数化:立方映射 4.6.2 环境贴图参数化:球面映射 4.6.3 环境贴图参数化:对偶抛物面贴图 4.6.4 环境贴图——可比点 4.6.5 立方贴图和向量规范化 4.7 实现BRDF:可分离的近似 4.8 着色语言和着色器 4.8.1 着色语言:简单的历史回顾 4.8.2 RenderMan着色语言 4.8.3 实时渲染的着色语言 第5章 实时渲染:实践 5.1 基本着色器 5.1.1 渲染状态 5.1.2 着色器排序 5.1.3 着色器类的实现 5.2 渲染状态 5.2.1 全局设定 5.2.2 局部设定 5.3 着色器实例 5.3.1 环境映射和铬映射效果——玻璃、金属和铬 5.3.2 移动发光告示牌

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值