Understanding colon notation in MATLAB - matlab

So I'm completely new to MATLAB and I'm trying to understand colon notation within mathematical operations. So, in this book I found this statement:
w(1:5)=j(1:5) + k(1:5);
I do not understand what it really does. I know that w(1:5) is pretty much iterating through the w array from index 1 through 5, but in the statement above, shouldn't all indexes of w be equal to j(5) + k(5) in the end? Or am I completely wrong on how this works? It'd be awesome if someone posted the equivalent in Java to that up there. Thanks in advance :-)

I am pretty sure this means
"The first 5 elements of w shall be the first 5 elements of j + the first 5 elements of k" (I am not sure if matlab arrays start with 0 or 1 though)
So:
w1 = j1+k1
w2 = j2+k2
w3 = j3+k3
w4 = j4+k4
w5 = j5+k5
Think "Vector addition" here.

w(1:5)=j(1:5) + k(1:5);
is the same that:
for i=1:5
w(i)=j(i)+k(i);
end

MATLAB uses vectors and matrices, and is heavily optimized to handle operations on them efficiently.
The expression w(1:5) means a vector consisting of the first 5 elements of w; the expression you posted adds two 5 element vectors (the first 5 elements of j and k) and assigns the result to the first five elements of w.

I think your problem comes from the way how do you call this statement. It is not an iteration, but rather simple assignment. Now we only need to understand what was assigned to what.
I will assume j,k, w are all vectors 1 by N.
j(1:5) - means elements from 1 to 5 of the vector j
j(1:5) + k(1:5) - will result in elementwise sum of both operands
w(1:5) = ... - will assign the result again elementwise to w
Writing your code using colon notation makes it less verbose and more efficient. So it is highly recommended to do so. Also, colon notation is the basic and very powerful feature of MATLAB. Make sure you understand it well, before you move on. MATLAB is very well documented so you can read on this topic here.

Related

Dot Product: * Command vs. Loop gives different results

I have two vectors in Matlab, z and beta. Vector z is a 1x17:
1 0.430742139435890 0.257372971229541 0.0965909090909091 0.694329541928697 0 0.394960106863064 0 0.100000000000000 1 0.264704325268675 0.387774594078319 0.269207605609567 0.472226643323253 0.750000000000000 0.513121013402805 0.697062571025173
... and beta is a 17x1:
6.55269487769363e+26
0
0
-56.3867588816768
-2.21310778926413
0
57.0726052009847
0
3.47223691057151e+27
-1.00249317882651e+27
3.38202232046686
1.16425987969027
0.229504956512063
-0.314243264212449
-0.257394312588330
0.498644243389556
-0.852510642195370
I'm dealing with some singularity issues, and I noticed that if I want to compute the dot product of z*beta, I potentially get 2 different solutions. If I use the * command, z*beta = 18.5045. If I write a loop to compute the dot product (below), I get a solution of 0.7287.
summation=0;
for i=1:17
addition=z(1,i)*beta(i);
summation=summation+addition;
end
Any idea what's going on here?
Here's a link to the data: https://dl.dropboxusercontent.com/u/16594701/data.zip
The problem here is that addition of floating point numbers is not associative. When summing a sequence of numbers of comparable magnitude, this is not usually a problem. However, in your sequence, most numbers are around 1 or 10, while several entries have magnitude 10^26 or 10^27. Numerical problems are almost unavoidable in this situation.
The wikipedia page http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems shows a worked example where (a + b) + c is not equal to a + (b + c), i.e. demonstrating that the order in which you add up floating point numbers does matter.
I would guess that this is a homework assignment designed to illustrate these exact issues. If not, I'd ask what the data represents to suss out the appropriate approach. It would probably be much more productive to find out why such large numbers are being produced in the first place than trying to make sense of the dot product that includes them.

What's the most idiomatic way to create a vector with a 1 at index i?

