How to divide an absolute value of a vector in MATLAB - matlab

I want to find a vector operation such that every positive element becomes 1 and negative element becomes -1 and 0 remains 0. The first idea come to my mind is to use the following code,
a=[0.0023 0 -0.0011];
b=a./abs(a);
However, this fails to keep the 0 element in the original vector, which gives an NaN instead. How to realize this in Matlab without using a for loop? Thanks.

Use the sign function:
b=sign(a)

Related

Unexpected matlab behaviour when using vectorised assignment

I've come across some unexpected behaviour in matlab that I can't make sense of when performing vectorised assignment:
>> q=4;
>> q(q==[1,3,4,5,7,8])
The logical indices contain a true value outside of the array bounds.
>> q(q==[1,3,4,5,7,8])=1
q =
4 0 1
Why does the command q(q==[1,3,4,5,7,8]) result in an error, but the command q(q==[1,3,4,5,7,8])=1 work? And how does it arrive at 4 0 1 being the output?
The difference between q(i) and q(i)=a is that the former must produce the value of an array element; if i is out of bounds, MATLAB chooses to give an error rather than invent a value (good choice IMO). And the latter must write a value to an array element; if i is out of bounds, MATLAB chooses to extend the array so that it is large enough to be able to write to that location (this has also proven to be a good choice, it is useful and used extensively in code). Numeric arrays are extended by adding zeros.
In your specific case, q==[1,3,4,5,7,8] is the logical array [0,0,1,0,0,0]. This means that you are trying to index i=3. Since q has a single value, reading at index 3 is out of bounds, but we can write there. q is padded to size 3 by adding zeros, and then the value 1 is written to the third element.

Creating a path on coordinate system without repeating values (Matlab)

I'm trying to create a random "path" on a coordinate system on Matlab. I am doing this by creating a for loop where for each iteration it fills in a new value on a matrix that has initial values of zeros.
For example, I have 5 points so I have an initial matrix a=[0 0 0 0 0; 0 0 0 0 0] (row1 = x values, row2 = y values).
The path can move right/left or up/down (no diagonals). In my for loop, I call randi(4) and say something like "if randi(4)=1, then move 1 point to the left (x-1). if randi(4)=2, then move to the right (x+1), etc."
The problem is that you cannot visit a specific point more than once. For example, the path can start at (0,0), then go to (0,1), then (1,1), then (1,0), and then it CANNOT go back to (0,0).. in my current code I don't have this restriction so I was hoping I could get some suggestions..
Since in this example the matrix would look something like a=[0 0 1 1 0; 0 1 1 0 0].
I was thinking of maybe subtracting each new coordinate (here (0,0)) from each column on the matrix a and if any of the columns give me values of zero for both rows (since it's the same coordinate subtracted from itself), then go back one step and let randi(4) run again.. but
How could I tell it to "go back one step" (or two or three)?
How do you compare one column against each column of the already established matrix?
This was just an idea.. are there any functions in Matlab that would let me do this? or maybe compare if two columns are the same within a matrix?
To your questions.
to go back - I suppose this means just throwing away the rightmost columns in your matrix.
to find if it is present you could use ismember
unfortunately it only takes rows so you will need to transpose. Snippet:
a = [1:10; repmat(1:2,1,5)]'
test = ismember(a,[3,2],'rows')
any(test) % not found
test = ismember(a,[3,1],'rows')
any(test) % found
Of course your idea would also work.
I can answer this:
How do you compare one column against each column of the already
established matrix?
Use two different matrices. Compare them using the setdiff() function: http://www.mathworks.com/help/matlab/ref/setdiff.html

Subselecting matrix and use logical selection (matlab)

I have a line of code in matlab for which i am selecting a subset of a matrix:
A(3:5,1:3);
Now i want to adapt this line, to only select rows for which all three values are larger than zero:
(A(3:5,1:3) > 0);
But apparently i am not doing this right. How do i select part of the matrix, and also make sure that only the rows (for which all three values are) larger than zero are selected?
EDIT: To clarify: lets say that i have a matrix of coordinates called A, that looks like this:
Matrix A [5,3]
3 4 0
0 1 0
0 3 1
0 0 0
4 8 7
Now i want to select only part [3:5,1:3], and of that part i only want to select row 3 and 5. How do i do that?
The expression:
A(find(sum(A(3:5,:),2)~=0),:)
will return only the rows of A(3:5,:) which have a row-sum not equal to zero.
If you had posted syntactically correct Matlab it would have been easier for me to cut and paste your test data into my Matlab session.
I'm modelling this answer off of A(find( A > 0 ))
distances = pdist(find( pdist(medoidContainer(i,1:3)) > 0 ));
This will give you a vector of values in the distances variable. The reason the pdist(medoidContainer(i,1:3) > 0) does not work is because it first, finds the indices specified by i,1:3 in medoidContainer. Then it finds the indices in medoidContainer(i,1:3) that are greater than 0. However, since medoidContainer(i,1:3) and pdist now likely have different dimensions, the comparison does not give the right indexes.

using linspace in matlab

I want to create a vector which runs from 1 to 260 with increments of 360 between every whole number.
I can do this manually by: y=linspace(1,2,360); y1=linspace(2,3,360);... and so on.
By combining these I would have a vector which was 260*360=93600 long. However, there must be a easier way of doing this? preferably without a loop.
Maybe you can just do:
n=261;
linspace(1,n,(n-1)*360);
And what about y=(1:1/360:260) ?
Or if you want to have exactly 360 elements between 1 and 2 (included) as it seems from your use of linspace(1,2,360) you could do y=(1:1/359:260).
Also, your final vector would have less than 360*260 elements as you have to account for duplicates.

How can I test submatrices of a matrix to see if they contain all zeroes?

I've a large matrix, say A[1,10,10000], which contains 10000 1-by-10 submatrices. I want to check each of these submatrices to find which ones contain all zeroes. How can I do this?
You could do this using the functions ALL and SQUEEZE:
allZeroIndex = squeeze(all(all(A == 0,2),1));
And this will give you a logical vector allZeroIndex that has the same length as the third dimension of A and contains a 1 (i.e. true) for matrices that have all zeroes and 0 (i.e. false) for matrices that contain non-zero values.
NOTE: Of course the above would really only be appropriate for a matrix of integer values. If there is the chance that you will have floating point values in A, then odds are good that you may never get exactly 0 for a value. In such a case, you need to check for values that are within some threshold of 0, like so:
allNearZeroIndex = squeeze(all(all(abs(A) < 1e-10,2),1));
The simple answer is to use nnz.
if nnz(A) == 0
disp('Yup, this is one really boring matrix.')
end
Instead of all, you can also use sum:
allZero = sum(sum(A==0)); % will be non-zero if there are non-zero values
I think using nnz is probably the best bet, but didn't know about that until now. Instead I would have used unique(): if unique(A)==0 ...