matlab vba ternary-operator conditional-operator iif

¿Hay un operador de IF condicional de Matlab que pueda colocarse INLINE como el IIF de VBA



ternary-operator conditional-operator (7)

En VBA puedo hacer lo siguiente:

A = B + IIF(C>0, C, 0)

de modo que si C> 0 obtengo A=B+C y C <= 0 obtengo A=B

¿Hay un operador o función que me permita hacer estos condicionales en línea en el código de MATLAB?


¿Qué tal si usamos simplemente el hecho de que MATLAB convierte automáticamente los tipos de variables cuando la operación lo requiere? Por ejemplo, lógico para duplicar.

Si sus variables son escalares dobles, su código, creo, puede ser reemplazado por

a = b + (c > 0) * c;

En este caso, el operador (c > 0) valora 1 (tipo lógico) siempre que c > 0 y valores a 0 caso contrario.


Ahora hay una función tern en el intercambio de archivos MathWorks: http://www.mathworks.com/matlabcentral/fileexchange/39735-functional-programming-constructs/content/tern.m

El código se reproduce aquí:

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


Esto es más un resumen de la respuesta de Alex.

El método de Alex no funciona cuando quieres regresar inf

En estos casos, a menudo terminas obteniendo una cifra de 0*inf , que MATLAB evaluará como NaN . Problemático ... Podemos evitar esta multiplicación usando una búsqueda en su lugar.

Como ejemplo, una función de barrera útil en la optimización convexa es algo que se comporta como log positivo en todas partes y, en -inf otro lugar. Aquí se explica cómo puede crear dicha función usando una búsqueda:

INF_CONDITION = [0, inf]; fn_logbr = @(x) (x>0)*log(x) - INF_CONDITION( 1+(x<=0) )

Los condicionales en línea son un truco, y pierdes la evaluación perezosa. Tienes que tener cuidado. Sin embargo, tener código semántico es realmente agradable, y es más fácil compartir tu código cuando no puedes garantizar que todos los entornos sean iguales.


Inspirado por la respuesta de Jonas, la función siguiente también funciona para entradas y caracteres de tipo mixto, para los cuales su función no es estable.

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

Editar : eliminando las opciones condicionales adicionales en la rama de la celda, que aparentemente fueron restos de un error anterior, esto es probablemente más rápido y definitivamente más limpio.


No hay operador ternario en Matlab. Por supuesto, puede escribir una función que lo haría. Por ejemplo, la siguiente función funciona como iif con nd entrada para la condición, y con números y celdas para los resultados a y b :

function out = iif(cond,a,b) %IIF implements a ternary operator % pre-assign out out = repmat(b,size(cond)); out(cond) = a;

Para una solución más avanzada, hay una manera de crear una función en línea que incluso puede hacer otra cosa, como se describe en esta publicación de blog sobre engaños de funciones anónimas :

iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, ''first'')}();

Usas esta función como

iif(condition_1,value_1,...,true,value_final)

donde reemplaza los puntos con cualquier número de pares de condición / valor adicionales.

La forma en que esto funciona es que elige entre los valores el primero cuya condición es verdadera. 2*find(),1,''first'') proporciona el índice en los argumentos de valor.


No hay una solución incorporada para esto, pero puede escribir un IIF usted mismo .

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


Otros ya han dicho que no hay un operador ternario en Matlab. Como solución sugiero esta función, que toma tres funciones en lugar de valores. Por lo tanto, la cantidad de cálculos innecesarios se minimiza y puede verificar las condiciones antes de comenzar los cálculos, por ejemplo, si un valor es realmente numérico, finito o distinto de cero:

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

Úselo así:

f = @(y)(iif(@(x)(x > 3), @(x)(x.^2), @(x)(x/2), y)) f(linspace(0,6,10))