2026a
# 代码生成与 FMU 支持
支持 Sysplorer 调用 SyslabFunction 组件的模型生成半物理仿真代码,以及导入/导出 FMU 功能。
提示
阅读本章前,请先阅读 Syslab 代码生成、Sysplorer 外部 C 语言集成、Sysplorer 半物理仿真接口工具等帮助文档。
# 概述
在通信领域,Algebraicinterleaver 函数常用于对输入数据序列重新排列,以增强通信系统对突发错误的抵抗能力,特别是在需要提高抗干扰能力或减小误码率的场景中。例如,在无线通信系统中,通过数据交织可以使数据在信道中更均匀地分布,从而提高抗多径衰落的能力。为了在系统建模中也能使用该算法函数,我们通过 SyslabFunction 将其封装为 Modelica 组件,并搭建了一个简单的示例模型用于验证 Algebraicinterleaver.mo。
仿真结果:
SyslabFunction 函数脚本:
using TyMathCore
function Algebraicinterleaver(data, num, type1, k, h)
num = Int64(num)
k = Int64(k)
h = Int64(h)
type1 = Int64(type1)
data_size = size(data)
if num != data_size[1]
error("num must equal the length of the sequence(s) in data")
end
int_table = zeros(Int64,num)
if type1 == 1#"takeshita-costello"
if !isa(k, Int64) || k >= num || k < 1
error("k must be positive integer and less then num")
end
if !isa(h, Int64) || h >= num || h < 0
error("h must be nonnegative integer and less then num")
end
if num != 2.0^round(log(num) / log(2))
error("number of elements must be a power of 2")
end
m = [0:(num - 1);]
c = rem.(k .* m .* (m .+ 1) ./ 2, num) .+ 1
d = [c[2:end]; c[1]]
v = sortperm(c)
int_table = Int64.(d[v])
if h > 0
# New indices based on Takeshita-Costello method
int_table = [int_table[(h + 1):end]; int_table[1:h]]
#int_table = circshift(int_table,-h)
end
else # 0"Welch-Costas"
alpha =k
if !isa(alpha, Int64) || alpha >= num
error("alpha must be integer and less then num")
end
temp_divisor = num + 1
# if isprime(temp_divisor)
# error("number of elements plus one must be prime")
# end
pf = nfactor(num)
z = alpha * ones(Int64,length(pf))
n = [2:pf[end];]
pfLen = length(pf)
m = [1:(2^pfLen - 2);]
np_tmp = Int64[]
#np = zeros(Int64,length(n)*pfLen)
for i in 1:lastindex(pf)
np_tmp = [np_tmp; Int64.(n .<= pf[i])]
#np[(i-1)*length(n)+1:i*length(n)] = Int64.(n .<= pf[i])
end
np = collect(reshape(np_tmp,length(n), pfLen)')
if length(np) == 0
temp = [0;;]
else
temp = np .* [1:pfLen;]
end
temp_len = sum(temp .!= 0; dims=1)
t=filter(!=(0),vec(temp))
y_ini = 0
for i in 1:floor(Int64,length(temp) / pfLen)
y_len = temp_len[i] + y_ini
t_ind = t[(y_ini + 1):y_len]
temp2 = z[t_ind] * alpha
z[t_ind] = temp2 .- (temp_divisor .* floor.(Int64,temp2 ./ temp_divisor))
y_ini = y_len
end
# Checks if the primitive element is valid
temp_xpf = rem.(floor.(Int64,m .* pow2([0:-1:(1 - pfLen);])'), 2) .* pf'
replace!(temp_xpf, 0 => 1)
xpp = prod(temp_xpf; dims=2)
temp_mx, temp_lx = findmax(temp_xpf; dims=2)
for i in 1:length(m)
prd = 1
lx = temp_lx[i]
limit = floor(Int64,xpp[i] / temp_mx[i])
for n in 1:limit
prd = mod(prd * z[lx[2]], temp_divisor)
end
if prd == 1
error("specified value is not a primitive element.")
end
end
y = ones(Int64,num)
for i in 2:num
y[i] = mod(y[i - 1] * alpha, num + 1)
end
# New indices based on Welch-Costas method
int_table = y
end
intrlved = intrlv_patch(data, int_table)
return intrlved
end
function nfactor(n)
fm = TyMathCore.factor(n)
nm = length(fm[1])
nmp = sum(fm[2])
temp = fm[1][1] * ones(fm[2][1])
if nm > 1
for i in 2:nm
temp = [temp; fm[1][i] * ones(fm[2][i])]
end
end
return Int.(temp)
end
function intrlv_patch(In,PermutationVector)
out = In[PermutationVector]
return out
end
Syslab 中测试数据:
data = [1, 2, 3, 4, 5, 6, 7, 8] # Example data array
num = length(data) # Length of the sequence(s) in data
type1 = 1 # Using Takeshita-Costello method
k = 3 # Parameter k
h = 2 # Parameter h
# Call the function
result = Algebraicinterleaver(data, num, type1, k, h)
# Print the result
println("Interleaved Result: ", result)
Syslab 中运行结果:
Interleaved Result: [7, 2, 1, 8, 6, 5, 4, 3]