How can I calculate the unique centroids along with its radius range ?
    조회 수: 4 (최근 30일)
  
       이전 댓글 표시
    
Suppose I've centroid coordinates stored in text files, and I extracted those coordinates and stored them in auxillary arrays. For example, the centroids are like these :   (Also the Threshold = 2 and Radius range =4:10 )
1st array has centroids (radius 4) - 34.00  26.00 
                                                        36.00  21.00
2nd array has centroids (radius 5) - 40.81  36.13 
                                                         58.50  54.00
3rd array has centroids (radius 6) - 24.50  49.75 
                                                          40.82  35.91 
                                                          40.62  10.56 
                                                          57.14  50.00
4th array has centroids (radius 7) - 24.00  49.00 
                                                        40.73  35.94 
                                                         40.75  10.75
5th array has centroids (radisu 8) - 40.86 35.69 
6th array has centroids (radius 9) - 40.78 35.39 
7th array has centroids (radius 10) - 40.71 35.20
Now, first all the centroids at every array are marked un-visited which is 0. Now we start with 1st centroid of 1st array (34.00 26.00) and checks it with other centroids from 2nd, 3rd, 4th, 5th, 6th, 7th array. The matched ones(i.e., if the distance between current centroid and other centroid is less than equal to the threshold) gets into a buffer array and the average of them are calculated and put into the text file, if no matches are found append the current centroid directly to the text file. Also, the matched centroids from every array are marked visited are turned 1. Then I move to  next element (36.00 21.00) of 1st array and started checking with centroids from 2nd, 3rd, 4th, 5th, 6th, 7th array but couldn't found any matches. So, it's appended as it is in the text file. Next, I went to 2nd array and started comparing (40.81 36.13) with the un-visited centroids left in 3rd, 4th, 5th, 6th and 7th array. If found any matches put them in a buffer (for this case now the buffer wiil have - {40.81 36.13},{40.82 35.91},{40.73 35.95},{40.86 35.69},{40.78 35.39},{40.71 35.20}) calculate the average of them (for this case the average of them is coming out (40.78 35.71) and put them in the text file. Likewise, the average values that gets into the text file are called the unique centroids.
Also, I want the radius range along with the unique centroids in the text file. So, the 1st centroid of 1st array hasn't found any matches within 2nd,3rd,4th,5th,6th or 7th array. So the radius range will be 4 - 5, because the centroid belongs to radius 4 and since it has no matches so (current radius of the centroid +1). Also, for the 1st centroid of 2nd array has many matches, so its radius range is 5 - 11, becasue the centroid (40.81 36.13) belongs to radius 5 and since it has found matches upto the last array, i.e., 7th array which has the radius 10, so (last checked array radius +1).
So, my desired output coming for the above provided input of centroid arrays:
34.00  26.00 | 4 - 5
36.00  21.00 | 4 - 5
40.78  35.71 | 5 - 11
58.50  54.00 | 5 - 6
24.25 49.37 | 6 - 8
40.68  10.65 | 6 - 8
57.14  50.00 | 6 - 7
I've tried writtinf the code for the above explained logic, but I think there's some error in the logic.Here is the whole code:-
function step_stdA
centroidFiles = {'centroids1.txt','centroids2.txt','centroids3.txt','centroids4.txt','centroids5.txt','centroids6.txt','centroids7.txt'}; 
threshold = 2;
radiusRange = 4:10;
unique_centroids_A(centroidFiles, threshold,radiusRange);
end
function unique_centroids_A(centroidFiles, threshold,radiusRange)
% Initialize cell arrays to store centroid data and visited flags 
centroidsData = cell(1, numel(centroidFiles)); 
visitedFlags = cell(1, numel(centroidFiles));
% Read centroid data from files and initialize visited flags
for i = 1:numel(centroidFiles)
    centroidsData{i} = dlmread(centroidFiles{i}, ' ', 1, 1); % Read data
    numCentroids = size(centroidsData{i}, 1);
    visitedFlags{i} = zeros(numCentroids, 1); 
end
uniqueCentroidsAll = cell(1, numel(centroidFiles));
for i = 1:numel(centroidFiles)
    currentCentroids = centroidsData(i:end-1);
    subsequentArrays = centroidsData(i+1:end);
    uniqueCentroidsAll{i} = processCentroids(currentCentroids, subsequentArrays, threshold, visitedFlags, radiusRange);
end
fid = fopen('unique_centroids_A.txt', 'w');
for i = 1:numel(uniqueCentroidsAll)
    uniqueCentroids = uniqueCentroidsAll{i};
    for j = 1:size(uniqueCentroids, 1)
        fprintf(fid, '%.2f %.2f | %d - %d\n', uniqueCentroids(j, 1), uniqueCentroids(j, 2));
    end
end
fclose(fid);
end
function uniqueCentroids = processCentroids(currentCentroids, centroidsArray, threshold, visitedFlags,radiusRange)
buffer = [];
radiusRanges = zeros(size(currentCentroids, 1), 1);
order = [];
for j = 1:size(currentCentroids, 1)
    currentCentroid = currentCentroids(j, :); % jth row of the current array
    matches = [];
    for k = 1:length(centroidsArray)
        otherCentroids = centroidsArray{k};
        otherRadius = radiusRange(k);
        otherVisitedFlags = visitedFlags{k};
        for m = 1:size(otherCentroids, 1)
            if otherVisitedFlags(m) == 0
                otherCentroid = otherCentroids(m, :);
                distance = norm(currentCentroid - otherCentroid);
                if distance <= threshold
                    matches = [matches; otherCentroid];
                    otherVisitedFlags(m) = 1; % Mark as visited
                end
            end
        end
        visitedFlags{k} = otherVisitedFlags; % Update visited flags
    end
    if ~isempty(matches)
        averageCentroid = mean(matches);
        buffer = [buffer; averageCentroid]; % Add current centroid if matches found
        maxRadius = max(matches(:, 3)); % Get the maximum radius from matches
        radiusRanges(j) = maxRadius; % Set radius range to maximum radius
    else
        buffer = [buffer; currentCentroid]; % Add current centroid if no matches found
    end
    % Store the order of appearance
    order = [order; j]; 
end
% Remove duplicate centroids, if any
[~, uniqueIdx, ~] = unique(buffer, 'rows', 'stable');
uniqueCentroids = buffer(uniqueIdx, :);
% Sort unique centroids based on the order of appearance
[~, sortedOrder] = sort(order);
uniqueCentroids = uniqueCentroids(sortedOrder, :);
% Combine unique centroids with corresponding radius ranges
uniqueCentroids = [uniqueCentroids, radiusRanges];
end
It's highly appreciatable if you could come up with some help, I'm stuck with this problem for more than 2 weeks.
채택된 답변
  Matt J
      
      
 2024년 2월 18일
        
      편집: Matt J
      
      
 2024년 2월 18일
  
      load data; threshold=2;  %Example input
T=sortrows(table(Centroid, Radius),2)
Centroid=T.Centroid; Radius=T.Radius;
D=pdist2(Centroid,Centroid)<threshold;
 G=findgroups(Radius);
 N=histcounts(G,1:max(G)+1);
D=D&(1:width(D)>repelem(cumsum(N)',N)); %Block uppper-triangular mask
uniqueCentroid=(D*Centroid)./sum(D,2);
maxRad=max(Radius(:).'.*D,[],2);
nomatch=~any(D,2);
uniqueCentroid(nomatch,:)=Centroid(nomatch,:);
maxRad(nomatch,:)=Radius(nomatch,:);
result=table(uniqueCentroid,[Radius,maxRad+1],'Var',["Unique Centroids","Range"])
댓글 수: 6
  Matt J
      
      
 2024년 2월 18일
				
      편집: Matt J
      
      
 2024년 2월 18일
  
			load data; threshold=2;  %Example input
T=sortrows(table(Centroid, Radius),2);
D=pdist2(T.Centroid,T.Centroid)<threshold;
 G=findgroups(T.Radius);
 N=histcounts(G,1:max(G)+1);
D=D&(1:width(D)>repelem(cumsum(N)',N)); %Block uppper-triangular mask
Gr=digraph(D); Gr.Nodes=T;
T=parseGraph(Gr)
function T=parseGraph(Gr)
    Centroid=Gr.Nodes.Centroid; Radius=Gr.Nodes.Radius;
    buffer=[1;successors(Gr,1)];
    maxrad=max(Radius(buffer))+1; 
    avgcentroid=mean(Centroid(buffer,:),1);
    T=table(avgcentroid, [Radius(1), maxrad],'Var', ["Unique Centroids","Range"]);
    Gr=rmnode(Gr,buffer);
    if numnodes(Gr)==0
        return
    else
        T=[T;parseGraph(Gr)];
    end
end
추가 답변 (0개)
참고 항목
카테고리
				Help Center 및 File Exchange에서 Matrix Indexing에 대해 자세히 알아보기
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


