How to make ndgrid work with 1-dimensional data in MATLAB? - matlab

First of all, I could not find a better title to describe my problem, sorry for that. Maybe someone could suggest a better title.
I have the following code:
gridSize = (gridResolution - 1) .* gridStepSize;
positionsVectorY = gridSize(1) / 2 : -gridStepSize(1) : -gridSize(1) / 2;
positionsVectorX = -gridSize(2) / 2 : gridStepSize(2) : gridSize(2) / 2;
[ gridPositionMatrixY, gridPositionMatrixX ] = ndgrid(positionsVectorY, positionsVectorX);
This code works fine for me if gridSize(1) > 0, gridSize(2) > 0 and if gridResolution(1) > 1, gridResolution(2) > 1. However, if that is not the case, the matrix / matrices are empty. For example, [y, x] = ndgrid([], 1 : 3) returns empty matrices: Empty matrix: 0-by-3. What I would need in that case is [y, x] = ndgrid(0, 1 : 3).
So, my question is: What is the best way to change the above code to create the desired matrices?
I could simply check if positionsVectorY is empty and replace it with zeros. But I'm wondering if there is a more "elegant" solution to this.
Thank you,
Adrian
EDIT: An example:
Here is an example where my code works:
positionsVectorY = 1 : 2;
positionsVectorX = 1 : 3;
[y, x] = ndgrid(positionsVectorY, positionsVectorX)
The output is
y =
1 1 1
2 2 2
x =
1 2 3
1 2 3
And here is a special case where it does not work: If the resolution in y direction is 1, and the size of the grid is 0 in y direction, then my code generates an empty array positionsVectorY. Then:
positionsVectorY = [];
positionsVectorX = 1 : 3;
[y, x] = ndgrid(positionsVectorY, positionsVectorX)
The output is:
y =
Empty matrix: 0-by-3
x =
Empty matrix: 0-by-3
That is not what I want, I want that my code generates
positionsVectorY = 0; % instead of []
positionsVectorX = 1 : 3;
[y, x] = ndgrid(positionsVectorY, positionsVectorX)
in this special case, with the output:
y =
0 0 0
x =
1 2 3
What I want in the end, is to modify my code so it works for the general case, but also for the special case where the resolution in y or x direction can be 1. My temporary solution is using if-statements,
if(isempty(positionsVectorY))
positionsVectorY = 0;
end
if(isempty(positionsVectorX))
positionsVectorX = 0;
end
But I would like to remove them and do it in a more elegant way.

Related

Perform a successive XOR along rows

I'm trying to figure out how to perform a successive XOR on a row in matlab, where each element is the result of XORing itself and the previous element, for example:
If the row is
x = [1 0 1 1]
I would want the result to be:
x[0] = 1
x[1] = x[0]^x[1] = 1
x[2] = x[1]^x[2] = 0
x[3] = x[2]^x[3] = 1
x = [1 1 0 1]
I have tried using xor(A,B) but this only seems to work on multiple arrays at once. I also have tried this loop:
for k = 10000:1
for i = 1:64
allchallenge_full(k,i+1) = xor(allchallenge_full(k,i).^allchallenge_full(k,i+1))
end
end
But this simply results in all 1s.
Any suggestions are appreciated! Thank you!
If the input x is just zeros and ones:
result = mod(cumsum(x), 2);
To apply it on each row of a matrix x:
result = mod(cumsum(x,2), 2);
If you want to keep things simple, a for loop, together with the xor function (^ in Matlab represents the raising to a power), should work fine:
x = [1 0 1 1];
for i = 2:numel(x)
x(i) = xor(x(i-1),x(i));
end
The final output is the expected one:
x =
1 1 0 1
Remember that, in Matlab, indexing is one-based and not zero-based as in many other programming languages. The first element of x is, therefore, x(1) and not x(0).

Matlab: All combinations of binary matrix

I am looking for a simple way to get all combinations of an binary matrix. I tried already the function perms() but did not get a proper result.
I have for example an matrix N x N filled up with 1 and -1. With N=2 there would be 2^4 possible combinations of 1 and -1 like
(1 1) (1 1) (-1 -1)
M(1) = (1 1) , M(2) = (1 -1) , M(3) = ( 1 1) and so on...
When I use perms() I don't get for example the first matrix.
How can I fix that?
You can represent all numbers between 0 and 2^(N^2)-1 as binary numbers, and then reshape:
N = 2;
v = (1:2^(N^2))-1;
A = dec2bin(v)' - '0'; %'// Or use: decimalToBinaryVector(v)';
A(A==0) = -1;
A = reshape(A,N,N,2^(N^2));
A simple hack is as follows:
v = [1 -1 1 -1];
P = perms(v);
for ii = 1:size(P,1)
A = reshape(P(ii,:),2,2)
end
which results in:
A =
-1 -1
1 1
...
Still there are some identical matrices in the result which should be removed.
I think that I found an solution to my problem
L = 2;
N = L^2;
v = cell(N,1);
for k = 1:N
v{k} = linspace(-1,1,2);
end
ne=numel(v);
x=cell(ne,1);
[x{1:ne,1}]=ndgrid(v{end:-1:1});
p=reshape(cat(ne+1,x{:}),[],ne);
F = cell(length(p),1);
for k=1:length(p)
F{k} = reshape(p(k,:),L,L);
end

Can't figure out "if else" code correctly?

