Matlab: Merge year into interval - matlab

I have a vector with decades (note that some decades are deliberately missing:
decades = [1910 1920; 1921 1930; 1931 1940; 1951 1960]
and a vector with some years (max. 1 per decade) with a piece of information (let's say accidents):
years = [1916 35; 1923 77; 1939 28; 1941 40; 1951 32]
Is there a way to combine the information to the decades, other than using a loop?
result = [1910 1920 35; 1921 1930 77; 1931 1940 28; 1951 1960 32]

Assumptions (taken from OP's comments):
a. There won't be more than one year per decade.
b. decade and years are always sorted.
Code
%// Slightly different inputs to verify the correctness of code across
%//general cases, but within the above mentioned assumptions
decades = [1910 1920; 1921 1930; 1931 1940; 1951 1960; 1971 1980]
years = [1916 35; 1939 28; 1941 40; 1951 32]
cm = bsxfun(#ge,years(:,1),decades(:,1)') & bsxfun(#le,years(:,1),decades(:,2)')
select_years = any(cm,2)
select_decades = any(cm,1)
%// If result is needed such that decades which do not have a entry in
%// years must be logged in with the third column as 0
result = [decades sum(bsxfun(#times,cm,years(:,2)))'] %//'
%// If result is needed such that decades which do not have a entry in
%// years must be skipped
result = [decades(select_decades,:) years(select_years,2)]
Output
decades =
1910 1920
1921 1930
1931 1940
1951 1960
1971 1980
years =
1916 35
1939 28
1941 40
1951 32
result =
1910 1920 35
1921 1930 0
1931 1940 28
1951 1960 32
1971 1980 0
result =
1910 1920 35
1931 1940 28
1951 1960 32

This accumulates values if there is more than one per decade. It also handles the case when a decade doesn't have any value.
[~, bin] = histc(years(:,1),reshape(decades.',[],1)); %'// find bin of each value
bin = (bin+1)/2; %// non-integers here indicate intervals between decades
bin(mod(bin,1)~=0) = size(decades,1)+1; %// values between decades: move to end
accum = accumarray(bin,years(:,2)); %// accumulate all values from each bin
result = [decades accum(1:end-1)]; %// remove end bin (values between decades)
Example with two values in one decade, and zero values in some other decade:
decades = [1910 1920; 1921 1930; 1931 1940; 1951 1960];
years = [1916 35; 1918 77; 1939 28; 1941 40; 1951 32];
result =
1910 1920 112
1921 1930 0
1931 1940 28
1951 1960 32

decades = [1910 1920; 1921 1930; 1931 1940; 1951 1960]
years = [1916 35; 1923 77; 1939 28; 1951 32]
new_decades_1=repmat(decades(:,1),1,size(decades,1))
new_decades_2=repmat(decades(:,2),1,size(decades,1))
new_years=repmat(years(:,1),1,size(years,1))
cond=(new_decades_1<=new_years') & (new_decades_2>=new_years')
[x,y]=find(cond);
result=[decades,years(x,2)]
This however requires that years and decades have the same length.

Related

display mean instead of median in boxplot matlab

I have the example code below:
A = [16 20 15 17 22 19 17]';
B = [22 15 16 16 16 18]';
C = [23 9 15 18 13 27 17 14 16 15 21 19 17]';
group = [ ones(size(A));
2 * ones(size(B));
3;
4 * ones(size(C))
];
figure();
boxplot([A; B; NaN; C],group);
set(gca,'XTickLabel',{'A','B','','C'});
what can I add to the code to show the mean of each vector in the box plot instead of the median (which is a Matlab default), I know how to do it for one vector but if we have multiple boxplots, I need some help how to do it.
any suggestion, please?
Try removing the median line and then plotting the relevant means
:
A = [16 20 15 17 22 19 17]';
B = [22 15 16 16 16 18]';
C = [23 9 15 18 13 27 17 14 16 15 21 19 17]';
% Calculate means
meanOfA = mean(A);
meanOfB = mean(B);
meanOfC = mean(C);
group = [ ones(size(A));
2 * ones(size(B));
3;
4 * ones(size(C))
];
figure;
boxplot([A; B; NaN; C],group);
set(gca,'XTickLabel',{'A','B','','C'});
% Find handle for median line and set visibility off
h = findobj(gca,'Tag','Median');
set(h,'Visible','off');
%plot means as black asterisks.
hold on
plot(1,meanOfA, 'k*')
plot(2,meanOfB, 'k*')
plot(4,meanOfC, 'k*')

Fastest code to merge two matrices of different dimension in Matlab

I have two matrices in Matlab A and B respectively of dimension MxN and GxN.
M can be greater or smaller than G.
A and B do not contain identical rows.
I want to construct a matrix C of dimension Hx(N+2) in the following way
C=[];
for i=1:size(A,1)
%if A(i,1:end-1) coincides with a row in B(:,1:end-1) (it can coincide with only one row at most)
%then C=[C;A(i,1:end) B(j,end)]; %where j is the index of the identical row in B
%otherwise impose C=[C;A(i,1:end) 0]
end
for i=1:size(B,1)
%if B(i,1:end-1) does not coincide with any row in A(:,1:end-1)
%then impose C=[C; B(i,1:end-1) 0 B(i,end)];
end
For example:
A=[1 2 3 4 5 100; 6 7 8 9 10 101; 11 12 13 14 15 102];
B=[6 7 8 9 10 103; 15 16 17 18 19 104]
C=[1 2 3 4 5 100 0; 6 7 8 9 10 101 103; 11 12 13 14 16 102 0; 15 16 17 18 19 0 104]
As M and G can be very high, I am looking for the fastest way to perform this.
You can use ismember + indexing to do your task:
[idx1,idx2] = ismember(A(:,1:end-1), B(:,1:end-1), 'rows');
idx3 = ~ismember(B(:,1:end-1), A(:,1:end-1), 'rows');
C(idx1,:) = [A(idx1,:) B(idx2(idx1),end)];
C(~idx1,:) = [A(~idx1,:) zeros(sum(~idx1),1)];
C=[C;B(idx3,1:end-1) zeros(sum(idx3),1) B(idx3,end)];
You could also use intersect with a bit of preallocation to speed up the assignment (if M or G gets really large).
A=[1 2 3 4 5 100; 6 7 8 9 10 101; 11 12 13 14 15 102];
B=[6 7 8 9 10 103; 15 16 17 18 19 104];
C=[1 2 3 4 5 100 0; 6 7 8 9 10 101 103; 11 12 13 14 16 102 0; 15 16 17 18 19 0 104];
[M,N] = size(A);
G = size(B,1);
[tmp, idxA, idxB] = intersect(A(:,1:end-1),B(:,1:end-1),'rows')
idxBnotA = setdiff([1:G],idxB);
H = M + G - length(idxA);
C1 = zeros(H,N+1);
C1(1:M,1:N) = A;
C1(idxA,end) = B(idxB,end);
C1(M+1:end,1:end-2) = B(idxBnotA,1:end-1);
C1(M+1:end,end) = B(idxBnotA,end)

Mystery degree of freedom in VAR coefficient stderr

I've been testing the vector autoregressive coefficient estimation vgxvarx in Matlab's Econometrics toolbox. Once the coefficients are determined, vgxdisp gives you the choice of showing the standard errors estimated according to maximum likelihood or minimum bias. The only difference between the two is normalization by number of observations versus degrees of freedom, respectively. Since both are constant, you should be able to verify the 2 sets of standard errors by converting from one to the other. Just unnormalize by one constant and renormalize by the other.
I tried this and found that the minimum bias estimate of standard error seems to be off by one in the degrees of freedom. In the script below, I use vgxvarx to calculate VAR model coefficients and then request maximum likelihood and minimum bias estimates of their standard errors from vgxdisp (DoFAdj=false and true, respectively). To validate the two, I then convert the standard errors from ML to min bias by unnormalizing by the number of observations (nPoints) and renormalizing by degrees of freedom LESS ONE (found by trial and error). These scalings have to be square-rooted because they apply to variance and we're comparing standard errors.
I'm wondering if anyone can point out whether I am missing something basic that explains this mystery degree of freedom?
I've originally posted this to usenet. Here is a modification of the original code that natively sets the data so that it doesn't need to be obtained from http://www.econ.uiuc.edu/~econ472/eggs.txt.
clear variables
fnameDiary = [mfilename '.out.txt'];
if logical(exist(fnameDiary,'file'))
diary off
delete(fnameDiary)
end % if
diary(fnameDiary) % Also turns on diary
CovarType='full' % 'full'
nMaxLag=3
clf
tbChicEgg=table([
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 ...
1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 ...
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 ...
1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 ...
1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 ...
1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 ...
2002 2003 2004 2005 2006 ...
]',[
468491 449743 436815 444523 433937 389958 403446 423921 ...
389624 418591 438288 422841 476935 542047 582197 516497 ...
523227 467217 499644 430876 456549 430988 426555 398156 ...
396776 390708 383690 391363 374281 387002 369484 366082 ...
377392 375575 382262 394118 393019 428746 425158 422096 ...
433280 421763 404191 408769 394101 379754 378361 386518 ...
396933 400585 392110 384838 378609 364584 374000 370000 ...
373000 380000 356000 356000 353000 363000 371000 380000 ...
386000 388000 393000 410000 425000 437000 437000 444000 ...
444000 450000 454000 453000 453000 ...
]',[
3581 3532 3327 3255 3156 3081 3166 3443 3424 3561 3640 3840 ...
4456 5000 5366 5154 5130 5077 5032 5148 5404 5322 5323 5307 ...
5402 5407 5500 5442 5442 5542 5339 5358 5403 5345 5435 5474 ...
5540 5836 5777 5629 5704 5806 5742 5502 5461 5382 5377 5408 ...
5608 5777 5825 5625 5800 5656 5683 5700 5758 5867 5808 5600 ...
5675 5750 5892 5992 6158 6233 6367 6458 6650 6908 7058 7175 ...
7275 7292 7425 7500 7575 ...
]', ...
'VariableNames', {'year' 'chic' 'egg'} ...
);
seriesNames={'chic','egg'};
varChicEgg = vgxset( 'Series', seriesNames, 'n',2 );
chicEgg = table2array(tbChicEgg(:,seriesNames));
dChicEgg = diff(chicEgg);
dChicEgg = bsxfun( #minus, dChicEgg, mean(dChicEgg) ); % Make 0-mean
dChicEgg0 = dChicEgg(1:nMaxLag,:); % Presample-data
dChicEgg = dChicEgg(1+nMaxLag:end,:);
nPoints = length(dChicEgg)
yrs = table2array(tbChicEgg(1+nMaxLag:end,'year'));
yrs = yrs(1:nPoints);
subplot(3,1,1);
plotyy( yrs,dChicEgg(:,1) , yrs,dChicEgg(:,2) );
for DoFAdj = [false true]
% DoFAdj=1 means std err normalizes by df rather than n, where
% n=number of observations and df is n less the number of
% parameters estimated (from vgxdisp or vgxcount's NumParam)
[est.spec est.stdErr est.LLF est.W] = vgxvarx( ...
vgxset( varChicEgg, 'nAR',nMaxLag ), ...
dChicEgg, NaN, dChicEgg0, ...
'StdErrType', 'all', ...
'CovarType', CovarType ...
);
fprintf('-------------------------\nDoFAdj=%g\n',DoFAdj);
subplot(3,1,2+DoFAdj)
plotyy(yrs,est.W(:,1),yrs,est.W(:,2))
vgxdisp(est.spec,est.stdErr,'DoFAdj',DoFAdj);
end
fprintf('\nConvert ML stderr (DoFAdj=false) to min bias (DoFAdj=true):\n');
fprintf('Number of parameters: ')
[~,NumParam]=vgxcount(est.spec)
degreeFree = nPoints - NumParam
fprintf('\n');
stderr_ML_2_minBias=[
0.148195
21.1939
0.00104974
0.150127
0.160034
22.2911
0.0011336
0.157899
0.147694
20.9146
0.00104619
0.148148
6.43245e+07
381484
3227.54
] ...
* sqrt( nPoints / ( degreeFree - 1 ) );
for iParam = 1:length(stderr_ML_2_minBias)
disp(stderr_ML_2_minBias(iParam));
end
%--------------------------------------------------
diary off
% error('Stopping before return.');
return

How to find out the coefficient in matching pursuit algorithm [duplicate]

This question already has answers here:
Implementing matching pursuit algorithm
(3 answers)
Closed 6 years ago.
I'm trying to implement Matching Pursuit algorithm in Matlab.I have found out the maximum inner product value ,i m stuck with how to find out the coeffients.
help me out.
Here is the algorithm
D=[1 6 11 16 21 26 31 36 41 46
2 7 12 17 22 27 32 37 42 47
3 8 13 18 23 28 33 38 43 48
4 9 14 19 24 29 34 39 44 49
5 10 15 20 25 30 35 40 45 50];
b=[16;17;18;19;20];
n=size(D);
A1=zeros(n);
R=b;
x=[];
H=10;
if(H <= 0)
error('The number of iterations needs to be greater then 0')
end;
[c,d] = max(abs(D'*R));
Here i have used a prefined dictionary.
Thanks in advance
You can use this function based on "S. Mallat, Z. Zhang, 1993. Matching pursuit in a time frequency dictionary. IEEE Transactions Signal Processing, Vol. 41, No. 12, pp. 3397-3415."
x = MP(b,D,10);
function S = MP(y,Dictionary,iteration)
n = size(Dictionary,2);
S = zeros(n,1);
% Normalize the dictionary atoms (coloumns) to have unit norm
% It's better to implement this part out of function,
% to normalize the dictionary just one time!
%**************************************
for j = 1:n;
Dictionary(:,j) = Dictionary(:,j)/norm(Dictionary(:,j));
end
% *************************************
for i = 1:iteration
gn = Dictionary' * y / norm(y);
[MAX,index] = max(abs(gn));
y = y - MAX * Dictionary(:,index);
S(index) = MAX + S(index);
end

Aligning face data from MATLAB triangulation

I have a function f(x,y) which has certain symmetries that I would like to plot. Here is an example:
This plot can be generated with:
[x,y,z] =
0 0 0.1415
0.1999 0.1999 0.1165
0.2760 0 0.1268
0.3694 0.3694 0.0983
0.4830 0 0.1142
0.5090 0.5090 0.0903
0.5550 0.1871 0.0881
0.6189 0.3558 0.0715
0.6197 0.6197 0.0907
0.6399 0 0.1056
0.7071 0.7071 0.1415
0.7169 0.4835 0.0869
0.7215 0.1200 0.0859
0.7304 0.2392 0.0680
0.7643 0 0.1005
0.7926 0.3574 0.0856
0.8090 0.5878 0.1393
0.8581 0.1122 0.0821
0.8634 0.2343 0.0878
0.8794 0 0.0986
0.8910 0.4540 0.1332
0.9511 0.3090 0.1253
0.9877 0.1564 0.1191
1.0000 0 0.1169
t =
6 4 8
12 6 8
8 4 7
4 2 7
8 7 14
14 7 13
3 2 1
5 7 3
3 7 2
17 12 21
6 12 9
9 17 11
12 17 9
10 15 13
10 7 5
13 7 10
21 12 16
16 12 8
8 14 16
18 14 13
15 20 18
13 15 18
24 23 18
18 20 24
21 16 22
23 22 19
19 18 23
14 18 19
19 16 14
19 22 16
trisurf(t,x,y,z)
So I know that function has a reflection symmetry about y=x and then the resulting function is to be repeated in all the quadrants. Here is the code to do this:
allx = [x; x;-x;-x;y; y;-y;-y];
ally = [y;-y; y;-y;x;-x; x;-x];
allz = [z; z; z; z;z; z; z; z];
These are the new vertices for the surface I want to plot. Now how do I properly generate the faces for this new surface?
When I use a finer mesh and add some pretty lights it should look something like this:
Speculative:
So your question is about how to set-up the first argument of trisurf, i.e. how to define the extended t in your code. According to the docs this is the index into the vertices defined by the remaining arguments. I don't have MATLAB installed on this machine, but what happens if you do:
allx = [x; x;-x;-x];
ally = [y;-y; y;-y];
allz = [z; z; z; z];
s = size(x,1);
t = [t; t + s; t + 2*s; t + 3*s]
Just trying to think if this makes sense and if/how it extends into the other quadrants.