Problem with sorting array algorithm - arrays

I have three arrays. And I am trying to sort all of them by one of them so. So my arrays are itemarray, pricearray, quantityarray. I want itemarray to be sorted but the corresponding arrays aren't sorting appropriately along with itemarray.
Here is the algorithm I created. Do you know how I can fix this??
DO i=1, NumItems-1
SmallestItem = MINVAL(itemarray(i:NumItems))
MINLOC_array = MINLOC(itemarray(i:NumItems))
Locationsmallest = (i-1)+MINLOC_array(1)
itemarray(Locationsmallest) = itemarray(i)
itemarray(i) = SmallestItem
pricearray(Locationsmallest) = pricearray(i)
pricearray(i) = SmallestItem
quantityarray(Locationsmallest) = quantityarray(i)
quantityarray(i) = SmallestItem
END DO

You are setting pricearray(i) to something that came from itemarray. You should be swapping pricearray(Locationsmallest) and pricearray(i), which you can do by storing the value of pricearray(Locationsmallest) in a temporary variable.
The same is true for quantityarray(i).
By the way, this is an O(n^2) algorithm, and is likely to be very slow when there are a large number of values in your array.

Related

MATLAB - repmat values into cell array where individual cell elements have unequal size

I am trying to repeat values from an array (values) to a cell array where the individual elements have unequal sizes (specified by array_height and array_length).
I hope to apply this to a larger data set (containing ~100 x ~100 values) and my current solution is to have a line of code for each value (code example below). Surely there is a better way... Please could someone offer an alternative solution?
C = cell(3,2);
values = rand(3,2);
array_height = randi(10,3,2);
array_length = randi(10,3,2);
C{1,1} = repmat((values(1,1)),[array_height(1,1),array_length(1,1)]);
C{2,1} = repmat((values(2,1)),[array_height(2,1),array_length(2,1)]);
C{3,1} = repmat((values(3,1)),[array_height(3,1),array_length(3,1)]);
C{1,2} = repmat((values(1,2)),[array_height(1,2),array_length(1,2)]);
C{2,2} = repmat((values(2,2)),[array_height(2,2),array_length(2,2)]);
C{3,2} = repmat((values(3,2)),[array_height(3,2),array_length(3,2)]);
If you did this in a for loop, it might look something like this:
for i = 1:size(C,1)
for j = 1:size(C,2)
C{i,j} = repmat(values(i,j),[array_height(i,j),array_length(i,j)]);
end
end
However, if you are trying to generate or use this with a larger dataset, this code snippet likely will take forever! I suspect whatever your overall objective is can be better served by matlab's many optimizations for matrices and vectors, but without more information I can't help more than that.

Finding equal rows between multiple arrays of different sizes by voting

Let's say I have 5 arrays of different sizes. All of the arrays have the same number of columns, in my case 2, but a different number of rows. I need to find the elements of the rows that appear in at least 3 of such arrays.
Right now, I compare two arrays using ismember, then compare that result with the third array and then save the row values which occur in all the three arrays. I do this for every possible combination of 3 arrays; basically in my case, I have 10 of such operations in total. It's like choosing three out of 5 without repetitions.
It works, but I am looking for a more efficient implementation. In particular, I was looking for any implementation that can perform this by voting. It's like having sets of different sizes and trying to find the elements that appear in the majority of sets, in my case 3 arrays out of 5.
Not sure what you mean by voting but I think does what you are looking for.
It creates 1 big unique matrix of all the rows from the arrays. The does an ismember by rows of the unique array with each individual array. The ismember is summed together to get a count of how many times each unique row exists across your set of arrays.
You can then use that count to return a new array that has at least minNum occurrences.
You would call it like this:
>> [outRows, uRows, memCount]= getRowDuplicates(3,a,b,c,d,e)
Where a,b,c,d,e are you arrays and 3 is the minimum number of occurrences
function [outRows, uRows, memCount]= getRowDuplicates(minNum,varargin)
uRows = unique(vertcat(varargin{:}),'rows');
memCount = false(size(uRows,1),1);
for j = 1:nargin-1
memCount = memCount + ismember(uRows,varargin{j},'rows');
end
rowIdx = memCount >= minNum;
outRows = uRows(rowIdx,:);
Thanks to Aero Engy for the solution! This is my own attempt, after rewriting my initial, not very efficient, implementation. I thought someone might find it useful:
function [majorityPts] = MajorityPointSelection(Mat, numMajority)
result = vertcat(Mat{:});
allUniq = unique(result(:,1:2),'rows');
numUniq = size(allUniq,1);
allUniq = [allUniq zeros(numUniq,1); zeros(size(result,1)-numUniq, 3)];
for i = 1:numUniq
sumNumRow = sum(result(:,1:2) == allUniq(i,1:2),1);
allUniq(i,3) = sumNumRow(1);
end
allUniq(numUniq+1:end,:) = [];
majorityPts = allUniq(allUniq(:,3)>=numMajority,1:2);
end
Here Mat is a cell that contains all of the arrays that I want to compare in order to find the rows that appear in at least numMajority of them, where in my case numMajority = 3. Basically, I first dump all of the arrays in one big matrix (result), and then find the unique rows of this matrix. Finally, I count the number of each unique row and return the points that appear in the majority number of arrays as majorityPts.

