1
votes

The following problem leaves me head scratching:

I am indexing a vector R with dimensions Nx1 with a matrix, ie:

R = ones( [ N nSteps ] );
R = (:);

with a matrix of indicies. Basically each row of the matrix is a row of indicies for which I need the values stored in R, this is to have vectors out of R with different offsets off a current point in R. The matrix would look like the result of:

k = 0:nSteps;
I = repmat( k , [size(D,2) 1])
I = bsxfun(@minus, I , D');
% later in code, this is used as:
currI = currPoint + currI;
% this is used for indexing just a little later
... R(currI) ...

D in this example is an array storing the different offsets I want. It works perfectly in most cases and gives me arrays of dimensions [size(D,2) nSteps] as a result of the indexing with I can use.

Here is where the problem starts: The amount of offsets is passed as a parameter to the function and can vary. Whenever I try to use just one simple offset, for example 400, I run into problems. Matlab doesn't seem to care if something gets indexed by a 1xN or Nx1 vector and always returns, in this case, a vector with dimensions [nSteps 1] instead of [1 nSteps]. As the result is then used in a call for bsxfun, the result of that function no longer is a matrix of [size(D,2) nSteps] but a [nSteps nSteps] matrix with which I can do nothing and is also ill-defined in the context of the algorithm.

TLDR: Can I make matlab give me a 1 x N array when indexing R(1:400) instead of a N x 1 array? Can I force consistency with indexing with matrices?

2
I am not entirely sure that I have understood your problem, but is the problem that you get a row vector if you initialize a variable as a(1:10) = ones(10,1) but that R(:) always gives a column vector? - patrik
the problem is, that in the general case, I index R with a matrix, for example a 5x400 matrix, which gives me a 5x400 matrix in return. R is a vector currently something like 16000000x1. Now, sometimes, the matrix with which I index is really just a 1x400 matrix. which results in me getting a 400x1 vector instead of a 1x400 which I need. Since I would love to handle everything in one case, I cant simpy transpose that vector, it would affect the other solutions. Maybe I should have put it that way in the first place :x - jaqqz
Be more specific as to why you can't simply transpose the outcome. That seems to be the way to go. - Dennis Jaheruddin
the result is used later and the dimensions matter as I use it in bsxfun. But I get two different kinds of dimension depending on a parameter I pass, and I really dont want that. - jaqqz
or: 1 time, D is an array of offsets, I create a matrix to index that R array, I get a matrix that is the number of elements in D times however long my original indexing vector is. The next time however, D is just a number, or a 1x1 vector thingy, and now I get a matrix that is the size of the indexing vector in the first dimension and 1 in the 2nd instead of the other way around, which is what happens in the first case. That annoys the shit out of me. - jaqqz

2 Answers

1
votes

I may not be entirely sure of what you mean here, but I can explain a little about vectors in matlab. I think your problem has to do with not specifying dimensions correctly.

A vector initialized as vec(1:anyNbr) = someNbr % or vector of same size is always a row vector. To make it a column vector you can do vec(1:anyNbr,1) = someNbr.

The operator (:) rearranges the pointers to each element in a vector creating a column vector. This does also mean that a matrix becomes a column vector. The operation is faster that reshape(vec,numel(vec),1).

The element in a matlab vector is indexed columnwise which means that

r = [1,4,7;2,5,8;3,6,9];
r(:)

gives a column vector [1;2;3;4;5;6;7;8;9]

However defining a variable as vec = something will make vec exactly the same as something. Also, if the variable is already initialized the assignment vec(1:anyNbr) = something, will assign something to the dimension which vec is defined in. So if vec is a columnvector, it will remain as such.

Therefore, something to think of when defining vectors and matrices, is that sometimes the dimension must be specified at the initialization. You are probably aware of most of this, but I do not exactly know what your problem is so I am sorry if I give too much information.

0
votes

Problem as I understand it (and which I also had with my own code) can be shown like this:

Data1 = rand(1,12);
Data2 = rand(3,4);
Data3 = rand(12,1);
Index1 = reshape(1:12,[12,1]);
Index2 = reshape(1:12,[6,2]);
Index3 = reshape(1:12,[3,4]);
Index4 = reshape(1:12,[2,6]);
Index5 = reshape(1:12,[1,12]);
[size(Data1(Index1)),size(Data2(Index1)),size(Data3(Index1));
size(Data1(Index2)),size(Data2(Index2)),size(Data3(Index2));
size(Data1(Index3)),size(Data2(Index3)),size(Data3(Index3));
size(Data1(Index4)),size(Data2(Index4)),size(Data3(Index4));
size(Data1(Index5)),size(Data2(Index5)),size(Data3(Index5))]

The matlab (I think by design) gives those inconsistent results (marked here by strike thru bold values)

ans =

     1    12    12     1    12     1
     6     2     6     2     6     2
     3     4     3     4     3     4
     2     6     2     6     2     6
     1    12     1    12    12     1

I came to this after hours of debugging a little more subtle errors in my own code. As no one else here in my opinion, gave an adequate answer, I'll present my ugly workaround:

ConsistentResult = reshape(Data(Index),size(Index)));

Now testing like this:

[size(reshape(Data1(Index1),size(Index1))),size(reshape(Data2(Index1),size(Index1))),size(reshape(Data3(Index1),size(Index1)));
size(reshape(Data1(Index2),size(Index2))),size(reshape(Data2(Index2),size(Index2))),size(reshape(Data3(Index2),size(Index2)));
size(reshape(Data1(Index3),size(Index3))),size(reshape(Data2(Index3),size(Index3))),size(reshape(Data3(Index3),size(Index3)));
size(reshape(Data1(Index4),size(Index4))),size(reshape(Data2(Index4),size(Index4))),size(reshape(Data3(Index4),size(Index4)));
size(reshape(Data1(Index5),size(Index5))),size(reshape(Data2(Index5),size(Index5))),size(reshape(Data3(Index5),size(Index5)]

will give this:

ans =

    12     1    12     1    12     1
     6     2     6     2     6     2
     3     4     3     4     3     4
     2     6     2     6     2     6
     1    12     1    12     1    12