if APC<-2.9079
BUYz='z'
SELLy='y'
elseif APC>0.44
BUYy='y'
SELLz='z'
else
end
x and y are both single column matrices.
I want the system to check if the APC column is above or below the values as mentioned above, if yes, pick up corresponding values from x and y.
Do you think I have entered this correctly?
When I try the code it does not create BUYy or any of the others.
Thanks for all the help.
Clarification:
I have loaded an excel file in Matlab using xlsread. It has columns such as x, y, APC, Date etc.
I am using the "if else" statement in the command window after loading the file.
First a brief introduction to if and elseif for vectors.
Suppose A = [1 2 3], then the following will not result in B = 5.
if A > 2
B = 5;
end
The reason for this is because what the if sees is (A > 2) == [0 0 1]. The first 0 will cause the statement to be false, thus it will skip the rest.
Similarly, the following will also not result in B = 5.
if A < 2
B = 5;
end
The reason for this is because the if now sees (A < 2) == [1 0 0]. The if requires all of the elements to be true for it to "jump into it". The two below are equivalent:
if A < x
and
if all(A < x)
elseif behaves the exact same way.
Suppose y = [1 2 3], doing x = 'y' will not give you x = [1 2 3] but x = y (the character "y", not the variable. If you want the x variable to be equal to the y variable you simply do x = y.
So, what can you do?
If I understand you correctly, you have a vectors similar to this (might be decimals, but that doesn't matter).
APC = [1, -3, 4, -2, 0];
x = [1 2 3 4 5];
y = [6 7 8 9 10];
You want BUYx = x(2), and SELLy = y(2) since the second element is the only one in APC that's less than -2.9079.
You also want BUYy = [y(1), y(3)] and SELLx = [x(1), x(3)], since the first and third element of APC is larger than 0.44.
What you can do is:
BUYx = x(APC < -2.9079)
SELLy = y(APC < -2.9079)
BUYy = y(APC > 0.44)
SELLx = x(APC > 0.44)
This returns:
BUYx =
2
SELLy =
7
BUYy =
6 8
SELLx =
1 3
If you only want the first elements and not all of them, you can use find like this:
BUYx = x(find(APC < -2.9079,1,'first'))
SELLy = y(find(APC < -2.9079,1,'first'))
BUYy = y(find(APC > 0.44,1,'first'))
SELLx = x(find(APC > 0.44,1,'first'))
find(x < y, 5, 'first') find the first 5 elements where x < y. find(APC < -2.9079, 1, 'first') finds only the first element where APC < -2.9079.
or just do as the first approach and then: BUYx = BUYx(1) to only get the first elements.
It might be I have misinterpreted your question, but I think this will get you well on your way nevertheless. Good luck!

Obtain matrix of indices in octave / matlab

Given some multidimensional matrix A in Octave / Matlab,
What's the easiest way to get a matrix of the same size as A where all elements are replaced by their index along the k'th dimension
ie for the matrix
A =
ans(:,:,1) =
0.095287 0.191905
0.226278 0.749100
ans(:,:,2) =
0.076826 0.131639
0.862747 0.699016
I want a function f such that
f(A,1) =
ans(:,:,1) =
1 1
2 2
ans(:,:,2) =
1 1
2 2
f(A,2) =
ans(:,:,1) =
1 2
1 2
ans(:,:,2) =
1 2
1 2
and
f(A, 3) =
ans(:,:,1) =
1 1
1 1
ans(:,:,2) =
2 2
2 2
Also, given a sparse matrix B
What's the easiest way to get another sparse matrix of the same size where the nonzero elements are replaced by their index along the k'th dimension? (so same problem as above, but for only the nonzero elements)
Ideally I'm looking for a way which is well-vectorized for octave (meaning it doesn't explicitly loop over anything)
CLARIFICATION: For the sparse matrix one, I'm looking for a solution which does not involve creating a full size(B) matrix at any point
ndgrid() does what you want, although not in the format you are looking for. If you know the dims of the input A beforehand, you can use the following line to create the N-dimentional mesh grid:
% for matrix a where ndims(a) == 3
[x, y, z] = ndgrid (1:size(a,1), 1:size(a,2), 1:size(a,3));
% x is like f(a, 1)
% y is like f(a, 2)
% z is like f(a, 3)
You may be able to write a custom wrapper around ndgrid() to convert it to the function format you are looking for.
In case anyone's curious, since I didn't know about ndgrid, here's the answer I came up with:
function [y] = indices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = diag(1:n) * ones(size(y));
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction
function [y] = spindices(a,k)
s = size(a);
n = s(k);
D = length(s);
x = permute(a,[k,1:(k-1),(k+1):D]);
y = reshape(x,n,[]);
y = spdiag(1:n) * spones(y);
y = reshape(y,size(x));
y = permute(y,[(2:k),1,(k+1):D]);
endfunction

Counting Number of Specific Outputs of a Function

If I have a matrix and I want to apply a function to each row of the matrix. This function has three possible outputs, either x = 0, x = 1, or x > 0. There's a couple things I'm running into trouble with...
1) The cases that output x = 1 or x > 0 are different and I'm not sure how to differentiate between the two when writing my script.
2) My function isn't counting correctly? I think this might be a problem with how I have my loop set up?
This is what I've come up with. Logically, I feel like this should work (except for the hiccup w/ the first problem I've stated)
[m n] = size(matrix);
a = 0; b = 0; c = 0;
for i = 1 : m
x(i) = function(matrix(m,:));
if x > 0
a = a + 1;
end
if x == 0
b = b + 1;
end
if x == 1
c = c + 1;
end
end
First you probably have an error in line 4. It probably should be i instead of m.
x(i) = function(matrix(i,:));
You can calculate a, b and c out of the loop:
a = sum(x>0);
b = sum(x==0);
c = sum(x==1);
If you want to distinguish x==1 and x>0 then may be with sum(xor(x==1,x>0)).
Also you may have problem with precision error when comparing double values with 0 and 1.