I have been trying to print some complex numbers. If the complex number (modTrace) is like 'a-ib' then my code:
modTrace
v = [real(modTrace(:)) imag(modTrace(:))].';
fprintf(fileID,'%e+%ei\n',v);
gives the output as:
2.355387e-13+-7.217925e-13i
To avoid the extra + sign in front of the negative imaginary piece I write:
v = [real(modTrace(:)) imag(modTrace(:))].';
if imag(modTrace(:))>0
fprintf(fileID,'%e+%ei\n',v);
else
fprintf(fileID,'%e%ei\n',v);
end
Now in the output the 'if' is not being executed. So if I have a complex number 'a+ib' it prints
'a bi' and if a complex number is 'a-ib' it prints 'a-bi' according to the else statement.
if I then modify the code like:
v = [real(modTrace(:)) imag(modTrace(:))].';
if imag(modTrace(:))<0
fprintf(fileID,'%e%ei\n',v);
else
fprintf(fileID,'%e+%ei\n',v);
end
then again the 'if' statement in not being executed. So for a complex number 'a-ib' the output is 'a+-bi' and the 'else' statement in being executed correctly.
Could any body please help me to find the output in the correct form?
Thanks.
I think that in this case you are better off using a loop:
for k = 1:length(modTrace)
if imag(modTrace(k))>0
fprintf(fileID,'%e+%ei\n',real(modTrace(k)), imag(modTrace(k)));
else
fprintf(fileID,'%e%ei\n',real(modTrace(k)), imag(modTrace(k)));
end
end
You can't vectorize it that easily because if you pass a vector to if it only evaluates true when (http://www.mathworks.com/help/matlab/ref/if.html):
the result is nonempty and contains all nonzero elements (logical or
real numeric). Otherwise, the expression is false.
Related
I'm using strfind with an 'or' comparison like so:
name='hello';
if strfind(name,'hello') | strfind(name,'hi')
disp('yes!')
end
>> yes!
The if statement must evaluate as true, since yes! is displayed.
In contrast, MATLAB doesn't return yes! if the statements are swapped:
if strfind(name,'hi') | strfind(name,'hello')
disp('yes!')
end
Why?
This is because short-circuiting. Short-circuited logical operators are a thing to speed up code. You can have
if veryShort | superlongComputation
so what MATLAB does is first evaluate veryShort and if it is true, then no need to evaluate the second one! The if condition is already met.
In your case strfind(name,'hello') returns 1, but strfind(name,'hi') returns [].
In the first example, as the first thing evaluated returns 1, you get to the display. However in the second case, it returns [], therefore MATLAB evaluates the second thing in the if, and returns 1. Then MATLAB applies the or operations where [] | 1 is an 0x0 empty logical array, so the if is not true.
Note, generally you want to use || to enforce short-circuiting, but | also does it, if it is inside a while or an if:
https://uk.mathworks.com/matlabcentral/answers/99518-is-the-logical-operator-in-matlab-a-short-circuit-operator
Both of the following conditions are empty []:
name='hello';
strfind(name,'hello') | strfind(name,'hi'); % = []
strfind(name,'hi') | strfind(name,'hello'); % = []
As referenced in Ander's answer, the | operator is using short circuiting to skip evaluation of the second condition if the first is false (or empty).
Some quick debugging will give you better understanding if we ignore short-circuiting:
strfind(name,'hi'); % = []
strfind(name,'hello'); % = 1
In both cases you are doing "if empty or non-zero", which is empty and "if []" is false (that conditional statement won't be executed).
What you want to use to be explicit is something like this:
if ~isempty(strfind(name, 'hello')) & ~isempty(strfind(name, 'hi'))
disp('yes!')
end
Here, we guarantee that everything being evaluated in the if statement is a Boolean variable, not empty or an index like strfind returns, so unexpected results are less likely.
There are simpler methods, like using strcmp or ismember if your strings should match exactly. Or contains if you have R2016b or newer:
if contains('hello', {'hello','hi'})
disp('yes!');
end
I have the following if else statement that created by myself in order to link to the if else statement given in second part:
m=4
if m==3
disp(true)
else
disp(false)
Second part ( this code is fix cannot be change):
if (true)
A=Hello World
else
A=Bye
If using the first part code, my output will be
A=Hello World
but my desire output is
A=Bye
Anyone one have idea to edit the first part, because now my return value in first part not able to link to my second part.
If you can't change the second part's code, I'm afraid your desire cannot be fulfilled. Or rather, I'm afraid your code won't run at all, because your perenthesis, quotes, end-statement (and arguably semicolons) are not in place.
if true
A = 'Hello World';
else
A = 'Bye';
end
This code will return A = 'Hello World', no matter what, since true is always true. If-else conditions work like this:
if (*what's in here evealuates to true*)
%do stuff
else (*if what's up there does not evaluate to true*)
%do other stuff
Clearly, true will always evaluate to true. So the above if-else condition will always return A = 'Hello World'.
You don't need two if statements in order to accomplish this task. One is more than enough to perform all what you need:
m = 4;
if (m == 3)
A = 'Hello World';
else
A = 'Bye';
end
disp(A);
A few comments concerning your code:
if statements need to be closed with an end
if (true) will always pass into the statement
the disp function doesn't assign a value, its only goal is to display it in the Command Window
in order to work with text, you have to enclose it within single quotes ' (char array) or double quotes " (string), more info here
If you posted only small excerpts of your code and you need to perform those two checks sequentially, in different parts of your script, then:
m = 4;
if (m == 3)
m_equals_3 = true;
disp('M == 3');
else
m_equals_3 = false;
disp('M ~= 3');
end
% then, somewhere else...
if (m_equals_3)
A = 'Hello World';
else
A = 'Bye';
end
% ...
I guess this is a homework exercise. You should disclose that if it’s the case.
The exercise requieres you to change the workspace such that the second bit of code evaluated the else case. This can be accomplished by changing the meaning of true. In your first bit of code, make it so that
true = flase;
Or equivalently,
true = 0;
Note that this is really bad form, if you ever do something like this outside of a homework exercise that explicitly asks you to do so, you’ll get fired or maybe even shot. You’ve been warned!
By the way, I assume that the missing quote characters around the strings and the missing ends are typos?
i want to debug following simplest code in matlab and clarify why it executes always if statement
function testfile(x)
if 3<x<6
disp('in the middle of range');
else
disp('out of range');
end
end
i have used following code for debugger
echo testfile on
testfile(-2)
in the middle of range
testfile(6)
in the middle of range
why it does not execute else statement?i have used following code as a test
5<4<8
ans =
1
so does it mean that writing if statement in this style is wrong?a i understood it is same as if 5<4 || 4<8?then it makes clear for me why it executes only if statement and never reaches to else
5<4<8 is evaluated as (5<4)<8. If we resolve the expression in the parentheses first, we have 0<8, which is true. Test with 5<4==0, which evaluates to true.
What you want to do is check whether x is both bigger than 3 and smaller than 6, i.e.
3<x && x<6
In most OO languages, where variables may point to objects, they may also have a null value, which is highly convenient.
In Matlab, I have a function which parses a command, and then returns a cell array, or false (which is equal to zero — which is another common pattern) if it fails:
function re = parse(s)
...
if (invalid)
re = false;
return;
end
end
The problem is that when I check the result, it gives an error:
re = parse(s);
if (false == re)
Undefined function 'eq' for input arguments of type 'cell'.
I've written a function to check it without an error: strcmp('logical', class(re)) && false == re, but that seems to be really slow for use in hot areas of the code, and also inconvenient if I have to add this function to every M file I'm writing.
Using NaN is even worse, because besides throwing that error, it also isn't equal to itself.
What's a better alternative for use with this pattern?
You can use the isequal function to compare any two items without causing that error. For example:
if isequal (re, false)
%code here
end
A good alternative is to use the empty array: [] and isempty(re) to check. This doesn't throw the error.
Reference: http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/148764
If you can change the function parse one solution would be to return two output arguments [re status] = parse(s), where status would be logical variable. Set it to true in case of success, and to false otherwise.
I would use the empty cell array {} if it is not a valid result otherwise. Using empty matrices is MATLAB standard (see Evgeni Sergeev's answer), but using an empty cell array instead of an empty numeric array ensures that you'll always end up with the same type of result.
If, on the other hand, the empty cell array {} is a valid result of your function, then I'd use an exception to signalize a problem:
if invalid
error('Parse:InvalidArgumentError', 'The input is invalid.');
end
Make sure to use an appropriate error ID (first argument to error) so that you can catch exactly that exception when you call the function:
try:
result = parse(something);
catch ME
if strcmp(ME.identifier, 'Parse:InvalidArgumentError')
fprintf('Ooops\n');
else
% Some other error
ME.rethrow();
end
end
I think the problem is that matlab functions don't return pointers but copies of values.
IMHO the best best approach would be to define your own "pointer" class. Inside you can define an "isNull()" command or even override comparison to produce the behavior you desire.
I want to remove a (*) asterisk from my matrix and write out that matrix to a text file and the remaining elements will be concatenated to each other without a space or any kind of delimiters. I wrote this code
for b = 1 : length(out7num_r7_nt_back)
if ~(out7num_r7_nt_back(b) == '*')
out7num_r7_back(b) = '';
end
end
disp(out7num_r7_nt_back);
dlmwrite('my_data.txt',out7num_r7_nt_back, '');
I got this error message:
??? Index of element to remove exceeds matrix dimensions.
You can use a vectorized boolean index, replacing the loop as follows:
out7num_r7_nt_back = out7num_r7_nt_back(out7num_r7_nt_back(b) ~= '*');
That should be much faster as well.
Value of upper bound of for loop (length(out7num_r7_nt_back)) gets evaluated only once!
Say you have '*ab' in a variable. Loop will count to 3 (length of variable). Inside the loop when program erases '*', you'll get 'ab' which is of length 2. Since loop is iterating to 3, program will try to access out7num_r7_nt_back(3) which is out of bounds.
You could remove characters while going backwards:
...
for b = length(out7num_r7_nt_back) : -1 : 1
...
But you should prefer vectorized approach because it's faster and cleaner to write.