In Matlab, suppose I would like to create a 0-vector of length L, except with a 1 at index i?
For example, something like:
>> mostlyzeros(6, 3)
ans =
0 0 1 0 0 0
The purpose is so I can use it as a 'selection' vector which I'll multiply element-wise with another vector.
The simplest way I can think of is this:
a = (1:N)==m;
where N>=m. Having said that, if you want to use the resulting vector as a "selection vector", I don't know why you'd multiply two vectors elementwise, as I would expect that to be relatively slow and inefficient. If you want to get a vector containing only the m-th value of vector v in the m-th position, this would be a more straightforward method:
b = ((1:N)==m)*v(m);
Although the most natural method would have to be this:
b(N)=0;
b(m)=v(m);
assuming that b isn't defined before this (if b is defined, you need to use zeros rather than just assigning the Nth value as zero - it has been my experience that creating a zero vector or matrix that didn't exist before that is most easily done by assigning the last element of it to be zero - it's also useful for extending a matrix or vector).
I'm having a hard time thinking of anything more sensible than:
Vec = zeros(1, L);
Vec(i) = 1;
But I'd be happy to be proven wrong!
UPDATE: The one-liner solution provided by #GlenO is very neat! However, be aware that if efficiency is the chief criteria, then a few speed tests on my machine indicate that the simple method proposed in this answer and the other two answers is 3 or 4 times faster...
NEXT UPDATE: Ah! So that's what you mean by "selection vectors". #GlenO has given a good explanation of why for this operation a vector of ones and zeros is not idiomatic Matlab - however you choose to build it.
ps Try to avoid using i as a subscript, since it is actually a matlab function.
Just for the fun of it, another one-liner:
function [out] = mostlyzeros(idx, L)
out([L, idx]) = [0 1];
I can think of:
function mostlyones(m,n)
mat=zeros(1,m);
mat(n)=1;
Also, one thing to note. In MATLAB, index starts from one and not from zero. So your function call should have been mostlyzeros(6,3)
I would simply create a zero-vector and change whatever value you like to one:
function zeroWithOne(int numOfZeros, int pos)
a = zeros(numOfZeros,1);
a(pos) = 1;
Another one line option, which should be fast is:
vec = sparse(1, ii, 1, 1, L);

Binary operation with singleton expansion -- scalar output

