They seem to be exactly the same, like:
>> v1 = [5];
>> v2 = 5;
>> isequal(v1, v2)
ans =
1
>> [5] * [1,2,3]
ans =
5 10 15
>> v1(1)
ans =
5
>> v2(1)
ans =
5
Is there any differenceI should be aware of?
Thanks.
Is there any difference I should be aware of?
No
Although there is no significant difference, there is a difference.
v1=5; is creating a variable called v1 that has a value of 5.
v1=[5]; is defining a matrix/scalar with the value of 5; then it is concatenating that matrix with nothing - concatenation is the operation performed by the square brackets, and is why you do need them to define [1,2,3] - and then the result is assigned to the variable v1. So using the square brackets performs an additional operation.
This is why if you write your code in the editor you'll receive an m-lint message saying
The use of brackets [] is unnecessary. Use parenthesis to group, if needed.
There is no difference between [5] and 5. But in general there may be a difference between an expression [f] and f, where f is some expression. Here is an example:
c = {10,20,30,40,50,60};
x = c{1:3}
y = [c{1:3}]
Here, c is a cell array, so the operation c{1:3} returns all objects in places 1 to 3 of c as a comma-separated list, in other words it returns 10,20,30. It does not return the array [10,20,30]. So, the command x = c{1:3} is equivalent to x=10,20,30, which is equivalent to assigning x the value 10, and then doing nothing with the literals 20 and 30. On the other hand, the command y = [c{1:3}] groups the comma-separated list between brackets [], so it is equivalent to y=[10,20,30]. To conclude, x will have the value 10 while y will have the value [10,20,30].
Related
Is there a way in matlab to assign the output from a function in matlab to a vector within a single line?
For example, this function should assign a perimeter and an area value
function [p,a] = square_geom(side)
p = perimeter_square(side)
a = side.^2
[p,a]
however when I try to store the data like this
v = square_geom(3)
It doesn't work. However it is possible to do it like this
[p,a] = square_geom(3)
v=[p,a]
But that just doesn't look as good as keeping it to a single line. Any ideas?
You can change the definition of your function by using varargout as output variable:
Edit
Updated the definition of the function to include the check on the number of output
function varargout = square_geom(side)
p = 3;% %perimeter_square(side)
a = side.^2;
v=[p,a];
switch(nargout)
case 0 disp('No output specified, array [p,a] returned')
varargout{1}=v;
case 1 varargout{1}=v;
case 2 varargout{1}=p;
varargout{2}=a;
case 3 varargout{1}=v;
varargout{2}=p;
varargout{3}=a;
otherwise disp(['Error: too many (' num2str(nargout) ') output specified'])
disp('array [p,a,NaN, NaN ...] returned (NaN for each extra output)')
varargout{1}=v;
varargout{2}=p;
varargout{3}=a;
for i=4:nargout
varargout{i}=NaN
end
end
This allows you either calling your function in several ways
square_geom(3)
v=square_geom(3)
[a,b]=square_geom(3)
[a,b,d]=square_geom(3)
[a,b,d,e,f,g]=square_geom(3)
In the first case you get the array v as the automatic variable ans
square_geom(3)
No output specified, array [p,a] returned
ans =
3 9
In the second case, you get the array v
v=square_geom(3)
v =
3 9
In the third case, you get the two variables
[a,b]=square_geom(3)
a = 3
b = 9
In the fourth case, you get the array v and the two sigle variables a and b
[v,b,d]=square_geom(3)
v =
3 9
b = 3
d = 9
In the latter case (too many output specified), you get the array v, the two single variables a and b and the exceeding variables (e, f and g) set to NaN
[v,b,d,e,f,g]=square_geom(3)
Error: too many (6) output specified
array [p,a,NaN, NaN ...] returned (NaN for each extra output)
v =
3 9
b = 3
d = 9
e = NaN
f = NaN
g = NaN
Notice, to thest the code I've modified the function byh replacing the call toperimeter_square with 3
The value outputted by the function are two different variables, not an array.
So the output should be stored as two cells.
[v(1),v(2)]=fn(val)
Here, the value is stored in two different cell v(1) and v(2) of the same array 'v'.
The simplest solution that comes into my mind is:
c = test();
function result = test()
a = ...; % complex computation
b = ...; % complex computation
result = [a b];
end
The C variable will then be a column vector containing two values. But this solution is only suitable if your function output doesn't need to be flexible.
You can get your multiple outputs in a cell array.
In your case:
v=cell(1,2);
[v{:}]=square_geom(3)
This is simplified but take as an example the following MATLAB function handle:
F = #(x)[x(1)-x(2);x(2)-x(3)]
The system has of course has many solutions. Is it possible to obtain a solution for a function like this one after substituting at least one variable? For example, substituting x(3)=1 the function would become:
G = #(x)[x(1)-x(2);x(2)-1]
And a solution for the other variables can be obtained. I use fsolve and it works quite well for the system of equations I have. Of course what I need to do can be done using the Symbolic Toolbox, but calling it in a big for loop makes it too slow to use for my code.
I'm trying to come up with some code that can return G given F and a set of indices in x to replace with given values.
What you're basically asking to do is have G call F with values in x reassigned based on a logical replacement index index and a set of replacement values values, which is doable but messy since anonymous functions can only have a single executable statement.
The solution is similar to what is done in this answer, but instead of using the functional form for subscripted reference we'll need to use the functional form for subscripted assignment: subsasgn. Here's what it would look like:
F = #(x)[x(1)-x(2); x(2)-x(3)];
values = [3 2 1];
index = logical([0 0 1]);
G = #(x) F(subsasgn(x, struct('type', '()', 'subs', {{index}}), values(index)));
And here's a test:
>> F([3 2 3])
ans =
1
-1
>> F([3 2 1]) % Replace the last element by 1
ans =
1
1
>> G([3 2 3]) % G handles replacing the last element by 1
ans =
1
1
For example, Why are 1:5 and [1:5] the same in matlab?
What is the reason behind this convention?
The reason for the convention is hard to tell without asking the creators of MATLAB, but here's a little insight. I apologies if this is a bit messy.
If you don't bother reading it all, here's the executive summary:
: is used to create regularly spaced vectors, while square brackets are used for concatenating.
First, you should know that even scalars are considered to be matrices in MATLAB. Scalars are simply 1x1 matrices, or to be more specific: 1x1x1x1x......1. There are in theory infinite amount of trailing singleton dimensions.
1 == [1] == [[[1]]]
Also:
a = 1;
a(1,1,1,:,:,1) %% Messy indexing showing how you can index a matrix using more dimensions than it appears to have.
ans =
1
The documentation says:
The colon operator is used to create regularly spaced vectors (and subscript arrays, and specify for iterations).
As scalars can be created without brackets, there's no reason you should need brackets around a clearly and unambiguously defined operator.
Brackets [] on the other hand creates vectors or matrices by concatenating values and vectors. From the documentation:
Square brackets are used in array construction and concatenation, and also in declaring and capturing values returned by a function.
Therefore, you can basically put brackets around anything you want. The same example as with the scalar above:
1:4 == [1:4] == [[[1:4]]]
Or around cells (doesn't change anything):
a = {3,1:4,'Hello, World!'}
a =
[3] [1x4 double] 'Hello, World!'
b = [a]
b =
[3] [1x4 double] 'Hello, World!'
Concatenating strings:
str1 = 'Hello';
str2 = ', World!';
str = [str1 str2]
str =
Hello, World!
Concatenating vectors:
[1:4, 6:8, 10]
ans =
1 2 3 4 6 7 8 10
If you had to put brackets around the 1:4 part, this would be (also works, but much more cumbersome):
[[1:4], [6:8], 10]
ans =
1 2 3 4 6 7 8 10
A possible reason for the convention:
It would be inconsistent if you needed brackets around 1:3.
Unrelated: For anyone used to other programming languages, brackets inside brackets often means you "go up" one dimension. Therefore, this might be confusing to some.
Well in a way they are and are not the same , In MATLAB every thing is a matrix , even
a = 5
is 1x1 matrix , for 1-D matrix or vector they will perform the same operation
when you write
>> x=1:3
ans =
1 2 3
MATLAB consider the matrix as one dimensional , like for instance in the example below it consider only the last row of the declaration
>> x=1:3;2:4
ans =
2 3 4
but when you specify brackets it can be an nxm dimensional matrix
>> x=[1:3;1:3]
x =
1 2 3
1 2 3
>> v1
[0.6324] [0.0975] [0.2785]
>> c1
[0.8147] [0.9058] [0.1270] [0.9134]
>> c1{1:3} = v1{1:3}
I get the following error message:
The right hand side of this assignment has too few values to satisfy
the left hand side.
Here c1 and v1 are both simple cell arrays, ie, both have simple numerical values. Then, why shouldn’t this work?
When using curly brackets {}, you are extracting the values of the cells. Use normal brackets () to refer to a set of cells and therefore keep the cells without extracting the actual content. So the following line will assign the cells (not the values inside the cells) from the right hand side to the left hand side:
c1(1:3) = v1(1:3)
We can check the datatype of c1(1:3) easily and see that it is in fact a cell-array:
>> A = c1(1:3)
A =
[1] [2] [3]
>> class(A)
ans =
cell
To see that curly brackets {} extract the values itself, we can do the following and see that the datatype of B is double:
>> B = c1{1}
B =
1
>> class(B)
ans =
double
As #Dan mentions in his comment, v1{1:3} gives you a comma-separated list of three separate doubles. You can notice that by seeing three ans = using the command line, because all the values will be returned individually:
>> v1{1:3}
ans =
1
ans =
2
ans =
3
Following that, you can do the assignment in a different way, which I do not recommend. The following provides three elements on the LHS by using the concatenation operator [] , the RHS provides three elements as well as we saw above.
>> [c1{1:3}] = v1{1:3}
c1 =
[1] [2] [3] [7]
We can specify a list by a = [1:3]
but at the same time,
we can also specify a list by a = 1:3.
I see that the output on the command window for a is the same, i.e.
a =
1 2 3
But is there any difference in the internal structure where we cannot see and cause difference in further calculation?
I don't think so. In MATLAB, the square brackets can be used for concatenating some number of matrices together. So for example, I could do
x = [1:2, 5:7, 9:12]
x =
1 2 5 6 7 9 10 11 12
In your case, you are doing matrix concatenation with only one matrix, which simply yields the matrix provided.
You don't even need to go to vectors. Even for scalars, the following are equivalent:
a = 123;
a = [ 123 ];
The first one declares a as the scalar 123, while the second one declares it as a length-1 vector whose sole element is 123. In MATLAB, these two are exactly the same thing.
Here's an example (using octave):
octave:1> x = 123
x = 123
octave:2> x(2) = 456
x =
123 456
As you can see, what was declared as a scalar could very easily be handled as a vector. I think everything is just stored as vectors.