How to slice array in GUI function? - arrays

Because I am trying to let a GUI element slice my array, there will be a : (colon) sign in the variables. This returns me an error:
Error in gui_mainfcn (line 96)
feval(varargin{:});
line 96 refers to this code:
image(handles.data(1:handles.rows,1:handles.cols, temp))
Temp looks like this
temp =
1 1 1 1 2 1 1 1 1
And both handles.rows and cols are the value 64. So the problem seems to be that I use colons in the gui function. However, to slice I need to use colons. My question now is: Any idea how to work around this?
To clarify as requested below
The above code works when I manually enter it in the console. Also when I use handles.data(:,:,1,1,1,1,2,1,1,1,1), handles.data(1:end,1:end,1,1,1,1,2,1,1,1,1), handles.data(1:64,1:64,1,1,1,1,2,1,1,1,1), etc I get the same error from the gui. Manually they all work and return a 64 by 64 array of doubles which I can plot with image().
Might be related to these questions, however those deal with parfor difficulties and dont seem to answer my question:
matlab-parfor-slicing-issue
index-inside-parfor-slicing
I am now also reading the advanced topics for slicing variables. Still dont see what I am doing wrong though, so any help or explanation would still be greatly apprectiated. Thanks!

Explanation
By putting the vector temp as the third index into your data, you are not indexing the higher dimensions - you are repeatedly indexing the third. In other words, you get handles.data(:,:,[1 1 1 1 2 1 1 1 1]) instead of handles.data(:,:,1,1,1,1,2,1,1,1,1).
Solution
Here's a solution that doesn't require squeeze or eval. It exploits the comma-separated lists output of the {:} syntax with cell arrays, and the ability to apply linear indexing on the last subscripted dimension.
ctemp = num2cell(temp); % put each index into a cell
sz = size(handles.data); % i.e. sz = [256 256 1 1 2 1 2]
sliceind = sub2ind(sz(3:end),ctemp{:}); % compute high dim. linear index (scalar)
image(handles.data(:,:,sliceind));
This performs subscripting of a >3D array with only 3 subscripts by computing the last subscript as a linear index. It's weird, but convenient sometimes.

A heads up for people with the same problem, this error can not only result from not knowing how to slice, it could also result from not having defined your variables correctly: http://www.mathworks.nl/matlabcentral/answers/87417-how-to-slice-inside-gui-without-error-feval-varargin

Related

arrayfun to bsxfun possible

I know that bsxfun(which works fast!) and arrayfun(as far as I could understand, uses loops internally which is expected to be slow) are intended for different uses, at least, at the most basic level.
Having said this, I am trying
to sum up all the numbers in a given array, say y, before a certain index
add the number at the specific location(which is the number at the above index location) to the above sum.
I could perform this with the below piece of example code easily:
% index array
x = [ 1:6 ]; % value array
y = [ 3 3 4 4 1 1 ];
% arrayfun version
o2 = arrayfun(#(a) ...
sum(y(1:(a-1)))+...
y(a), ...
x)
But it seems to be slow on large inputs.
I was wondering what would be a good way to convert this to a version that works with bsxfun, if possible.
P.S. the numbers in y do not repeat as given above, this was just an example, it could also be [3 4 3 1 4 ...]
Is x always of the form 1 : n? Assuming the answer is yes, then you can get the same result with the much faster code:
o2 = cumsum(y);
Side note: you don't need the brackets in the definition of x.
if you have a supported GPU device, you can define your variables as gpuArray type since arrayfun, bsxfun and pagefun are compatible with GPUs.
GPU computing is supposed to be faster for large data.

matlab rearrange (permute) string array

I have a string array:
size(entries)
ans =
1 19413
I would like to rearrange the array to 4853 rows and 4 columns:
output=permute(entries,[4853 4]);
but get following error:
Error using permute ORDER contains an invalid permutation index.
What is the (probably obvious thing) I am doing wrong? thanks
You currently have 19413 elements, yet you wish to reshape this into a 4853 x 4 matrix that consists of 4853 * 4 = 19412 elements. No function in the world will help you do this because the original and target amount of elements don't match - they're off by one element. If you remove one of the elements...say... the last one, then we're getting somewhere.
Supposing you made a mistake and included that extra element by accident, you don't use permute here, but you use reshape. The second argument to reshape is the amount of elements to spread out for each target dimension, and that's what you're looking for. First remove the extraneous element that appears at the end of the array, then reshape the matrix:
output = reshape(entries(1:end-1),[4853 4]);
I'm 3 years late, but here's to anyone still looking for an answer.
In your case as mentioned above, yes you should use reshape() while minding that you preserve the total number of elements.
You use permute() when you want to reorder the dimensionality of an n-dimensional (ND) matrix.
The ORDER parameter specifies the order of the columns.
For example, if matrix A is LxMxN, the following line would make it MxLxN.
A = permute(A,[2 1 3]);
Hope this clears things.

No. of paths in integer array

There is an integer array, for eg.
{3,1,2,7,5,6}
One can move forward through the array either each element at a time or can jump a few elements based on the value at that index. For e.g., one can go from 3 to 1 or 3 to 7, then one can go from 1 to 2 or 1 to 2(no jumping possible here), then one can go 2 to 7 or 2 to 5, then one can go 7 to 5 only coz index of 7 is 3 and adding 7 to 3 = 10 and there is no tenth element.
I have to only count the number of possible paths to reach the end of the array from start index.
I could only do it recursively and naively which runs in exponential time.
Somebody plz help.
My recommendation: use dynamic programming.
If this key word is sufficient and you want the challenge to find a possible solution on your own, dont read any further!
Here a possible DP-algorithm on the example input {3,1,2,7,5,6}. It will be your job to adjust on the general problem.
create array sol length 6 with just zeros in it. the array will hold the number of ways.
sol[5] = 1;
for (i = 4; i>=0;i--) {
sol[i] = sol[i+1];
if (i+input[i] < 6 && input[i] != 1)
sol[i] += sol[i+input[i]];
}
return sol[0];
runtime O(n)
As for the directed graph solution hinted in the comments :
Each cell in the array represents a node. Make an directed edge from each node to the node accessable. Basically you can then count more easily the number of ways by just looking at the outdegrees on the nodes (since there is no directed cycle) however it is a lot of boiler plate to actual program it.
Adjusting the recursive solution
another solution would be to pruning. This is basically equivalent to the DP-algorithm. The exponentiel time comes from the fact, that you calculate values several times. Eg function is recfunc(index). The initial call recFunc(0) calls recFunc(1) and recFunc(3) and so on. However recFunc(3) is bound to be called somewhen again, which leads to a repeated recursive calculation. To prune this you add a Map to hold all already calculated values. If you make a call recFunc(x) you lookup in the map if x was already calculated. If yes, return the stored value. If not, calculate, store and return it. This way you get a O(n) too.

Entering Elements in a 4-D array in the Correct Orientation

In the code below "G" returns a (10*4) matrix which is in the correct orientation.
All I want then is to be able to view/call these (10*4) matrices indexed by (j,k). However when I store the matrix "G" in the 4-D matrix "test" the data is displayed in a way that is a little counter intuitive? When I look at test in the variable editor I get:
val(:,:,1,1) =
1
val(:,:,2,1) =
0
val(:,:,3,1) =
0
val(:,:,4,1) =
0
.
.
.
val(:,:,1,10) =
1
val(:,:,2,10) =
0
val(:,:,3,10) =
0
val(:,:,4,10) =
0
So all the data is there but I want it displayed at a 10*4 matrix?
Also as you will see I had to change the code for "Correl_betas" and transpose "G" to get to where I am above. However I felt I did this by playing around rather than what I thought the code should be doing. Why does the original code not work? I am having to change the order of the 3rd and 4th dimensions when declaring "Correl_betas" and then pass the transpose of G, but this seems totally counter intuitive as the last two dimensions in the original "Correl_betas" and the original (un-transposed) "G" also match? But when I did it this way the ordering seemed even further from the 10*$ matrix I want.
So I have 2 questions?
1.) How can I get to the 2-dimentional (10*4) matrices I want indexed by j,k from where I am?
2.) How come the original code above doesn't result in the last two columns producing (10,4) matrices?
A large part of the problem is that I have very little experience working with matrices that have more than 2 dimensions so sorry if this question shows a lack of understanding. Maybe a pointer to a god tutorial on how to interpret manipulate higher dimensional matrices would help too.
%Correl_betas=zeros(50,50,10,4);
Correl_betas=zeros(50,50,4,10);
mats=[1:10]';
L1=-1;
for j=1:51
L1=L1+1;
L2=-1;
for k=1:51
L2=L2+1;
lambda=[ L1; L2 ];
nObs=size(mats,1);
G= [ones(nObs,1) (1-exp(-mats./lambda(1)))./(mats./lambda(1)) ((1-exp(-mats./lambda(1)))./(mats./lambda(1))-exp(-mats./lambda(1))) ((1-exp(-mats./lambda(2)))./(mats./lambda(2))-exp(-mats./lambda(2)))];
%Correl_betas(j,k,:,:)=G;
Correl_betas(j,k,:,:)=G';
test=Correl_betas(j,k,:,:);
temp1=corrcoef(Correl_betas(j,k,:,2),Correl_betas(j,k,:,3),'rows','complete');
temp2=corrcoef(Correl_betas(j,k,:,2),Correl_betas(j,k,:,4),'rows','complete');
temp3=corrcoef(Correl_betas(j,k,:,3),Correl_betas(j,k,:,4),'rows','complete');
F2_F3(j,k)=temp1(1,2);
F2_F4(j,k)=temp2(1,2);
F3_F4(j,k)=temp3(1,2);
end
end
To reshape the matrix as desired,
val2 = permute(val,[4 3 2 1]);
This brings the 4th dimension (size of 10) onto the first, and the the 3rd dimension (size of 4) onto the second.
In your loop, both j and k cycle through 1:51 so the first two dimensions of Correl_betas will end up being length 51 too.

Finding whether a value is equal to the value of any array element in MATLAB

Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?
The way I intend to use it is to check whether an element index in one matrix is equal to the values stored in another array (where the stored values are the indices of the elements which meet a certain criteria).
So, if the indices of the elements which meet the criteria are stored in the matrix below:
criteriacheck = [3 5 6 8 20];
Going through the main array (called array) and checking if the index matches:
for i = 1:numel(array)
if i == 'Any value stored in criteriacheck'
%# "Do this"
end
end
Does anyone have an idea of how I might go about this?
The excellent answer previously given by #woodchips applies here as well:
Many ways to do this. ismember is the first that comes to mind, since it is a set membership action you wish to take. Thus
X = primes(20);
ismember([15 17],X)
ans =
0 1
Since 15 is not prime, but 17 is, ismember has done its job well here.
Of course, find (or any) will also work. But these are not vectorized in the sense that ismember was. We can test to see if 15 is in the set represented by X, but to test both of those numbers will take a loop, or successive tests.
~isempty(find(X == 15))
~isempty(find(X == 17))
or,
any(X == 15)
any(X == 17)
Finally, I would point out that tests for exact values are dangerous if the numbers may be true floats. Tests against integer values as I have shown are easy. But tests against floating point numbers should usually employ a tolerance.
tol = 10*eps;
any(abs(X - 3.1415926535897932384) <= tol)
you could use the find command
if (~isempty(find(criteriacheck == i)))
% do something
end
Note: Although this answer doesn't address the question in the title, it does address a more fundamental issue with how you are designing your for loop (the solution of which negates having to do what you are asking in the title). ;)
Based on the for loop you've written, your array criteriacheck appears to be a set of indices into array, and for each of these indexed elements you want to do some computation. If this is so, here's an alternative way for you to design your for loop:
for i = criteriacheck
%# Do something with array(i)
end
This will loop over all the values in criteriacheck, setting i to each subsequent value (i.e. 3, 5, 6, 8, and 20 in your example). This is more compact and efficient than looping over each element of array and checking if the index is in criteriacheck.
NOTE: As Jonas points out, you want to make sure criteriacheck is a row vector for the for loop to function properly. You can form any matrix into a row vector by following it with the (:)' syntax, which reshapes it into a column vector and then transposes it into a row vector:
for i = criteriacheck(:)'
...
The original question "Can anyone tell me if there is a way (in MATLAB) to check whether a certain value is equal to any of the values stored within another array?" can be solved without any loop.
Just use the setdiff function.
I think the INTERSECT function is what you are looking for.
C = intersect(A,B) returns the values common to both A and B. The
values of C are in sorted order.
http://www.mathworks.de/de/help/matlab/ref/intersect.html
The question if i == 'Any value stored in criteriacheck can also be answered this way if you consider i a trivial matrix. However, you are proably better off with any(i==criteriacheck)

Resources