用ezunits和if-sale
可悲的是,我在Ezunits上遇到了麻烦,并再次策划。 这次与if-CARE相结合。 这起作用,但可能没有应有的作用:
/*just works*/
M_K1q(n):= if n <= 500 then 0
else (n-500)^2/20000;
wxdraw2d(explicit(qty(M_K1q(n)), n, 0, 1500));
/*kinda works*/
M_L(n):= (10+n/100`minute)`N*m; /*doesn't*/
M_L(n):= (10+(n`minute)/100)`N*m; /*doesn't*/
M_L(n):= (10`N*m)+n/100`N*m*minute; /*works*/
wxdraw2d(explicit(qty(M_L(n)), n, 0, 1500));
/*but both work that way*/
M_L(n):= (10+n/100`minute)`N*m;
M_L(n):= (10+(n`minute)/100)`N*m;
wxdraw2d(explicit(qty(qty(M_L(n))), n, 0, 1500));
但是对于单位,我无法绘制它,尝试了许多变体:
M_K1(n):= block(
(if qty(n) <= 500 then 0
else ((n`minute)-500)^2/20000)`N*m
);
M_K1(99`1/minute); /*works*/
wxdraw2d(explicit(qty(M_K1(n)), n, 450, 600)); /*doesn't*/
输入n
应该在1/minune
中,输出应应BE n*m
。 看起来qty()
无法正常工作,因为单元未完全删除:
draw2d (explicit): non defined variable in term: 5.0*10^-5*((realpart(501.7241379310345 ` minute)-500.0)^2-1.0*imagpart(501.7241379310345 ` minute)^2)
-- an error. To debug this try: debugmode(true);
2022-05-29编辑:
是的,使用qty()需要输入n
在1/分钟
中,如果图形和求解可以工作,这将是可接受的解决方法。
该死的,我尝试了很多版本。 那是在0
上没有单位的一个,因为它是“全局”:
M_K1(n):= (if n <= 500`1/minute then 0
else (n`minute-500)^2/20000)`N*m;
最后一个也不起作用吗?
(%i102) M_K1(1000`1/minute);
(%o102) 25/2 ` N*m
(%i108) M_K1(2.5`1/s);
(%o108) 0 ` N*m
(%i111) M_K1((1000/60)`1/s)``N*m;
(%o111) (50/3 ` minute/s-500)^2/20000 ` N*m
绘制图形需要一两分钟,然后崩溃:
(%i24) wxdraw2d(explicit(qty(M_K1(n)), n, 450, 600));
draw2d (explicit): non defined variable in term:
realpart(if 455.1724137931034<=500.0 ` 1/minute then 0.0 else 5.0*10^-5*(455.1724137931034 ` minute-500.0)^2)
-- an error. To debug this try: debugmode(true);
不应该起作用吗?
它看起来正确,但是使用您的:
M_K2(n):=if n <= 500 ` 1/minute then 0 ` N*m
else (n-500 ` 1/minute)^2/(45000 ` 1/(kg*m^2));
我得到:
(%i40) M_K2(1000`1/minute)``N*m;
(%o40) 1/648 ` N*m
那不对!
(%i78) M_K2(n):= if n <= 500`1/minute then 0`N*m
else (n`minute-500)^2/45000`N*m;
(%o78) M_K2(n):=if n<=500 ` 1/minute then 0 ` N*m else (n ` minute-500)^2/45000 ` N*m
(%i79) M_K2(1000`1/minute);
(%o79) 50/9 ` N*m
更像是这样。
另外,它应该可以解决:
(%i69) res: dimensionally(solve(M_K2(n) = 10`N*m, n)); n_K2P2: rhs(res[1])``1/minute; float(%);
(%o67) [(if n<=500 ` 1/minute then 0 ` N*m else (n^2 ` N*m*minute^2+(-1000*n) ` N*m*minute+250000 ` N*m)/45000)=10 ` N*m]
(%o68) (600*kg*m^2)/s ` 1/minute
(%o69) (600.0*kg*m^2)/s ` 1/minute
应该看起来像这样:
(%i86) res: dimensionally(solve(M_K2(n) = 10`N*m, n)); n_K2P2: rhs(res[2])``1/minute; float(%);
(%o84) [n=(500-12*5^(5/2)) ` 1/minute,n=(12*5^(5/2)+500) ` 1/minute]
(%o85) (12*5^(5/2)+500) ` 1/minute
(%o86) 1170.820393249937 ` 1/minute
如果我有一件事有效,另一件事就会断裂。下一个后看起来像一个边缘案例。
Sadly I'm having trouble with ezunits and plotting again.
This time in combination with if-clause.
This works, but probably not as it should:
/*just works*/
M_K1q(n):= if n <= 500 then 0
else (n-500)^2/20000;
wxdraw2d(explicit(qty(M_K1q(n)), n, 0, 1500));
/*kinda works*/
M_L(n):= (10+n/100`minute)`N*m; /*doesn't*/
M_L(n):= (10+(n`minute)/100)`N*m; /*doesn't*/
M_L(n):= (10`N*m)+n/100`N*m*minute; /*works*/
wxdraw2d(explicit(qty(M_L(n)), n, 0, 1500));
/*but both work that way*/
M_L(n):= (10+n/100`minute)`N*m;
M_L(n):= (10+(n`minute)/100)`N*m;
wxdraw2d(explicit(qty(qty(M_L(n))), n, 0, 1500));
But with units I cannot plot it, have tried many variations of it:
M_K1(n):= block(
(if qty(n) <= 500 then 0
else ((n`minute)-500)^2/20000)`N*m
);
M_K1(99`1/minute); /*works*/
wxdraw2d(explicit(qty(M_K1(n)), n, 450, 600)); /*doesn't*/
Input n
should be in 1/minute
and output should be N*m
.
Looks like qty()
isn't working properly, since the units weren't removed completely:
draw2d (explicit): non defined variable in term: 5.0*10^-5*((realpart(501.7241379310345 ` minute)-500.0)^2-1.0*imagpart(501.7241379310345 ` minute)^2)
-- an error. To debug this try: debugmode(true);
2022-05-29 EDIT:
Yes, using qty() would require entering n
in 1/minute
, which would be an acceptable workaround, if graphs and solving would work.
Damn it, I tried so many versions.
That's the one with no unit at the 0
because it's "global":
M_K1(n):= (if n <= 500`1/minute then 0
else (n`minute-500)^2/20000)`N*m;
Shouldn't the last one also work?
(%i102) M_K1(1000`1/minute);
(%o102) 25/2 ` N*m
(%i108) M_K1(2.5`1/s);
(%o108) 0 ` N*m
(%i111) M_K1((1000/60)`1/s)``N*m;
(%o111) (50/3 ` minute/s-500)^2/20000 ` N*m
Drawing graphs with that takes a minute or two and then crashes:
(%i24) wxdraw2d(explicit(qty(M_K1(n)), n, 450, 600));
draw2d (explicit): non defined variable in term:
realpart(if 455.1724137931034<=500.0 ` 1/minute then 0.0 else 5.0*10^-5*(455.1724137931034 ` minute-500.0)^2)
-- an error. To debug this try: debugmode(true);
Shouldn't it work though?
It looks correct, but using your:
M_K2(n):=if n <= 500 ` 1/minute then 0 ` N*m
else (n-500 ` 1/minute)^2/(45000 ` 1/(kg*m^2));
I get:
(%i40) M_K2(1000`1/minute)``N*m;
(%o40) 1/648 ` N*m
That's not right!
(%i78) M_K2(n):= if n <= 500`1/minute then 0`N*m
else (n`minute-500)^2/45000`N*m;
(%o78) M_K2(n):=if n<=500 ` 1/minute then 0 ` N*m else (n ` minute-500)^2/45000 ` N*m
(%i79) M_K2(1000`1/minute);
(%o79) 50/9 ` N*m
That's more like it.
Also, it should be solvable:
(%i69) res: dimensionally(solve(M_K2(n) = 10`N*m, n)); n_K2P2: rhs(res[1])``1/minute; float(%);
(%o67) [(if n<=500 ` 1/minute then 0 ` N*m else (n^2 ` N*m*minute^2+(-1000*n) ` N*m*minute+250000 ` N*m)/45000)=10 ` N*m]
(%o68) (600*kg*m^2)/s ` 1/minute
(%o69) (600.0*kg*m^2)/s ` 1/minute
Should look like this:
(%i86) res: dimensionally(solve(M_K2(n) = 10`N*m, n)); n_K2P2: rhs(res[2])``1/minute; float(%);
(%o84) [n=(500-12*5^(5/2)) ` 1/minute,n=(12*5^(5/2)+500) ` 1/minute]
(%o85) (12*5^(5/2)+500) ` 1/minute
(%o86) 1170.820393249937 ` 1/minute
If I get one thing working, another one breaks. Looks like one edge-case after the next.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为这种配方可以正常工作。
在M_K1中,我非常小心地返回一个在的分支上都有单位的结果,并向具有单位的M_K1提供参数。请注意,M_K1
在小于或等于500个分支和
大于500个分支上的返回。
M_K1的这种公式要求您知道其参数的单位
n
,因为该函数说QTY(n)
,然后与该数字一起使用。因此,您无法将单位更改为1/小时
或其他情况,而无需更改函数中的常数。为了使M_K1与不同的等效单位保持一致,可以进行几个更改。首先是编写
,如果n&lt; 500`1/分钟然后...
。 Ezunits确实与单位实施了逻辑比较,但它很慢。例如,另一个是将单位放在算术表达式上的500和20000上。然后,即使更改了其参数的单位,M_K1也返回正确的结果。
数量&gt; 500但单位较小,因此小于500 Hz:
数量&LT; 500但单位更大,所以它大于500 Hz:
哦,这很混乱,它具有我们期望的尺寸,即能量吗?
好消息,%O13的尺寸与J.(次要疣:恒定因子3出现在%O13中
。
lbf
是“磅力”,与lbm
,“磅质量”区分开。I think this formulation works okay.
In M_K1, I'm being careful to return a result which has units on both branches of the
if
, and supplying an argument to M_K1 which has units. Note that M_K1 returnson the less than or equal to 500 branch, and
on the greater than 500 branch.
This formulation of M_K1 requires that you know the units of its argument
n
, since the function saysqty(n)
and then works with that number. So you couldn't change the units to1/hour
or something without also changing the constants in the function.To make M_K1 behave consistently with different, equivalent units, one can make a couple of changes. The first is to write
if n < 500 ` 1/minute then ...
. Ezunits does implement logical comparisons with units, but it's slow. E.g.The other is to put units on the constants 500 and 20000 in the arithmetic expression. Then M_K1 returns a correct result even when the units for its argument are changed.
Quantity > 500 but units are smaller, so it's less than 500 Hz:
Quantity < 500 but units are bigger, so it's greater than 500 Hz:
Oh, that's messy, does it have the dimensions we expect, namely energy?
Good news, %o13 has same dimensions as J. (Minor wart: constant factor 3 appearing in %o13.) Okay, now convert to J:
Just for fun, nonstandard units of energy.
lbf
is "pound force", distinguished fromlbm
, "pound mass".感谢您的持续关注。我将尝试一一解决问题。总的来说,我看到的主要内容是单位并不始终如一。
(1)
n
必须具有1/time的尺寸 - 好的。 “然后”分支返回0`n*m
- 好吧。在“ Else”分支上,我想您想将n
转换为1/MINONE
以匹配500。n`minute
几乎可以使用。要明确您想要的内容,您可以说n`minute``1
或n/(1`1/minune) (1`minune)``1
或qty(n`` 1/分钟)
。 (foo```1
降低了一个单位表达式,实际上与非单元表达式无二维。)我认为
qty(n````` 1/code)
表达了意图最清楚的是,但这里是一种表述,上面写着“将单元划分为兼容单元” - 我知道这在应用程序中是常规的。现在我得到:
(2)关于情节,有必要确保参数是维度的。
似乎具有预期的效果。
尺寸比较
如果n&lt; = 500`1/minune ...
是正确的,但是很慢。更快的等效公式是(3)关于
m_k2
,结果%o40对我来说是正确的。我明白了:这似乎是正确的,因为
然后替换秒钟几分钟,
您显示的M_K2的第二个配方是%i78,它使秒和分钟混淆了 - 分子必须为
1/minune^2
,但是它的书面方式,单位丢失。然后引入n
,其中包含1/时间平方,必须在1/second^2
中测量。(4)关于
solve
,主要问题是它不知道该如何使用 。我们可以通过假设
来寻找大于500`1/分钟
的解决方案。 (理想情况下,我们不必这样提供帮助;这是一个工作。)在这种情况下,我倾向于说
假设(foo&gt; 500)
,然后与foo`1/minune
,因为我对假设
正确处理单元的疑问。但是,我发现更明显的假设(n&gt; 500`1/分钟)
具有预期效果。该语句并不是真正正确的,因为
0
与0`1/分钟
不同。无论如何,让我们向前锻造。 (我们可以通过说假设(%n&gt; 500)
并使用%n`1/分钟
。让我们使其更具可读性:
将假定的解决方案替换回M_K2:
Thanks for your continued interest. I'll try to address the problems one by one. Overall the main thing I see is that units aren't used consistently.
(1)
n
must have dimensions of 1/time -- okay. The "then" branch returns0 ` N*m
-- okay. On the "else" branch, I guess you want to convertn
to1/minute
to match 500.n`minute
almost works. To be clear about what you want, you can sayn`minute `` 1
orn/(1 ` 1/minute) `` 1
orn*(1 ` minute) `` 1
orqty(n `` 1/minute)
. (Thefoo `` 1
reduces a units expression which is actually nondimensional to a non-units expression.)I think
qty(n `` 1/minute)
expresses the intent most clearly, but here is a formulation which says, "divide a unit by a compatible unit" -- I know this is conventional in applications.Now I get:
(2) About the plot, it's necessary to ensure the argument is dimensional.
seems to have the desired effect.
The dimensional comparison
if n <= 500 ` 1/minute ...
is correct, but it's slow. An equivalent formulation which is much faster is(3) About
M_K2
, the result %o40 looks correct to me. I get:That seems right because
and then substituting seconds for minutes,
The second formulation for M_K2 which you showed, %i78, is confusing seconds and minutes -- the numerator must be
1/minute^2
but the way it's written, the units are lost. ThenN
is introduced, which contains 1/time squared which must be measured in1/second^2
.(4) About
solve
, the main problem is that it doesn't know what to do withif
. We can look for solutions greater than500 ` 1/minute
viaassume
. (Ideally we wouldn't have to help out like that; it's a work-around.)In a case like this, I'm inclined to say
assume(foo > 500)
and then work withfoo ` 1/minute
, because I'm doubtful aboutassume
handling units correctly. However, I find that the more obviousassume(n > 500 ` 1/minute)
has the expected effect.That statement isn't really correct, since
0
is not the same thing as0 ` 1/minute
. Let's forge ahead regardless. (We could be more careful by sayingassume(%n > 500)
and working with%n ` 1/minute
here.)Hmm, those units are very messy, let's make it more readable:
Substituting a supposed solution back into M_K2: