Removing consecutive duplicates from vector MATLAB - matlab

Here is my MATLAB code:
[numeric, pics] = xlsread('matrix.xls');
[r,c] = size(pics);
done = r*c;
randvecall = randsample(done, done, true);
randvec = randvecall([1,diff(randvecall)]~=0);
currk = randvec(k);
Essentially what this does is it builds an array of values from a Microsoft Excel spreadsheet. I want to have duplicates in the array, but not consecutive duplicates, so I added a line of code that removes them. When I manually enter values into randvecall and run the above code, it works perfectly. However, when I run the code as seen above, I get the following error:
??? Error using ==> horzcat
CAT arguments dimensions are not consistent.
Error in ==> testAS_randsample at 76
randvec = randvecall([1,diff(randvecall)]~=0);
Why is this happening? For example, this works:
randvecall=[1 2 3 4 5 5 5 5 8 7 8 8];
randvec = randvecall([1,diff(randvecall)]~=0);
disp(randvec)
randvec = [1 2 3 4 5 8 7 8]
That is exactly what I want my code to do. But why does my actual code give me the horzcat error message? Can anybody help me with this? It must have something to do with the way randsample is building the randvecall array, but I can't figure out why this would give me that error message?

That seems to be a problem with how randsample(n,k,true) works: it returns a 1xk vector, while you need a kx1 vector. Transposing randvecall should do the trick.
EDIT:
Let me rephrase it in code for the general reader:
randvec = randvecall([1,diff(randvecall')]~=0);

Related

Content of a uitable is not being saved

I'm trying to write a GUI for several purposes, that looks like this,
one of them is create a matrix based on user input via a uitable, so in the untitled_OpeningFcn it was predefined the size and enabled the cell edition
set(handles.uitable1,'Data',cell(2,3));
set(handles.uitable1,'ColumnEditable',true(1,3))
inside the pushbutton2_Callback, I try to read the data written in the table, store it and display in a static text field:
value=get(handles.uitable1,'Data');
value=str2double(value);
set(handles.text2,'String',num2str(value));
But when it is running the text field says "NaN", so the data is not being saved.
What else it is needed?
UPDATE
Thanks by the aswer it does not give the expected results
When using the original code it gives the next output
and when using the suggeste mat2str I got this
I believe the reason for your problem is that the line
value = get(handles.uitable1,'Data');
doesn't result in anything that is convertible to a number.
Consider the following example:
hF = uifigure(); % works the same way with `figure()`.
hT = uitable(hF,'Data',[1 2 3; 4 5 6]);
Then, consider the following:
>> hT.Data
ans =
1 2 3
4 5 6
>> class(hT.Data)
ans =
'double'
>> str2double(hT.Data)
ans =
NaN
>> mat2str(hT.Data)
ans =
'[1 2 3;4 5 6]'
In conclusion - what you need is likely mat2str.

How can I make reverse function of diff of Matlab? [duplicate]

I am trying to resolve why the following Matlab syntax does not work.
I have an array
A = [2 3 4 5 8 9...]
I wish to create an indexed cumulative, for example
s(1) = 2; s(2)=5, s(3)=9; ... and so on
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
The logic is that if a vector is created for s using x, why would not the sum function behave the same way? The above returns just the first element (2) for all x.
For calculating the cumulative sum, you should be using cumsum:
>> A = [2 3 4 5 8 9]
A =
2 3 4 5 8 9
>> cumsum(A)
ans =
2 5 9 14 22 31
The issue is that 1:x is 1 and that sum reduces linear arrays. To do this properly, you need a 2d array and then sum the rows:
s(x)=sum(triu(repmat(A,[prod(size(A)) 1])'))
You are asking two questions, really. One is - how do I compute the cumulative sum. #SouldEc's answer already shows how the cumsum function does that. Your other question is
Can someone please explain why the following does not work
x = 1:10
s(x) = sum(A(1:x))
It is reasonable - you think that the vector expansion should turn
1:x
into
1:1
1:2
1:3
1:4
etc. But in fact the arguments on either side of the colon operator must be scalars - they cannot be vectors themselves. I'm surprised that you say Matlab isn't throwing an error with your two lines of code - I would have expected that it would (I just tested this on Freemat, and it complained...)
So the more interesting question is - how would you create those vectors (if you didn't know about / want to use cumsum)?
Here, we could use arrayfun. It evaluates a function with an array as input element-by-element; this can be useful for a situation like this. So if we write
x = 1:10;
s = arrayfun(#(n)sum(A(1:n)), x);
This will loop over all values of x, substitute them into the function sum(A(1:n)), and voila - your problem is solved.
But really - the right answer is "use cumsum()"...
Actually what you are doing is
s(1:10)= sum(A(1:[1,2,3...10]))
what you should do is
for i=1:10
s(i)=sum(A(1:i))
end
hope it will help you

matlab reshape function - error on number of elements

Hi I have the following code
A = squeeze(hourly_surplus(1,1,1,:));
B = reshape(A,365,24);
Where size(A) = 8760 x 1
however I get the error
Error using reshape
To RESHAPE the number of elements must not change
This error appears on the line of "B", however I think that A has 8760 elements and B = 365 x 24 which also is 8760. What could be going wrong?
Thanks
This:
A=rand(8760,1);
B=reshape(A,365,24);
works fine, so the problem is with your A.

splitting a Matrix into column vectors and storing it in an array

My question has two parts:
Split a given matrix into its columns
These columns should be stored into an array
eg,
A = [1 3 5
3 5 7
4 5 7
6 8 9]
Now, I know the solution to the first part:
the columns are obtained via
tempCol = A(:,iter), where iter = 1:end
Regarding the second part of the problem, I would like to have (something like this, maybe a different indexing into arraySplit array), but one full column of A should be stored at a single index in splitArray:
arraySplit(1) = A(:,1)
arraySplit(2) = A(:,2)
and so on...
for the example matrix A,
arraySplit(1) should give me [ 1 3 4 6 ]'
arraySplit(2) should give me [ 3 5 5 8 ]'
I am getting the following error, when i try to assign the column vector to my array.
In an assignment A(I) = B, the number of elements in B and I must be the same.
I am doing the allocation and access of arraySplit wrongly, please help me out ...
Really it sounds like A is alread what you want--I can't imagine a scenario where you gain anything by splitting them up. But if you do, then your best bet is likely a cell array, ie.
C = cell(1,3);
for i=1:3
C{i} = A(:,i);
end
Edit: See #EitanT's comment below for a more elegant way to do this. Also accessing the vector uses the same syntax as setting it, e.g. v = C{2}; will put the second column of A into v.
In a Matlab array, each element must have the same type. In most cases, that is a float type. An your example A(:, 1) is a 4 by 1 array. If you assign it to, say, B(:, 2) then B(:, 1) must also be a 4 by 1 array.
One common error that may be biting you is that a 4 by 1 array and a 1 by 4 array are not the same thing. One is a column vector and one is a row vector. Try transposing A(:, 1) to get a 1 by 4 row array.
You could try something like the following:
A = [1 3 5;
3 5 7;
4 5 7;
6 8 9]
arraySplit = zeros(4,1,3);
for i =1:3
arraySplit(:,:,i) = A(:,i);
end
and then call arraySplit(:,:,1) to get the first vector, but that seems to be an unnecessary step, since you can readily do that by accessing the exact same values as A(:,1).

Set variable in Matlab Dataset array to a single value

Let's say I have a dataset array (from the statistics toolbox):
>> myds
myds =
Observation SheepCount
1 88
2 2
3 14
4 12
5 40
I'm putting together data from various sources, so I'd like to set 'Location' to be 4 in all of these observations, before I vertcat this dataset together with others. In a normal matrix, you'd say myds(:, 3) = 4, which would broadcast the 4 into all of the spaces in the matrix.
Is there a way to do that on a dataset without using repmat?
Things I've tried that don't work:
myds(:, 'Location') = 4
myds(:).Location = 4
myds.Location(:) = 4
myds.Location = 4
Things that work:
myds.Location = 4; myds.Location(:) = 4; % have to run both
myds.Location = repmat(4, length(myds), 1);
So, do I have to get over my aversion to repmat? Thanks.
edit: I guess what I actually want is to avoid specifying the dimensions of the array of 4's.
You can try using ones instead of repmat.
myds.Location=4*ones(1,5);
it's not elegant but you can also try:
myds.Location= myds.Observation*0 + 4;