Modelica - 增量不符合条件(Modelica - Increment doesn't follow conditions)
我在Wolfram System Modeler中创建了一个Max Per Interval块。
为了便于我解释,我只需将Max值设置为10。
block HighWaterMarkPerInterval extends Modelica.Blocks.Interfaces.SISO; protected Integer index; Real currentMax; Real endTimes[1, 45] = [30812532.2, 32037805, 33265581.8, 34493233.8, 35720861.5, 36948483, 38176307.7, 39426940.6, 40654485.4, 41882212.1, 43109672.7, 44337076, 45564265.7, 46793039.6, 48045130.9, 50749960.3, 52040090.6, 53558507.7, 54814537.3, 56331978.2, 57587753.3, 59105952.9, 60362517.8, 61879307.8, 63136031.5, 64363411.4, 65590464.3, 67738027.40000001, 84725789.8, 87831338.09999999, 89030965.40000001, 90258821.8, 91486663.5, 92714210.3, 93941727.7, 95166770.3, 97283519, 99434222.90000001, 100658067.1, 102807019, 104030032.7, 106179193, 107402090, 109550214.2, 110771545.3]; algorithm if endTimes[1, index] < time then index := pre(index) + 1; currentMax := 0; else currentMax := 10; // Constant to until I get logic working end if; initial algorithm index := 0; equation y = currentMax; end HighWaterMarkPerInterval;
运行时,索引会立即增加到无穷大。 我认为我的逻辑有问题,但我无法理解。
代码应该检查我们是否仍然处于间隔时间,当我们跨越到下一个间隔时间时,它将“currentMax”值设置为零。 这将重置我在另一个块中实现的Max值。
任何帮助,将不胜感激。 谢谢。
编辑:代码部分表单示例。
model HighWaterMarkPerInterval annotation(Diagram(coordinateSystem(extent = {{-148.5, -105}, {148.5, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5}))); extends Modelica.Blocks.Interfaces.SISO; Modelica.Blocks.Math.Max maxblock(u1 = currentMax, u2 = u); Real flybyEnds[1, 45] = [30813151,32038322,33266015, truncated for space saving...]; Integer index; Real currentMax; initial equation index = 1; currentMax = 0; algorithm // When we are in the interval continually grab max block output and output currentMax when {time>=flybyEnds[1, index-1], time <=flybyEnds[1,index]} then currentMax := pre(maxblock.y); y := currentMax; end when; // When we move to the next interval reset current max and move to the next interval when time > flybyEnds[1, index] then currentMax := 0; index := pre(index) + 1; end when; end HighWaterMarkPerInterval;
I am creating a Max Per Interval block in Wolfram System Modeler.
To make it easy for me to explain, I just set the Max value to 10.
block HighWaterMarkPerInterval extends Modelica.Blocks.Interfaces.SISO; protected Integer index; Real currentMax; Real endTimes[1, 45] = [30812532.2, 32037805, 33265581.8, 34493233.8, 35720861.5, 36948483, 38176307.7, 39426940.6, 40654485.4, 41882212.1, 43109672.7, 44337076, 45564265.7, 46793039.6, 48045130.9, 50749960.3, 52040090.6, 53558507.7, 54814537.3, 56331978.2, 57587753.3, 59105952.9, 60362517.8, 61879307.8, 63136031.5, 64363411.4, 65590464.3, 67738027.40000001, 84725789.8, 87831338.09999999, 89030965.40000001, 90258821.8, 91486663.5, 92714210.3, 93941727.7, 95166770.3, 97283519, 99434222.90000001, 100658067.1, 102807019, 104030032.7, 106179193, 107402090, 109550214.2, 110771545.3]; algorithm if endTimes[1, index] < time then index := pre(index) + 1; currentMax := 0; else currentMax := 10; // Constant to until I get logic working end if; initial algorithm index := 0; equation y = currentMax; end HighWaterMarkPerInterval;
When ran, index increments to infinity right off the bat. I figure there is something wrong with my logic, but I can't figure it.
The code is supposed to check to see if we are still in the interval time, and when we cross over into the next interval time it sets the "currentMax" value to zero. Which will reset the Max value I've implemented in another block.
Any help would be appreciated. Thanks.
EDIT: Code section form example.
model HighWaterMarkPerInterval annotation(Diagram(coordinateSystem(extent = {{-148.5, -105}, {148.5, 105}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5}))); extends Modelica.Blocks.Interfaces.SISO; Modelica.Blocks.Math.Max maxblock(u1 = currentMax, u2 = u); Real flybyEnds[1, 45] = [30813151,32038322,33266015, truncated for space saving...]; Integer index; Real currentMax; initial equation index = 1; currentMax = 0; algorithm // When we are in the interval continually grab max block output and output currentMax when {time>=flybyEnds[1, index-1], time <=flybyEnds[1,index]} then currentMax := pre(maxblock.y); y := currentMax; end when; // When we move to the next interval reset current max and move to the next interval when time > flybyEnds[1, index] then currentMax := 0; index := pre(index) + 1; end when; end HighWaterMarkPerInterval;
原文:https://stackoverflow.com/questions/28372249
最满意答案
您可以使用以下内容完成整个过程(我认为):
n = 0:100; pn = (25*n.^2 - 23*n)/2; sumadetres = unique(bsxfun(@plus, pn, pn')); sumadetres = unique(bsxfun(@plus, sumadetres, pn));
函数
bsxfun
在MATLAB中对于像这样的向量化操作非常有用。 您可以在此处阅读文档 。 基本上,bsxfun
为您提供了在两个向量之间执行逐元素二元运算的有效方法。上面使用
bsxfun
的第一个表达式将pn'
的每个值都添加到pn'
每个值,并创建结果的矩阵。 通过使用unique
函数,您只能存储此矩阵中的唯一值。 然后使用bsxfun
的第二个表达式将pn
每个值添加到第一个表达式的唯一结果向量中。 结果应该是pn(n) + pn(m) + pn(l)
的所有唯一组合的向量。通常,在MATLAB中,使用内置向量化函数比使用循环快得多。 如果你在C ++等中做了很多编程,这是违反直觉的,但这是因为MATLAB是一种解释语言,基本上使用内置的矢量化函数会产生更高效的在处理器上执行的实际代码。 很奇怪,你想避免在MATLAB中循环。
You can do the whole thing with the following (I think):
n = 0:100; pn = (25*n.^2 - 23*n)/2; sumadetres = unique(bsxfun(@plus, pn, pn')); sumadetres = unique(bsxfun(@plus, sumadetres, pn));
The function
bsxfun
is really helpful in MATLAB for vectorized operations like this. You can read the documentation here. Basicallybsxfun
gives you an efficient way of performing element-wise binary operations between two vectors.The first expression using
bsxfun
in the above adds every value ofpn'
to every value ofpn
and creates a matrix of the results. By using theunique
function, you only store unique values from this matrix. The second expression usingbsxfun
then adds every value ofpn
to this vector of unique results from the first expression. The result should be a vector of all unique combinations ofpn(n) + pn(m) + pn(l)
.In general, in MATLAB, using built in vectorization functions is a lot faster than using loops. This is counterintuitive if you have done much programming in C++ and the like, but it is because MATLAB is an interpreted language and basically using the built in vectorized functions results in more efficient actual code that is executed on the processor. Weird as it is, you want to avoid loops in MATLAB.
相关问答
更多-
在我看来,如果你不关心彼此绘制点和线,那么这个问题就很容易了。 以下就像罪恶一样丑陋,主要是因为使用了仅仅fullcircle scaled来定义点,但它有效: beginfig(1); pair right, nright; u:=1cm; right:=(u,0); path p,q,dot,seg; dot:=fullcircle scaled (u/2); seg:=(0,0)-- (dot shifted right); for N=1 upto 6: p:=dot; nright:=(N*u ...
-
OpenGL的多边形渐变(Polygonal gradients with OpenGL)[2021-11-14]
您可能拥有的一个选项是渲染一个带有渐变的简单多边形到纹理,然后使用该多边形来纹理实际的多边形。 然后,您可以旋转源多边形,任何纹理其图像的内容都将使其渐变旋转,而不会更改实际几何体。 One option you may have is to render a simple polygon with a gradient to a texture, which you then use to texture your actual polygon. Then you can rotate the sourc ... -
这是至少大部分通过sf解决方案的途径。 在这里,我们利用包的仿射变换能力,只需要复制一个八边形和一个正方形组成的拼贴。 我借用并修改了八角形函数来制作一个快速八角形。 显然,这将创建一个倾斜的网格,如图所示,但对绘图函数的一些修改可以按任何方向细分单元。 关键在于通过将c(x, y)到您的sfc对象来为下一个图块指定正确的转换。 对于某些背景, sf将点和线存储为2列矩阵,将多边形存储为矩阵列表。 这就是为什么在st_polygon有一个list调用list 。 library(sf) #> Linking ...
-
BRep通常是指实体表面定义为原始(平面,圆柱形,圆锥形,球形,环形)或Nurbs表面,而多边形网格表面始终是平面的(大部分时间,三角形)。 BRep commonly refers to solid with faces defined as primitive (planar, cylindrical, conical, spherical, toroidal) or Nurbs surfaces while for polygonal meshes faces are always planar (m ...
-
如何在iOS上以编程方式自定义多边形框架视图?(How to programmatically customize a polygonal frame view on iOS? [closed])[2021-09-15]
不,iOS中的所有视图都有一个矩形框架。 No, all views in iOS have a rectangular frame. -
我找到了一个更好的解决方案: 使二进制blob 变得有趣 通过追踪像素线和分支点来构建骨架图 (无周期) 获取从每个末端节点到所有其他末端节点的所有最短路径并取最长路径(大约是blob的开始和结束) 从一端节点(度数= 1)到另一端节点的最终路径是蠕虫中线的近似值。 如果有人对解决方案感兴趣,我可能会共享一个python笔记本。 最终结果:绿色=最终中线图,深绿色=最终中线 斯凯尔顿的图表 源代码 : 这个问题的代码可以在这里找到: https : //github.com/gabyx/WormAnalys ...
-
我认为这是画布的高级用法。 您必须了解基础知识,如何绘制,如何使用图层,如何操作像素。 只需要谷歌搜索教程。 假设你知道前一个,我会试一试。 我以前从未这样做过,但我有一个想法: 你需要3个画布: 包含图片的图片(图片大小) 用户绘制选择形状的图层(图片的大小,在第一个画布的顶部) 一个结果画布,将包含你的裁剪图片(相同的大小,这个不需要显示) 当用户点击你的图片时:实际上,他点击图层,图层被清除并开始换行。 当他再次点击它时,会绘制上一个开始的行,另一个开始,等等......你一直这样做,直到你点击一个非 ...
-
Matlab,多边形数字(Matlab, Polygonal numbers)[2023-10-19]
您可以使用以下内容完成整个过程(我认为): n = 0:100; pn = (25*n.^2 - 23*n)/2; sumadetres = unique(bsxfun(@plus, pn, pn')); sumadetres = unique(bsxfun(@plus, sumadetres, pn)); 函数bsxfun在MATLAB中对于像这样的向量化操作非常有用。 您可以在此处阅读文档 。 基本上, bsxfun为您提供了在两个向量之间执行逐元素二元运算的有效方法。 上面使用bsxfun的第一个 ... -
这是一个强大而缓慢的方法: 从质心偏移一个边界框的角(强制在关闭的多边形网格外面保证它),然后创建一个从该网格到网格上任何三角形中心点的线段。 测量该线段与三角形法线之间的角度。 将该线段与网格的每个三角形面相交(包括用于生成线段的三角形)。 如果存在奇数个交叉点,则法线和线段之间的角度应<180。 如果有偶数,则应该大于180。 如果有偶数个交叉点,则数字应该颠倒。 这应该适用于非常复杂的表面,但是它们必须关闭,否则它会崩溃。 This is a robust, but slow way to get t ...
-
你需要一些矢量数学才能做到这一点。 创建描述对象应移动的路径的点列表,然后计算描述从当前位置到目标位置的方向的向量。 然后使用该向量移动对象。 一旦你击中目标,瞄准下一个移动点。 这是一个例子: import pygame import math from itertools import cycle # some simple vector helper functions, stolen from http://stackoverflow.com/a/4114962/142637 def magnit ...