Closed
Description
Good afternoon.
Bug description
The error lies in incorrect code generation. When generating and trying to reproduce the function, which I will describe below.
Minimum (non-)working example
fis = @mamfis function tipper(delta_p)::control_signal
delta_p := begin
domain = -50000.0:50000.0
very_high = SigmoidMF(0.005, 17000.0)#GaussianMF(17000.0, 3000.0) # Очень высокое давление
high = GaussianMF(15000.0, 4120.0) # Высокое давление
moderate = GaussianMF(-6000.0, 3000.0) # Нормальное давление
low = GaussianMF(-15000.0, 3000.0) # Низкое давление
very_low = ZShapeMF(-40000.0, -20000.0)#GaussianMF(-30000.0, 3000.0) # Очень низкое давление
end
control_signal := begin
domain = 0.0:0.005
fully_closed = TriangularMF(0.00000000001, 0.00000001, 0.000001) # Полностью закрытая заслонка
partially_closed = TriangularMF(0.0000009, 0.000005, 0.00001) # Частично закрытая заслонка
neutral = TriangularMF(0.00001, 0.00002, 0.0003) # Нейтральное положение (половина открыта)
partially_open = TrapezoidalMF(0.0003, 0.0009, 0.003, 0.0044) # Частично открытая заслонка
fully_open = TriangularMF(0.004, 0.0047, 0.005) # Полностью открытая заслонка
end
# Работающие правила
delta_p == very_high --> control_signal == fully_open
delta_p == high --> control_signal == partially_open
delta_p == moderate --> control_signal == neutral
delta_p == low --> control_signal == partially_closed
delta_p == very_low --> control_signal == fully_closed
end
asd = compilefis(fis)
The result is a function:
:(function tipper(delta_p)
very_high = 1 / (1 + exp(-0.005 * (delta_p - 17000.0)))
high = exp(-((delta_p - 15000.0) ^ 2) / 3.39488e7)
moderate = exp(-((delta_p - -6000.0) ^ 2) / 1.8e7)
low = exp(-((delta_p - -15000.0) ^ 2) / 1.8e7)
very_low = if delta_p <= -40000.0
one(float(Symbol))
elseif delta_p >= -20000.0
zero(float(typeof(delta_p)))
elseif delta_p >= -30000.0
5.0e-9 * (delta_p - -20000.0) ^ 2
else
1 - 5.0e-9 * (delta_p - -40000.0) ^ 2
end
ant1 = very_high
ant2 = high
ant3 = moderate
ant4 = low
ant5 = very_low
control_signal_agg = collect(LinRange{Float64}(0.0, 0.005, 101))
@inbounds for (i, x) = enumerate(control_signal_agg)
fully_closed = max(min((x - 1.0e-11) / 9.99e-9, (1.0e-6 - x) / 9.9e-7), 0)
partially_closed = max(min((x - 9.0e-7) / 4.1000000000000006e-6, (1.0e-5 - x) / 5.0e-6), 0)
neutral = max(min((x - 1.0e-5) / 1.0e-5, (0.0003 - x) / 0.00028), 0)
partially_open = max(min((x - 0.0003) / 0.0006000000000000001, 1, (0.0044 - x) / 0.0014000000000000002), 0)
fully_open = max(min((x - 0.004) / 0.0007000000000000001, (0.005 - x) / 0.0002999999999999999), 0)
control_signal_agg[i] = max(max(max(max(min(ant1, fully_open), min(ant2, partially_open)), min(ant3, neutral)), min(ant4, partially_closed)), min(ant5, fully_closed))
end
control_signal = ((2 * sum((mfi * xi for (mfi, xi) = zip(control_signal_agg, LinRange{Float64}(0.0, 0.005, 101)))) - first(control_signal_agg) * 0.0) - last(control_signal_agg) * 0.005) / ((2 * sum(control_signal_agg) - first(control_signal_agg)) - last(control_signal_agg))
return control_signal
end)
After defining this function, I passed a vector through it and got an error, which is that an attempt is being made to convert a Symbol type value to a number, which is impossible:
MethodError: no method matching AbstractFloat(::Type{Symbol})
Closest candidates are:
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
@ Base char.jl:50
(::Type{T})(::SymbolicUtils.Symbolic) where T<:Union{AbstractFloat, Integer, Complex{<:AbstractFloat}, Complex{<:Integer}}
@ Symbolics /usr/local/julia-1.9.3/packages/Symbolics/VIBnK/src/Symbolics.jl:146
(::Type{T})(::Base.TwicePrecision) where T<:Number
@ Base twiceprecision.jl:266
Maybe you should make sure that something else is used during code generation, for example, use one(Float64) or one(0.0).
Expected behavior
I would like the function to work without errors
Version info
FuzzyLogic v0.1.2
Related issues
Maybe you should make sure that something else is used during code generation, for example, use one(Float64) or one(0.0).