There is such function as bsxfun: http://www.mathworks.com/help/techdoc/ref/bsxfun.html however it work in element-by-element mode. I want similar function which works in vector-by-vector mode (and with scalar output).
As illustration I would try to use here bsxfun in such way. As inner function I will use (this is just an example) dot product of vectors.
function f = foo(a,b), f=a'*b; printf("called\n");, end
The above dummy function foo expects 2 vector, the result is scalar. Each time it is called we will see a message.
bsxfun(#foo,[2;3],[1 5;4 3])
The result is:
called
called
ans =
14 19
0 0
So, two calls (nice), however instead of a vectors (pair of 2 scalars) we got a matrix. One can say, it will suffice to get just first row in such case, because the matrix is the created in advance by bsxfun, and the rest will be always zeros.
But it is not always a case -- sometimes I got some real values, not only zeros -- and I am afraid some side-effects are involved (the above dot product is the simplest example which came to head).
Question
So, is there a function similar to bsxfun, but which gets vectors and expects a scalar, per each operation of those vectors?
I don't think there is a built in function, but using arrayfun or cellfun you might be able to do something. Generally arrayfun is also element-wise, but if you first split your larger array into a cell then you can do it:
foo = #(a,b) b*a
y = [2;3];
X = [1 5; 4 3];
% split X into cell array of rows
% apply foo to each row
cellfun(#(x) foo(y,x), num2cell(X,2))
ans =
17
17
I am not sure it would give any speed advantage (I would imagine an explicit loop would be quicker) but sometimes it can be easier to read.

Matlab problem with writing equations

i am having problem with writing equations.
r = 25, k= 2, R = 50:25:600, DR = 0.5:0.5:4.0
h= r*[1-cos(asin((sqrt(2*R*DR+DR^2))+r*sin(acos(r-k)/r)/r))]-k
but as a resault i get this: h = 1.9118e+001 +1.7545e+002i.
I just start with Matlab. Thanks
What I get from what you've written is actually
??? Error using ==> mtimes
Inner matrix dimensions must agree.
which is correct because you're trying to multiply two row vectors by one another. Could you please show us the actual code you used?
Anyway, supposing that's dealt with somehow, it looks to me as if you're feeding something to asin that's much bigger than 1. That'll give you complex results. Is the thing you're passing to asin perhaps meant to be divided by R^2 or DR^2 or something of the kind? You have a similar issue a bit later with the argument to acos.
I also suspect that some of your * and ^ and / operators should actually be elementwise ones .*, .^, ./.
If you're trying to do as you said:
so in first equation i used R= 50, DR
= 0.5, r= 25, k=2 and i need to get h. In second equation i used R=75,
DR=1.0, r=25, k=2...for a last
equation i used
R=600,DR=4.0,r=25,k=2.
DR and R need to be the same length... so if R goes between 50 and 600 in increments of 25, DR should go from 0.5 to 12.5 in increments of 0.5, or 0.5 to 4.0 in increments of 0.1522...
once you figure that out, be sure the add a period before every matrix multiplication operation (e.g. * or ^)
EDIT: formula adjusted slightly (bracketing) to reflect success in comment.
When you say you want a table, I guess it is to be an R by DR table (since you have to vectors of different length). To do that you need to use R as a column vector (R' below) and multiply with * (not .*). When R doesn't appear in a term multiply by ones(size(R)) (or use repmat) to get DR into the right shape. To square DR by element, you need DR.^2. There seems to be a misplaced bracket for the acos, surely you divide by r before taking the acos. There must be a division by something like r in the asin (not r^2 because you've taken the sqrt). Finally, the last division by r is redundant as written, since you multiply by r at the same level just before. Anyway, if I do the following:
h= r*(1-cos(asin((sqrt(2*R'*DR+ones(size(R))'*DR.^2)/r)+sin(acos((r-k)/r)))))-k
I get an R by DR table. Results for small R,DR are real; higher R,DR are complex due to the argument of the first asin being >1. The first entry in the table is 4.56, as you require.

List all permutations of the numbers 1,...,n in lexicographic order

I'm trying to program a Matlab to list all permutations of the numbers 1 through n in lexicographic order. What I have so far is below. I am using recursion to try and write a program that will work for n=3 first, and then see if I can gain insight into writing the program for any n. So far I have 2 of the 6 columns for n=3: P=[1 2 3;1 3 2]. I need the next two columns to simply swap the ones and the twos. I don't know how to begin to do that.
function [P] = shoes(n)
if n == 1
P = 1;
elseif n == 2
P = [1 2; 2 1];
else
T = shoes(n-1) + 1;
G = ones(factorial(n-1),1);
P(1:2,1:3) = [G T];
end
See the documentation for a start. If by lexicographical order you mean alphabetical by english name, you may want to populate your input with the names, sort them, then permute that.
If I've misunderstood what you're wanting, comment or edit the question & I'll check back later.
Hints:
The permutations of an empty list are easy to find.
Induction is an important concept in mathematics. You should be familiar with it.
The environment you are working in supports recursion
The permutations of a longer list can be produced in the order you want by recursion; first figure out what you want the first element to be, and then figure out the rest.
If you get stuck again, edit the question posting what you've gotten so far and where/why you think you're stuck.
Hints after seeing your code.
Your core function permutes a vector, and so should take a vector as argument, not an integer
Don't start solving the n=3 case; try the n=0 case (it's []) and then go straight to the n=20 case.
Think about the n=20 case before you write any code. What is the first column going to look like? Are there any examples of the n=19 case hidden in the answer to the n=20 case? (The answer is yes, and they are all different).
Reread the first set of hints
You appear to have asked this question twice. Instead of reposting questions, you should simply click the "edit" link below your question and update it. I'll repost here the answer I gave to your other question, but you should really remove one of them.
If you have the following matrix:
A = [1 2 3; 1 3 2];
and you want all the ones to become twos and the twos to become ones, the following would be the simplest way to do it:
B = A;
B(A == 1) = 2;
B(A == 2) = 1;