How do I shorten an array in Matlab to prevent a dimension mismatch?

I'm taking in two arrays and comparing them. However, one array might be larger than the other.
So, how can I trim the larger array to the size of the smaller one to prevent a dimension mismatch?
Now, I'm using this code to trim the rows:
[nRows1, nCols1] = size(data1);
[nRows2, nCols2] = size(data2);
data1(nRows1 + 1:nRows2, :) = [];
But, this is still not working and it says that there is a dimension mismatch.
This should do it:
data1(size(data2, 1)+1:end, :) = [];
data2(size(data1, 1)+1:end, :) = [];

Which syntax is better for deleting elements of an array in MATLAB?

In MATLAB say I have an array, and have created a logical vector that has true entries for elements that I want to remove, call it del_index for example. To accomplish this, is one of the following ways better/faster and/or preferable?
arr(del_index) = [];
OR
arr = arr(~del_index);
Both look nice, so lets test the speed.
time1=0;
th=0.5
for ii=1:100000
arr=rand(10000,1);
del_index=arr<th;
tic
arr(del_index) = [];
time1=time1+toc;
end
time2=0;
for ii=1:100000
arr=rand(10000,1);
del_index=arr<th;
tic
arr = arr(~del_index);
time2=time2+toc;
end
display(['arr(del_index) is ', num2str(time1/time2), ' times slower'])
I tried with different values of th, from 0 to 1 and I generally get this value. So yeah, second on is better.
arr(del_index) is 1.5136 times slower

Is there a more efficient way of choosing an element from 1 array and to every element of the same array

I want to, for every element of an array ZAbs, compare it for equality to every element of the array itself and put them into another distinct array. I want the distinct array's elements to have the same index as the ZAbs array.
I did this by creating 4 nested for loops:
for pAbs2 = 1:400
for qAbs2 = 1:300
zAbsCompare = ZAbs(qAbs2, pAbs2);
for pAbs3 = 1:400
for qAbs3 = 1:300
zAbsCompare2 = ZAbs(qAbs3, pAbs3);
if (zAbsCompare == zAbsCompare2)
InitialZModEqualsImag(pAbs2,qAbs2) = InitialZImag(qAbs2, pAbs2);
InitialZModEqualsReal(pAbs2,qAbs2) = InitialZReal(qAbs2, pAbs2);
end
end
end
end
end
However, this runs really slowly. I can't think of a better way to do this, but as I'm inexperienced with MATLAB there's probably something I'm overlooking here. Any help?
EDIT: Fixed an error and restated the question.
You can do the comparison (not sure that's what you want) efficently with bsxfun:
comp = bsxfun(#eq, X, shiftdim(X,-2));
The result comp(m,n,p,q) is 1 if X(m,n) == X(p,q), and 0 otherwise.

Resources