gpt4 book ai didi

modelica - Modelica 中的正则化

转载 作者:行者123 更新时间:2023-12-04 14:07:03 27 4
gpt4 key购买 nike

我想知道是否有其他正则化技术(例如双曲正切)而不是 smoothStep函数存在于 Modelica 中。我处理我使用的复杂代码 smoothStep几次以避免在我的模型中喋喋不休;但是,我已经在我的模型结果中看到了这个函数的一些副作用,我宁愿采用其他技术。为了更清楚地说明,我只包含了一部分代码,如下所示:

model MassFlow
import Modelica.SIunits.MassFlowRate;
import Modelica.Media.Common.smoothStep;
Real c1[15];
parameter MassFlowRate mDotSource[15]={0.00,-0.10,0.10,1.00,2.00,0.00,0.10,0.01,0.09,-0.20,-0.30,0.00,-0.10,-0.03,0.06};

parameter MassFlowRate smallFlow = 0.01 "Small flow value used to avoid chattering problems";
equation
c1 = smoothStep(mDotSource, 1, 0, smallFlow);
end MassFlow;

因此,目标是对 mDotSource 的正则化进行更精确的近似.如果您能帮助我,我将不胜感激。

根据@matth 的有用评论,我使用了 spliceFunction。为了在输入负值时返回 0,我修改了 spliceFunction 如下:

function spliceFun "Spline interpolation of two functions"
extends Modelica.Icons.Function;
input Real pos "Returned value for x-deltax >= 0";
input Real neg "Returned value for x+deltax <= 0";
input Real x "Function argument";
input Real deltax=1 "Region around x with spline interpolation";
output Real out;
protected
Real scaledX;
Real scaledX1;
Real y;
algorithm
scaledX1 := x/deltax;
scaledX := scaledX1*Modelica.Math.asin(1);
if scaledX1 <= -0.00000001 then
y := 0;
elseif scaledX1 >= 0.999999 then
y := 1;
else
y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1)/2;
end if;
out := pos*y + (1 - y)*neg;
annotation (derivative=spliceFun_der);
end spliceFun;

正如所见,当 scaledX1 <= -0.00000001 时只有“if 语句”与原来的 spliceFunction 相比发生了变化。它在示例输入数据 (mDotSource) 上正常工作:

model MassFlow
import Modelica.SIunits.MassFlowRate;

parameter MassFlowRate mDotSource[15]={0.00,-0.10,0.20,1.00,2.00,0.00,0.10,0.01,0.09,-0.20,-2.0,0.00,-0.10,-0.03,-0.8};
Real c1[15];

equation
c1 = SHCLibrary.Tests.spliceFun(1,0,mDotSource,1);

end MassFlow;

但是,当我尝试在我的复杂代码中应用修改后的 spliceFunction (spliceFun) 时,模拟运行是无休止的。它既不停止也不给出错误。我必须在这里补充一点,在我的复杂代码中,我使用了 6 倍的 spliceFun,当我用 smoothStep 替换其中的 5 个时功能并仅使用 1 个 spliceFun,它可以工作,但我没有收到我期望的准确结果。
你能就这个问题提出建议吗?

最佳答案

您可以使用除 spliceFun 之外的其他一些正则化,但有两个要求:

  • 边缘光滑
  • 正确的导数

如果我们查看您的函数,我们会发现 scaledX1=0 给出 y=0,而 scaledX1=1 给出 y=1;这很好,但是如果我们查看正则化分支中的 scaledX,我们有:

(Modelica.Math.tanh(Modelica.Math.tan(scaledX1*asin(1))) + 1)/2;

对于 scaledX1=0 给出 y=0.5,对于 scaledX1=1 给出 y=1;根本不规则,0 处的斜率不是 0。基本上看起来你有一个转变,你想要这样的东西:

scaledX := (scaledX1-0.5)*Modelica.Math.asin(1);
...
y:= Modelica.Math.tan(scaledX)) + 1)/2;

因此 scaledX1=0 给出 scaledX=-0.5*Modelica.Math.asin(1) 从而给出 y=0,但是不幸的是边缘处没有零导数。使用 tanh 它变得更加困惑,但仍然要求 scaledX=0 和 1 的限制应该匹配。

是用的idea

   scaledX := (2*scaledX1-1)*Modelica.Math.asin(1);
...
y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1)/2;

好像边是在-1 和1 而不是0 和1?这个变体似乎从 0 到 1,并且在过渡时很平滑。

第二部分很容易通过编写来更正:annotation (smoothOrder=2); 而不是尝试编写派生词。

关于modelica - Modelica 中的正则化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67736666/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com