From: Priom Rahman on
Dear Oleg,

That worked brilliantly, Thank you so much for your help,

What I meant by closest was "the smallest difference in the rainfall compared to the closest day" so the smallest abs(current day's rian - the values of rain in "ans" column 5)

[essesntially, in logic i'm trying to find the 3 most similar rainfall in that date window for the x amount of years of data I have, and wanting to know when they happened] - but your code finds all the dates, so I can just pick out the "closest" 3.


I just had one other question, if was to repeat this 18000 times ? (i.e now move on and do 6th of january 1960 (+- 2 days), then 7th january 1960 +-(2 days) , ect ect.

so i would be looping the code:

for i = 1:size(In)

end

therefore i will end up with a loc martix for every data point i have,

I dont know how I should be organising this data?

I want to be able to look up any date - (and not have 18000 "loc" matricies)

Thank you for sharing your matlab tallent !!!!
From: Oleg Komarov on
"Priom Rahman" <z3188254(a)unsw.edu.au> wrote in message <i2sqnv$6dh$1(a)fred.mathworks.com>...
> Dear Oleg,
>
> That worked brilliantly, Thank you so much for your help,
>
> What I meant by closest was "the smallest difference in the rainfall compared to the closest day" so the smallest abs(current day's rian - the values of rain in "ans" column 5)
>
> [essesntially, in logic i'm trying to find the 3 most similar rainfall in that date window for the x amount of years of data I have, and wanting to know when they happened] - but your code finds all the dates, so I can just pick out the "closest" 3.
>
>
> I just had one other question, if was to repeat this 18000 times ? (i.e now move on and do 6th of january 1960 (+- 2 days), then 7th january 1960 +-(2 days) , ect ect.
>
> so i would be looping the code:
>
> for i = 1:size(In)
>
> end
>
> therefore i will end up with a loc martix for every data point i have,
>
> I dont know how I should be organising this data?
>
> I want to be able to look up any date - (and not have 18000 "loc" matricies)
>
> Thank you for sharing your matlab tallent !!!!

Using the same input:

% Tolerance in days
tol = 2;

% Number of close results
numR = 3;

% Size of you input
szIn = size(In);

% Preallocate Out
Out = repmat({zeros(4,7)},szIn(1),1);
Out(isnan(In(:,end))) = {NaN};

% LOOP for each row
for r = 1:szIn(1)
if ~isnan(In(r,end))

% Find those rows of the same month, day+-tol and same class rain
loc = find(In(:,2) == In(r,2) & ismember(In(:,3), In(r,3)-tol:In(r,3)+tol) & In(:,5) == In(r,5));

% temporary results sorted by abs(current_rain-rain)
tmp = sortrows([loc In(loc,:) abs(In(r,4)-In(loc,4))],7);

% Allocate results; first row is the current selected row
Out{r} = tmp(1:min(numR+1, numel(loc)),:);
end
end

Oleg
From: Priom Rahman on
That worked so fast,

My code took 11 mins to run !! for my 18000 data points, but yours took about 20 seconds. Here is what I had (with help from what you said yesterday ofcourse)

'''''''''''''''''''''''''''''''''''''''''''''''

for i = 8: size(In,1)-8
% Current date
Cdate = datenum(In(i,1), In(i,2), In(i,3));
%[Cyear Cmonth Cday] = datevec(Cdate);
[Cyear Cmonth Cday] = datevec(Cdate);
% Current class rain
Cclrain = In(datenum(In(:,1:3)) == Cdate,5);
% Tolerance in days
window = 7;

% Find those rows of the same month, day+-tol and same class rain
%Match = the days in the window that match the same class
Match = find(In(:,2) == Cmonth & ismember(In(:,3),Cday-window:Cday+window) & In(:,5) == Cclrain);

% Now i get this result - shows the position and the corresponding numbers
% attributable to those positions.
%note also - it has 6 columns |position|year|month|day|rain|class| at this
%stage)
Neighb = [Match In(Match,:)];


% find the departures (absolute value between all the classes and the
% current rain)
depart= abs(Neighb(:,5)- In(i,4));

%recreate the nighbour matrix - adding the departure column.
%Now it has 7 columns |position|year|month|day|rain|class|departure|

Neighb = [Neighb depart];

% Sort the Neighb matrix based on departures (col 7)
Neighb = sortrows(Neighb, 7);

% 6 neighbours with the smallest departures (not counting current postion)

if size(Neighb,1)>= 7
positions = Neighb(2:7, 1);
positions';
locationmat(i,:) = positions';
end



end

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

but yours was much faster - very impressive ! I didnt think to store it the way you did, its very clever, however I'm unfamiliar with how to call the values later if i need them, but I'll look that up.

what i was working on when I read your msg, was goind back and finding a way to fill in the dates with NaN (in my code its 0) because even if there arent "3 closest values" there may be 1 o r 2 (and the rest of them would be NaN) .... any suggesttions ??

I need to know because after I get these reference dates I need to apply a bootstrap.

:(

but another problem for another day !!


Thanks again for your help, it would take me weeks without your matlab wisdom.