1

This might be a trivial problem but I want to write a simple for loop in Matlab that uses string variables for the different cases.

In Python, it is simply,

from numpy import cos, sin, pi

dist = 'markovian'

x = pi/7

if dist == 'lorentzian':
    z = sin(x)
    print(z)
elif dist == 'markovian':
    z = cos(x)
    print(z)
else:
    z = sin(x) + cos(x)
    print(z)

whereas in Matlab I have tried

dist = 'markovian';

x = pi/7;

if dist == strcmpi('lorentzian','true')
    z = sin(x)
elseif dist == strcmpi('markovian','true')
    z = cos(x)
else
    z = sin(x) + cos(x)
end

but it doesn't calculate z. What am I doing wrong with strcmpi?

0

2 Answers 2

4

Using strcmpi with if / else

The function strcmpi compares two strings ignoring case and returns a logical value. Thus, you need to use it as follows:

dist = 'markovian';
x = pi/7;
if strcmpi(dist, 'lorentzian')
    z = sin(x)
elseif strcmpi(dist, 'markovian')
    z = cos(x)
else
    z = sin(x) + cos(x)
end

Using switch

The code may be clearer with a switch statement. You can use lower to achieve case insensitivity.

dist = 'markovian';
x = pi/7;
switch lower(dist)
    case 'lorentzian'
        z = sin(x)
    case 'markovian'
        z = cos(x)
    otherwise
        z = sin(x) + cos(x)
end

Without branching

Here is an alternative that avoids branching. If you only have two or three options this approach is unnecesarily complicated, but if there are many options it may be more adequate for compactness or even readability.

This works by finding the index of the chosen option in a cell array of char vectors, if present; and using feval to evaluate the corresponding function from a cell array of function handles:

names = {'lorentzian', 'markovian'}; % names: cell array of char vectors
funs = {@(x)sin(x), @(x)cos(x), @(x)sin(x)+cos(x)}; % functions: cell array of handles.
                                                    % Note there is one more than names
dist = 'markovian';
x = pi/7;
[~, ind] = ismember(lower(dist), names); % index of dist in names
ind = ind + (ind==0)*numel(funs); % if 0 (dist not in names), select last function
feval(funs{ind}, x)
Sign up to request clarification or add additional context in comments.

Comments

3

Another option in MATLAB >= R2016b is to use string rather than char for text data. string lets you compare using ==, like this:

dist = "markovian"

x = pi/7

if dist == "lorentzian"
    z = sin(x)
elseif dist == "markovian"
    z = cos(x)
else
    z = sin(x) + cos(x)
end

2 Comments

Hm, not entirely clear to me they wanted case-insensitive - surely == is case-sensitive in Python? That appeared to me to be their starting point.
You are right. Python's == is case-sensitive, but Matlab's strcmpi is not. So it's not clear what they wanted

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.