MF-DFA算法Matlab转Julia实现的RMS嵌套数组存储问题
解决方案
核心错误原因
- 你在每次
ns迭代的循环内部重新初始化了全局RMS数组,之前迭代的计算结果被直接覆盖,所以最终只有最后一个scale的结果被保留,其余位置都是初始值0。 - 你用固定维度的二维数组存储不同长度的RMS结果,逻辑和Matlab元胞数组不匹配。Julia中对应Matlab可变长度元胞数组的结构是嵌套向量(Vector of Vectors),每个元素可以是任意长度的一维数组。
修改后代码
using DelimitedFiles, TimeSeries, Plots, StatsBase using Polynomials, LinearAlgebra, CSV, DataFrames # 数据读取与预处理 sp500 = CSV.read("sp500_Nasdaq.csv", DataFrame) sp500_V = values(sp500[:,2]) SP1 = cumsum(sp500_V .- mean(sp500_V)) SP1_Ord = sqrt(mean(SP1.^2)) X = SP1 # 一阶多项式拟合函数 function polyfit(xVals,yVals) n = length(xVals) xBar, yBar = mean(xVals), mean(yVals) sXX = sum((xVals.-xBar).^2) sXY = dot(xVals.-xBar, yVals.-yBar) b1A = sXY/sXX b0A = yBar - b1A*xBar return b0A, b1A end # 超参数定义 scales = [16,32,64,128,256,512,1024] q = [-5,-3,-1,0,1,3,5] n_scale = length(scales) n_q = length(q) # 初始化嵌套数组存储RMS,完全对应Matlab的元胞数组结构 RMS = Vector{Vector{Float64}}(undef, n_scale) Fq = zeros(n_q, n_scale) # 主循环(移除所有不必要的global声明,避免变量覆盖问题) for ns in 1:n_scale seg_num = floor(Int, length(X)/scales[ns]) # 初始化当前scale对应的RMS向量 RMS[ns] = zeros(seg_num) for v in 1:seg_num idx = ((v-1)*scales[ns] + 1):(v*scales[ns]) C = polyfit(idx, X[idx]) fit_val = Polynomial(C).(idx) RMS[ns][v] = sqrt(mean((X[idx] .- fit_val).^2)) end # 计算各阶q对应的Fq值 for nq in 1:n_q q_val = q[nq] if q_val == 0 Fq[nq, ns] = exp(0.5*mean(log.(RMS[ns].^2))) else Fq[nq, ns] = mean(RMS[ns].^q_val)^(1/q_val) end end end
结果验证
运行后得到的RMS是长度为7的嵌套向量,其中RMS[1]长度为159、RMS[2]长度为79、RMS[3]长度为39、RMS[4]长度为19、RMS[5]长度为9、RMS[6]长度为4、RMS[7]长度为2,和Matlab的输出结构完全一致。
内容的提问来源于stack exchange,提问作者utello10
相关产品推荐
相关产品推荐

