I'm new to Matlab and I'm just stuck with this line of code:
[r,c] = find(abs(fh) <= 2 );
Beware: ironically it was easy for me understanding what the right part of the assignment is.
The left part however (which is maybe the definition of a variable)... I don't know how to search because I have too generic results by googling just square brackets with something inside.
My assumption is this line of code is creating some a matrix with r rows and c columns but r and c are nowhere to be found in the rest of the code.... or maybe it's a simple array with two elements... but it doesn't make much sense to me honestly.
Can you guys help me please?
Whenever you see that syntax, it means that the function being called is returning more than one output argument (two in this case).
The best way to learn about the function output arguments is to check the documentation:
https://www.mathworks.com/help/matlab/ref/find.html#d120e368337
[row,col] = find(___) returns the row and column subscripts of each
nonzero element in array X using any of the input arguments in
previous syntaxes.
The output arguments are positional, so r is row, c is col.
Take a look in Matlab find() docs.
If X is a vector, then find returns a vector with the same orientation as X.
If X is a multidimensional array, then find returns a column vector of the linear indices of the result.
If X contains no nonzero elements or is empty, then find returns an empty array.
If you call
X = [18 3 1 11;
8 10 11 3;
9 14 6 1;
4 3 15 21 ]
[row,col] = find(X>0 & X<10,3)
You will get:
row = 3×1
2
3
4
col = 3×1
1
1
1
Which represents the index (row number and column number) of each elements that satifies the condition you defined. Since it returns more than 1 value, you can divide the output in two different variables and that is what the left side represents.
I have a 1x24 cell array called chaining, whose each cell contains a 119x119 matrix:
I want to find the sum of each corresponding elements of all the cells, and store them in a matrix called result. That is, the (j,k)th element of result should contains the sum of the (j,k)th elements of all the matrices in the cell array chaining.
The code I wrote to do this is:
for j=1:size(chaining,2)
for k=1:size(chaining,2)
result(j,k) = sum(chaining{1,:}(j,k));
end
end
But this gives error because apparently MATLAB can't aggregate cell arrays for some reason (i.e., the chaining{1,:} part).
Could anyone please show me how to go about doing this?
how about
result = sum( cat(3, chaining{:}), 3 );
What just happened here?
First, we convert the cell array into a 3D array by "stacking" the 2D cell elements on the third dimension:
cat(3, chaining{:})
Once we have a 3D array of size 119-by-119-by-24 we can sum along the third dimension and get result of size 119-by-119:
sum( ..., 3 );
For more info see cat and sum help pages.
BTW,
If you insist on chaining{1,:}(jj,kk) type of solution (not recommended), you might find subsref command useful.
I need to create a function that has the input argument n, a integer , n>1 , and an output argument v, which is a column vector of length n containing all the positive integers smaller than or equal to n, arranged in such a way that no element of the vector equals its own index.
I know how to define the function
This is what I tried so far but it doesn't work
function[v]=int_col(n)
[1,n] = size(n);
k=1:n;
v=n(1:n);
v=k'
end
Let's take a look at what you have:
[1,n] = size(n);
This line doesn't make a lot of sense: n is an integer, which means that size(n) will give you [1,1], you don't need that. (Also an expression like [1,n] can't be on the left hand side of an assignment.) Drop that line. It's useless.
k=1:n;
That line is pretty good, k is now a row vector of size n containing the integers from 1 to n.
v=n(1:n);
Doesn't make sense. n isn't a vector (or you can say it's a 1x1 vector) either way, indexing into it (that's what the parentheses do) doesn't make sense. Drop that line too.
v=k'
That's also a nice line. It makes a column vector v out of your row vector k. The only thing that this doesn't satisfy is the "arranged in such a way that no element of the vector equals its own index" part, since right now every element equals its own index. So now you need to find a way to either shift those elements or shuffle them around in some way that satisfies this condition and you'd be done.
Let's give a working solution. You should really look into it and see how this thing works. It's important to solve the problem in smaller steps and to know what the code is doing.
function [v] = int_col(n)
if n <= 1
error('argument must be >1')
end
v = 1:n; % generate a row-vector of 1 to n
v = v'; % make it a column vector
v = circshift(v,1); % shift all elements by 1
end
This is the result:
>> int_col(5)
ans =
5
1
2
3
4
Instead of using circshift you can do the following as well:
v = [v(end);v(1:end-1)];
I have a 1x10 ( say 10 because it is actually 262144, but for the purpose of my question, 10 is enough) cell array called x. Each cell is an array of 0 to 4 real values.
I'd like to run an if condition based on the number of element in each cell, WITHOUT using a for loop (as I said, it is actually 262144 cell long, so a for loop might be a bit heavy).
for loop exemple to show what I want to do :
for i = 1:10
if numel(x{i}) > 2
h(i) = 0;
else
h(i) = 1;
end
end
And then I'll want to run a while loop independantly on each cell, incrementing h by 1 until it reaches the value of the lenght of the cell.
len = cellfun(#numel,x)
while h < len
h = h+1;
%code that does thing on each cell still in the while loop
end
I've never seen anything like that online even though I've looked quite thoroughly. If anyone can give me a global indication on how to work independantly on separate cells without using a for loop (which is the core of my problem), I'd be great!
EDIT : Knowing how to operate on value X of all cells would be great too. E.g:
k = x{:}(1) < x{:}(2)
This doesn't work, but I don't know why and I don't what would. Trying to compare all first values with all second values.
For your first problem, you can easily use a combination of cellfun and logical indexing to generate h:
h = cellfun(#numel, x) <= 2;
The <= 2 bit will return a 1 if a value is, well, less than or equal to 2, and 0 otherwise.
Note that for and while loops really aren't slow, so maybe what you have written is "good enough".
EDIT: With regards to your new, edited question: naively this can't be done unless you can guarantee that the length of each array inside each cell is the same. I will assume that it is.
If that's the case, you can simply call cell2mat to convert the cell array to a matrix, then directly compare the two columns:
A = cell2mat(x);
k = A(:,1) < A(:,2);
If the lengths are all different, you can fill them with zeros or nan or something to make them the same length.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Over the years, reading others code, I encountered and collected some examples of MATLAB syntax which can be at first unusual and counterintuitive. Please, feel free to comment or complement this list. I verified it with r2006a.
MATLAB always returns first output argument of a function (if it has at least one) into its caller workspace, also unexpectedly if function is being called without returning arguments like myFunc1(); myFunc2(); the caller workspace still would contain first output of myFunc2(); as "invisible" ans variable. It could play an important role if ans is a reference object - it would remain alive.
set([], 'Background:Color','red')
MATLAB is very forgiving sometimes. In this case, setting properties to an array of objects works also with nonsense properties, at least when the array is empty. Such arrays usually come from harray = findobj(0,'Tag','NotExistingTag')
myArray([1,round(end/2)])
This use of end keyword may seem unclean but is sometimes very handy instead of using length(myArray).
any([]) ~= all([])
Surprisigly any([]) returns false and all([]) returns true. And I always thought that all is stronger then any.
EDIT:
with not empty argument all() returns true for a subset of values for which any() returns true (e.g. truth table). This means that any() false implies all() false. This simple rule is being violated by MATLAB with [] as argument.
Loren also blogged about it.
Select(Range(ExcelComObj))
Procedural style COM object method dispatch. Do not wonder that exist('Select') returns zero!
[myString, myCell]
MATLAB makes in this case an implicit cast of string variable myString to cell type {myString}. It works, also if I would not expect it to do so.
[double(1.8), uint8(123)] => 2 123
Another cast example. Everybody would probably expect uint8 value being cast to double but Mathworks have another opinion. Without a warning this behavior is very dangerous.
a = 5;
b = a();
It looks silly but you can call a variable with round brackets. Actually it makes sense because this way you can execute a function given its handle.
Syntax Foo(:) works not only on data but also with functions if called as Bar.Foo(:), in this scenario the function input argument is passed as char colon ':'.
For example let Bar.Foo = #(x) disp(x)
Now calling Bar.Foo(:) prints char ':' in the MATLAB Command Window.
This strange feature works with all MATLAB 7 versions without warnings.
a = {'aa', 'bb'
'cc', 'dd'};
Surprsisingly this code neither returns a vector nor rises an error but defins matrix, using just code layout. It is probably a relict from ancient times.
EDIT: very handy feature, see the comment by gnovice.
set(hobj, {'BackgroundColor','ForegroundColor'},{'red','blue'})
This code does what you probably expect it to do. That function set accepts a struct as its second argument is a known fact and makes sense, and this sintax is just a cell2struct away.
Equvalence rules are sometimes unexpected at first. For example 'A'==65 returns true (although for C-experts it is self-evident). Similarly isequal([],{}) retuns, as expected, false and isequal([],'') returns true.
The string-numeric equivalence means that all string functions can be used also for numeric arrays, for example to find indices of a sub-array in a large array:
ind = strfind( [1 2 3 4 1 2 3 4 1 2 3 4 ], [2 3] )
MATLAB function isnumeric() returns false for booleans. This feels just ... false :-)
About which further unexpected/unusual MATLAB features are you aware?
Image coordinates vs plot coordinates Used to get me every time.
%# create an image with one white pixel
img = zeros(100);
img(25,65) = 1;
%# show the image
figure
imshow(img);
%# now circle the pixel. To be sure of the coordinate, let's run find
[x,y] = find(img);
hold on
%# plot a red circle...
plot(x,y,'or')
%# ... and it's not in the right place
%# plot a green circle with x,y switched, and it works
plot(y,x,'og')
Edit 1
Array dimensions
Variables have at least two dimensions. Scalars are size [1,1], vectors are size [1,n] or [n,1]. Thus, ndims returns 2 for any of them (in fact, ndims([]) is 2 as well, since size([]) is [0,0]). This makes it a bit cumbersome to test for the dimensionality of your input. To check for 1D arrays, you have to use isvector, 0D arrays need isscalar.
Edit 2
Array assignments
Normally, Matlab is strict with array assignments. For example
m = magic(3);
m(1:2,1:3) = zeros(3,2);
throws a
??? Subscripted assignment dimension mismatch.
However, these work:
m(1:2,1:2) = 1; %# scalar to vector
m(2,:) = ones(3,1); %# vector n-by-1 to vector 1-by-n (for newer Matlab versions)
m(:) = 1:9; %# vector to 'linearized array'
Edit 3
Logical indexing with wrongly sized arrays Good luck debugging this!
Logical indexing seems to make a call to find, since your logical array doesn't need the same amount of elements as there are indices!
>> m = magic(4); %# a 4-by-4 array
>> id = logical([1 1 0 1 0])
id =
1 1 0 1 0
>> m(id,:) %# id has five elements, m only four rows
ans =
16 2 3 13
5 11 10 8
4 14 15 1
%# this wouldn't work if the last element of id was 1, btw
>> id = logical([1 1 0])
id =
1 1 0
>> m(id,:) %# id has three elements, m has four rows
ans =
16 2 3 13
5 11 10 8
Instead of listing examples of weird MATLAB syntax, I'll address some of the examples in the question that I think make sense or are expected/documented/desired behavior.
How ANY and ALL handle empty arguments:
The result of any([]) makes sense: there are no non-zero elements in the input vector (since it's empty), so it returns false.
The result of all([]) can be better understood by thinking about how you might implement your own version of this function:
function allAreTrue = my_all(inArray)
allAreTrue = true;
N = numel(inArray);
index = 1;
while allAreTrue && (index <= N)
allAreTrue = (inArray(index) ~= 0);
index = index + 1;
end
end
This function loops over the elements of inArray until it encounters one that is zero. If inArray is empty, the loop is never entered and the default value of allAreTrue is returned.
Concatenating unlike classes:
When concatenating different types into one array, MATLAB follows a preset precedence of classes and converts values accordingly. The general precedence order (from highest to lowest) is: char, integer (of any sign or number of bits), single, double, and logical. This is why [double(1.8), uint8(123)] gives you a result of type uint8. When combining unlike integer types (uint8, int32, etc.), the left-most matrix element determines the type of the result.
Multiple lines without using the line continuation operator (...):
When constructing a matrix with multiple rows, you can simply hit return after entering one row and enter the next row on the next line, without having to use a semicolon to define a new row or ... to continue the line. The following declarations are therefore equivalent:
a = {'aa', 'bb'
'cc', 'dd'};
a = {'aa', 'bb'; ...
'cc', 'dd'};
a = {'aa', 'bb'; 'cc', 'dd'};
Why would you want MATLAB to behave like this? One reason I've noticed is that it makes it easy to cut and paste data from, for example, an Excel document into a variable in the MATLAB command window. Try the following:
Select a region in an Excel file and copy it.
Type a = [ into MATLAB without hitting return.
Right-click on the MATLAB command window and select "Paste".
Type ]; and hit return. Now you have a variable a that contains the data from the rows and columns you selected in the Excel file, and which maintains the "shape" of the data.
Arrays vs. cells
Let's look at some basic syntax to start with. To create an array with elements a, b, c you write [a b c]. To create a cell with arrays A, B, C you write {A B C}. So far so good.
Accessing array elements is done like this: arr(i). For Cells, it's cell{i}. Still good.
Now let's try to delete an element. For arrays: arr(i) = []. Extrapolating from examples above, you might try cell{i} = {} for cells, but this is a syntax error. The correct syntax to delete an element of a cell is, in fact, the very same syntax you use for arrays: cell(i) = [].
So, most of the time you access cells using special syntax, but when deleting items you use the array syntax.
If you dig deeper you'll find that actually a cell is an array where each value is of a certain type. So you can still write cell(i), you'll just get {A} (a one-valued cell!) back. cell{i} is a shorthand to retrieve A directly.
All this is not very pretty IMO.