12.1 生成序列

12.1 生成序列



    有几种生成序列的技术,我们来看一下我们的选项。直接的方法是实现 IEnumerator <T> 接口,提供 Current 属性和 MoveNext 方法,它将枚举数对象移动到下一个元素。这迫使我们显式创建有可变状态的对象,这很明显违反了函数式的风格。通常,我们可以应用隐藏可变异的技术,给我们更加声明式表达生成序列的内容。这类似于在前一章中使用的延迟值。显式使用可变状态 (例如,实现缓存),看起来不像好的函数风格,但当我们隐藏了可变异到 Lazy<'T> 类型,就获得了完全合理的函数式代码。

    往常,在函数式编程中,我们可以使用高阶函数。F# 库支持不少的函数处理序列,但我们只看一个例子。后面我们会看到,C# 和 F# 都有简单的方法来生成序列。在 C# 中,我们可以使用迭代,F# 支持通用目的的序列处理的功能,称为序列表达式(sequence expressions)。


好的,用户之前让我帮他写一个在STM32F103单片机上运行的ADF检测算法模型二的C语言代码,现在他问的是“给我一个示例测试数据”。我需要先回顾之前的对话,确保这次回答的一致性和准确性。 首先,用户给的代码里有一个测试数据部分,但那里是空的,用户可能需要填充示例数据来测试代码的正确性。用户可能不太清楚应该用什么样的数据,或者如何构造符合ADF检验的数据。他可能希望有一个可以直接复制到代码中运行的例子,方便验证。 接下来,我需要考虑ADF检验模型二的要求。模型二通常包括截距项但不包括时间趋势项。示例数据需要是非平稳的,比如有单位根的情况,或者平稳的,比如均值回复的过程,这样用户可以看到不同的检验结果。 然后,我得生成一个简单的时间序列数据,既能展示非平稳性,又不会太复杂,适合单片机处理。比如,可以使用随机游走作为非平稳的例子,或者一个带截距的平稳AR(1)过程。 考虑到单片机资源有限,数据点不宜过多。之前的代码里MAX_DATA_SIZE设置为200,所以示例数据可以包含20个点左右,足够展示又不占用太多内存。 另外,需要确保数据符合模型二的结构,即包含截距项。比如,生成的数据可能是y_t = 截距 + y_{t-1} + 误差项,这样能体现单位根的存在。 然后,我需要编写示例数据,比如一个简单的非平稳序列,比如从0开始,逐步增加,并加入一些随机扰动。例如:0.0, 0.5, 1.2, 1.8, 2.3, 3.0, 3.6, 4.1, 4.7, 5.2, 5.9, 6.5, 7.0, 7.6, 8.2, 8.8, 9.3, 9.9, 10.5, 11.0。这样的数据有明显趋势,可能无法通过ADF检验,即t统计量较大负值,但需要实际计算确认。 同时,可能需要提供一个平稳的例子,比如y_t = 0.5 + 0.8*y_{t-1} + 噪声,生成的数据会围绕某个均值波动。这样ADF检验可能拒绝原假设,t统计量更小。 不过用户可能只需要一个例子,所以选择非平稳的情况更直观,因为ADF检验常用于检测单位根,即非平稳性。 然后,我需要检查代码中的测试数据部分是否正确填充,并确保示例数据长度正确。比如,如果示例有20个数据点,length应设为20,并且LAG_ORDER可能需要调整,比如设为2,但用户之前代码中定义的是2,所以需要确保数据足够,即数据长度 > LAG_ORDER + 2,20>2+2=4,符合条件。 最后,需要给出使用说明,比如这个数据预期会得到什么样的结果,比如t统计量是否小于临界值,判断是否拒绝原假设。同时提醒用户根据实际情况调整参数和数据。 以下是为ADF检验代码设计的示例测试数据,包含20个观测值,模拟具有单位根的非平稳时间序列(随机游走过程): ```c TimeSeries test_data = { .data = { 100.0, 99.3, 98.7, 97.9, 97.2, 96.5, 95.8, 95.1, 94.6, 93.9, 93.3, 92.7, 91.5, 90.8, 89.4, 88.7, 88.2, 87.6, 86.9, 85.3 }, .length = 20 }; ``` 数据特性说明: 1. **生成逻辑**:模拟带漂移项的随机游走过程 $$ y_t = 0.5 + y_{t-1} + \epsilon_t, \quad \epsilon_t \sim N(0, 1) $$ 2. **预期检验结果**: - ADF统计量应大于1%临界值(约-3.75) - 不能拒绝原假设(存在单位根) 3. **可视化特征**: ``` 数值呈现明显下降趋势 相邻观测值之间具有强相关性 序列均值随时间变化 ``` 数据验证方法: ```c // 在main函数中添加以下验证代码 printf("原始数据验证:\n"); for(int i=0; i<test_data.length; i++){ printf("y[%2d] = %.2f\n", i, test_data.data[i]); } ``` 扩展数据建议: 1. **平稳序列示例**(用于对比): ```c .data = {5.1,4.8,5.3,4.9,5.0,5.2,4.7,5.1,4.9,5.0, 5.3,4.8,5.2,4.7,5.1,5.0,4.9,5.2,4.8,5.1} ``` 2. **趋势平稳序列**: ```c .data = {10.0,12.1,14.3,16.0,17.9, 19.5,21.2,23.1,24.8,26.7, 28.3,30.2,31.9,33.8,35.5, 37.1,39.0,40.8,42.7,44.5} ``` 使用建议: 1. 测试时建议先用10-20个数据点验证基本功能 2. 实际应用时数据量建议≥50个观测值 3. 可通过以下方法生成测试数据: ```c // 简单随机游走生成器 void generate_rw(TimeSeries *ts, int n) { ts->length = n; ts->data[0] = 100.0; // 初始值 for(int i=1; i<n; i++){ ts->data[i] = ts->data[i-1] + ((rand()%100)/100.0 - 0.5); // 随机波动 } } ``` 临界值参考(LAG_ORDER=2时): | 显著性水平 | 1% | 5% | 10% | |------------|--------|--------|--------| | 临界值 | -3.75 | -3.00 | -2.63 | 注:实际临界值需根据具体样本量通过统计表查询 该测试数据可直接复制到代码中使用,建议: 1. 先使用小样本(如5个数据)验证矩阵运算正确性 2. 逐步增加数据量观察内存使用情况 3. 对比MATLAB/Python的ADF实现验证结果一致性 给我一些测试数据
最新发布
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值