【问题标题】:Is Ternary operation valid in Octave?三元运算在 Octave 中有效吗?
【发布时间】:2021-02-04 23:26:54
【问题描述】:

问题是有效的三元运算,因为我无法在网上找到任何与之相关的文档。而且我还发现在 MATLAB 中不可能使用三进制,因此任何建议和答案都将在此不胜感激。

#三元运算代码

taxes = (income > 50000)*(((income-50000) * 0.20)+(0.10*50000)) + (~(income > 50000))*0.10 *50000
#Condition True and this computation False then this computation

#带有 if 和 else 的代码

if (income) > 50000
#income = income - 50000
#Taxed at 10% (i.e 0.10) for $ 50000
#taxes = 50000 * 0.10
#Rest income will be Taxed at 20% (i.e 0.20)
taxes = 50000 * 0.10 + ((income-50000) * 0.20)
else
#Taxed at 10% (i.e 0.10)
taxes = income * 0.10
endif

输出:

GNU Octave, version 6.1.0
Copyright (C) 2020 The Octave Project Developers.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type 'warranty'.

Octave was configured for "x86_64-w64-mingw32".

Additional information about Octave is available at https://www.octave.org.

Please contribute if you find this software useful.
For more information, visit https://www.octave.org/get-involved.html

Read https://www.octave.org/bugs.html to learn how to submit bug reports.
For information about changes from previous versions, type 'news'.

>> income = 60000;
>> compute_taxes
taxes = 7000
>> income = 50000;
>> compute_taxes
taxes = 5000
>>

【问题讨论】:

  • 您的“三元运算代码”在 Octave 和 MATLAB 中有效。它不是真正的三元运算符,但会产生等效的结果。 if/else 代码的优势在于它可以处理数组,而不仅仅是标量值。
  • 另外,请将终端输出复制粘贴到问题中,而不是上传屏幕截图。原因见here
  • 我知道它不是,但我试图复制它,我是 Octave 的初学者,但我已经知道 python,所以我尝试了这段代码。@CrisLuengo 是的,它为我提供了相同的功能
  • 那么问题到底是什么?你似乎已经有了一些你想要的代码?
  • 也许将其写入问题文本以使其更清晰。在 Octave 中有merge or ifelse(它们似乎是一样的),这可能是(类似于)你想要的

标签: matlab octave conditional-operator


【解决方案1】:

任何语言中的三元运算符的任何定义与 if 语句之间都有一些重要的区别。

主要是后者是一个语句,而三元运算符根据定义是一个表达式。换句话说,您希望它返回一个值。 octave/matlab 中的 if 块不会“返回”值(即您不能执行 a = if ... endif)。如果您需要“返回”某些内容,则需要将其分配给循环内部的外部变量,然后在循环外部使用该变量。

第二件大事是三元运算符应该是链式。即你应该能够做到“如果这个,那么那个,否则如果那个那么那个其他的事情”,这样在一个长的比较链结束时,你返回一个值。


现在,octave 和 matlab 没有这种运算符。但是在八度音程中,模拟一个很容易,例如带细胞:

M1 = false; M2 = false; M3 = true;
{'expression1', 'expression2', 'expression3', 'fallback'}([ M1, M2, M3, true ]){1}

如果你真的想,你可以把这种东西做成一个很好的匿名函数,它返回第一个掩码/测试为真的表达式:

tern = @(varargin) reshape(varargin,2,[])(2,:)([reshape(varargin,2,[]){1,:}]){1}
tern( M1, 1, M2, 2, M3, 3, true, 4 )   % ans = 3

“回退”只需在“回退”值之前进行明确评估为“真”的测试即可实现。

注意:这种在匿名函数中“链接”两个或多个索引操作的方式仅适用于 octave,因为不幸的是 matlab 不允许链接操作,例如a(1)(2)。但是,没有什么能阻止您制作等效的“正确”外部函数,在第二次索引之前将中间结果保存到临时变量中;因此,从概念上讲,这个策略也适用于 matlab。


或者,您可以使用稍微不同的语法制作一个更简单的“三元运算符”(嗯,函数),在其中分别传递“测试/掩码”数组、“表达式”和“后备”单元格。例如

tern2 = @(M,E,F) [E, F]{find([M, true], 1)}
tern2( [M1, M2, M3], {1, 2, 3}, {4} )   % ans = 3

最后,还有ifelse 函数,它在本质上是相似的,即ifelse(test, expr_if_true, expr_if_false),但这并不是真正的三元运算符/函数,因为它不可链接;它对于基于“真/假掩码”在两个备选方案之间进行选择更有用,例如

ifelse( [M1, M2, M3], {1, 2, 3}, {4,5,6} )
% ans = { 4, 5, 3 }

【讨论】:

    【解决方案2】:

    您可以使用两个短路 &&|| 运算符模拟三元 if 运算符。
    考虑一下if/else 声明:

    if condition 
        val = expr1;
    else
        val = expr2;
    end
    

    t 定义为t = @(x) 1; 并将三元if 运算符定义为:

    condition && t(val = expr1) || t(val = expr2);
    

    实现三元if 运算符的一个重点是表达式expr1expr2 的求值。如果conditiontrue,则不得评估expr2,如果conditionfalse,则不得评估expr1。在像ifelse/merge 这样的函数中,两个表达式在传递给函数之前都会被求值,因此ifelse 不应被视为真正的三元if 运算符。

    有一些基于 MATLAB 的实现 herehere 用于创建递归匿名函数。诀窍是表达式由 lambda 包装以防止它们的求值。
    考虑以下计算第 n 个斐波那契数的函数:

    function val = fib(f, n)
      if n <= 2
        val = 1;
      else
        val = f(f, n - 1) + f(f, n - 2));
    end
    

    当前提出的技术可用于实现它(在 Octave 6.1.0 上测试):

    fib = @(f, n, t = @(x) 1, tmp = n <= 2 && t(val = 1) || t(val = f(f, n - 1) + f(f, n - 2))) val;
    

    在递归匿名函数以外的情况下,你可以使用这个:

    val = {condition && t(tmp = expr1) || t(tmp = expr2), tmp}{2};
    

    但是,这些技巧可能不会比if/else 语句执行得更好。

    【讨论】:

      猜你喜欢
      • 2013-04-13
      • 2023-03-11
      • 1970-01-01
      • 2010-10-09
      • 2022-01-06
      相关资源
      最近更新 更多