在VBA中,我可以执行以下操作:
A = B + IIF(C>0, C, 0)
因此,如果C> 0,我得到A=B+C
而C< = 0我得到A=B
是否有运算符或函数可以让我在MATLAB代码中执行这些条件内联?
答案 0 :(得分:34)
如何简单地使用MATLAB在操作需要时自动转换变量类型的事实?例如,合理地加倍。
如果您的变量是标量加倍,我相信您的代码可以替换为
a = b + (c > 0) * c;
在这种情况下,只要(c > 0)
,运算符1
的值为c > 0
(逻辑类型),否则值为0
。
答案 1 :(得分:26)
Matlab中没有三元运算符。当然,您可以编写一个可以执行此操作的函数。例如,以下函数的作用为iif
,条件为n-d输入,结果为a
和b
的数字和单元格:
function out = iif(cond,a,b)
%IIF implements a ternary operator
% pre-assign out
out = repmat(b,size(cond));
out(cond) = a;
对于更高级的解决方案,有一种方法可以创建一个甚至可以执行else的内联函数,如this blog post about anonymous function shenanigans中所述:
iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();
您将此功能用作
iif(condition_1,value_1,...,true,value_final)
用任意数量的附加条件/值对替换点。
这种方法的工作方式是在值中选择条件为真的第一个值。 2*find(),1,'first')
为值参数提供索引。
答案 2 :(得分:6)
此处没有内置解决方案,但您可以write an IIF yourself。
function result=iif(cond, t, f)
%IIF - Conditional function that returns T or F, depending of condition COND
%
% Detailed
% Conditional matrix or scalar double function that returns a matrix
% of same size than COND, with T or F depending of COND boolean evaluation
% if T or/and F has the same dimensions than COND, it uses the corresponding
% element in the assignment
% if COND is scalar, returns T or F in according with COND evaluation,
% even if T or F is matrices like char array.
%
% Syntax
% Result = iif(COND, T, F)
% COND - Matrix or scalar condition
% T - expression if COND is true
% F - expression if COND is false
% Result - Matrix or scalar of same dimensions than COND, containing
% T if COND element is true or F if COND element is false.
%
if isscalar(cond)
if cond
result = t;
else
result = f;
end
else
result = (cond).*t + (~cond).*f;
end
end
答案 3 :(得分:6)
其他人已经说过Matlab中没有三元?:
运算符。作为一个解决方案,我建议使用这个函数,它取三个函数而不是值。因此,最小化了不必要的计算量,您可以在开始计算之前检查条件,例如:如果值实际上是数字,有限或非零:
function [ out ] = iif( condition, thenF, elseF, in, out)
%iif Implements the ternary ?: operator
% out = iif (@condition, @thenF, @elseF, in[, out])
%
% The result is equivalent to:
% condition(x) ? thenF(x) : elseF(x)
%
% The optional argument out serves as a template, if the output type is
% different from the input type, e.g. for mapping arrays to cells and
% vice versa.
%
% This code is in the public domain.
mask = condition(in);
if nargin <= 4
out = in;
end
if sum(mask)
out(mask) = thenF(in(mask));
end
if sum(~mask)
out(~mask) = elseF(in(~mask));
end
end
像这样使用:
f = @(y)(iif(@(x)(x > 3), @(x)(x.^2), @(x)(x/2), y))
f(linspace(0,6,10))
答案 4 :(得分:3)
受Jonas&#39;的启发回答下面的功能也适用于混合型输入和字符,其功能不稳定。
function out = iif(cond, a, b)
%IIF implements a ternary operator
% Use cell output for either char or mixed type input
if ischar(a) || ischar(b) || ~strcmp(class(a), class(b))
out = cell(size(cond));
[out{cond}] = deal(a);
[out{~cond}] = deal(b);
else
% Use array output and logical indexing
out = repmat(b, size(cond));
out(cond) = a;
end
end
编辑:清除了单元格分支中的额外条件选项,这些选项显然是先前错误的残余,这可能更快,而且更加清晰。
答案 5 :(得分:2)
您所指的是三元运算符,用类似C的符号?:表示。表达式
tern = bool ? T : F
如果T
的值为true,则返回bool
,否则为F
。 MATLAB没有三元运算符,但是它可以作为内联表达式以不同方式实现。
数组
% cell array version (any type)
tern = {F,T}{bool+1} % only Octave
tern = subsref({F,T}, struct('type', '{}', 'subs', {{bool+1}}))
% vector array version (numeric types only)
tern = [F,T](bool+1) % only Octave
tern = subsref([F,T], struct('type', '()', 'subs', {{bool+1}}))
请注意,T
和F
已交换,并且使用了不同的括号。向量数组版本是数字类型的专用化。 MATLAB does not allow direct indexation of fresh arrays,因此使用subsref
。
tern
和T
都返回结果到F
之前
被评估。逻辑运算符和评估
( bool && eval('tern=T') ) || eval('tern=F')
请注意,逻辑运算符为short-circuited。
T
或F
。tern
使用。 eval
效率不高,但必需。基本算术
tern = bool*T + !bool*F
T
或F
为NaN
或Inf
时可能会失败。 T
和F
均被评估。最大
tern = max(T,F) % bool = T>F
请注意,此解决方案符合max(C,0)
最初问题的特殊要求。
T
或F
为NaN
时可能会失败。 T
和F
均被评估。使用受到严格限制。答案 6 :(得分:1)
MathWorks文件交换现在有一个tern
函数:
http://www.mathworks.com/matlabcentral/fileexchange/39735-functional-programming-constructs/content/tern.m
代码转载于此:
function varargout = tern(condition, true_action, false_action)
% out = tern(condition, true_action, false_action)
%
% Ternary operator. If the first input is true, it returns the second
% input. Otherwise, it returns the third input. This is useful for writing
% compact functions and especially anonymous functions. Note that, like
% many other languages, if the condition is true, not only is the false
% condition not returned, it isn't even executed. Likewise, if the
% condition is false, the true action is never executed. The second and
% third arguments can therefore be function handles or values.
%
% Example:
%
% >> tern(rand < 0.5, @() fprintf('hi\n'), pi)
% ans =
% 3.1416
% >> tern(rand < 0.5, @() fprintf('hi\n'), pi)
% hi
%
% It works with multiple outputs as well.
%
% >> [min_or_max, index] = tern(rand < 0.5, ...
% @() min([4 3 5]), ...
% @() max([4 3 5]))
% min_or_max =
% 5
% index =
% 3
%
% Tucker McClure
% Copyright 2013 The MathWorks, Inc.
if condition() % Works for either a value or function handle.
[varargout{1:nargout}] = true_action();
else
[varargout{1:nargout}] = false_action();
end
end
答案 7 :(得分:1)
这更像是亚历克斯答案的补充。
当您想要返回inf
时,Alex的方法无法运作
在这些情况下,您最终会得到一个0*inf
数字,MATLAB将评估为NaN
。有问题......我们可以使用查找来避免这种乘法。
作为一个例子,凸优化中有用的屏障函数在任何地方都表现得像log
,而在其他地方表现得像-inf
。以下是使用查找创建此类函数的方法:
INF_CONDITION = [0, inf];
fn_logbr = @(x) (x>0)*log(x) - INF_CONDITION( 1+(x<=0) )
内联条件是一种黑客攻击,你会失去懒惰的评价。你必须要小心。但是,拥有语义代码非常好,并且当您无法保证每个人的环境都相同时,它更容易分享您的代码。
答案 8 :(得分:0)
如果您正在寻找一个不强迫您构建函数并且可以使用相当简单的表达式的选项,则可以利用匿名函数。匿名函数返回一个逻辑,可以是数字1或0。因此,可以将它们与其他数字相乘,以确定它们在表达式之后是否仍然保留值,或者丢失其值。
对于您的情况(包括A,B和C是否为向量):A = B .+ (@() C>0)()
答案 9 :(得分:-1)
使用:
eval('input;','input = 1;');
在可能首先不存在“输入”的地方非常有帮助。