Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]Possible error in code generation. #38

Closed
mishanya96 opened this issue Sep 18, 2024 · 1 comment · Fixed by #39
Closed

[bug]Possible error in code generation. #38

mishanya96 opened this issue Sep 18, 2024 · 1 comment · Fixed by #39
Labels
bug Something isn't working

Comments

@mishanya96
Copy link

mishanya96 commented Sep 18, 2024

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:
image

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).

@lucaferranti
Copy link
Owner

Thanks! There was a bug in the julia code gneeration of Z- and S-shaped membership functions! #39 fixes that! I will make a release after merging that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants