merge.m 5.29 KB
Newer Older
1
function q = merge(o, p) % --*-- Unitary tests --*--
2

3 4
% Merge method for dseries objects.
%
Stéphane Adjemian's avatar
Stéphane Adjemian committed
5
% INPUTS
6 7 8
% - o  [dseries]
% - p  [dseries]
%
Stéphane Adjemian's avatar
Stéphane Adjemian committed
9
% OUTPUTS
10 11
% - q  [dseries]
%
Stéphane Adjemian's avatar
Stéphane Adjemian committed
12
% REMARKS
13
% If dseries objects o and p have common variables, the variables in p take precedence.
14

15
% Copyright (C) 2013-2017 Dynare Team
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
%
% This file is part of Dynare.
%
% Dynare is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% Dynare is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.

32
if ~isdseries(p)
33 34 35
    error('dseries::merge: Both inputs must be dseries objects!')
end

36
if ~isequal(frequency(o), frequency(p))
Stéphane Adjemian's avatar
Stéphane Adjemian committed
37 38 39 40 41
    if isempty(inputname(1))
        error(['dseries::merge: Cannot merge dseries objects (frequencies are different)!'])
    else
        error(['dseries::merge: Cannot merge ' inputname(1) ' and ' inputname(2) ' (frequencies are different)!'])
    end
42 43
end

44
q = dseries();
45

46
[q.name, IBC, ~] = unique([o.name; p.name], 'last');
47

48 49
[list_of_common_variables, iO, iP] = intersect(o.name, p.name);

50 51
tex = [o.tex; p.tex];
q.tex = tex(IBC);
52

Stéphane Adjemian's avatar
Stéphane Adjemian committed
53 54
ops = [o.ops; p.ops];
q.ops = ops(IBC);
55

56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
otagnames = fieldnames(o.tags);
ptagnames = fieldnames(p.tags);
qtagnames = union(otagnames, ptagnames);
if isempty(qtagnames)
    q.tags = struct();
else
    for i=1:length(qtagnames)
        if ismember(qtagnames{i}, otagnames) && ismember(qtagnames{i}, ptagnames)
            q.tags.(qtagnames{i}) = vertcat(o.tags.(otagnames{i}), p.tags.(ptagnames{i}));
        elseif ismember(qtagnames{i}, otagnames)
            q.tags.(qtagnames{i}) = vertcat(o.tags.(qtagnames{i}), cell(vobs(p), 1));
        elseif ismember(qtagnames{i}, ptagnames)
            q.tags.(qtagnames{i}) = vertcat(cell(vobs(o), 1), p.tags.(qtagnames{i}));
        else
            error('dseries::horzcat: This is a bug!')
        end
        q.tags.(qtagnames{i}) = q.tags.(qtagnames{i})(IBC);
    end
end

76 77 78 79 80 81 82 83
if nobs(o) == 0
    q = copy(p);
elseif nobs(p) == 0
    q = copy(o);
elseif firstdate(o) >= firstdate(p)
    diff = firstdate(o) - firstdate(p);
    q_nobs = max(nobs(o) + diff, nobs(p));
    q.data = NaN(q_nobs, vobs(q));
84
    Z1 = [NaN(diff, vobs(o)); o.data];
85 86
    if nobs(q) > nobs(o) + diff
        Z1 = [Z1; NaN(nobs(q)-(nobs(o) + diff), vobs(o))];
Stéphane Adjemian's avatar
Stéphane Adjemian committed
87
    end
88 89 90
    Z2 = p.data;
    if nobs(q) > nobs(p)
        Z2 = [Z2; NaN(nobs(q) - nobs(p), vobs(p))];
Stéphane Adjemian's avatar
Stéphane Adjemian committed
91
    end
92
    Z = [Z1 Z2];
93
    q.data = Z(:,IBC);
94 95 96 97 98 99 100 101 102
    if ~isempty(list_of_common_variables)
        for i=1:length(iP)
            jO = iO(i);
            jP = iP(i);
            jQ = find(strcmp(o.name{jO}, q.name));
            id = isnan(q.data(:,jQ)) & ~isnan(Z1(:,jO)) & isnan(Z2(:,jP));
            q.data(id, jQ) = Z1(id,jO);
        end
    end
103
    q_init = firstdate(p);
104
else
105 106 107 108 109 110
    diff = firstdate(p) - firstdate(o);
    q_nobs = max(nobs(p) + diff, nobs(o));
    q.data = NaN(q_nobs, vobs(q));
    Z1 = [NaN(diff, vobs(p)); p.data];
    if nobs(q) > nobs(p) + diff
        Z1 = [Z1; NaN(nobs(q)-(nobs(p) + diff), vobs(p))];
111
    end
112 113 114
    Z2 = o.data;
    if nobs(q) > nobs(o)
        Z2 = [Z2; NaN(nobs(q) - nobs(o), vobs(o))];
Stéphane Adjemian's avatar
Stéphane Adjemian committed
115
    end
116
    Z = [Z2 Z1];
117
    q.data = Z(:,IBC);
118 119 120 121 122 123 124 125 126
    if ~isempty(list_of_common_variables)
        for i=1:length(iP)
            jO = iO(i);
            jP = iP(i);
            jQ = find(strcmp(o.name{jO}, q.name));
            id = isnan(q.data(:,jQ)) & isnan(Z1(:,jP)) & ~isnan(Z2(:,jO));
            q.data(id, jQ) = Z2(id,jO);
        end
    end
127
    q_init = firstdate(o);
128 129
end

130
q.dates = q_init:q_init+(nobs(q)-1);
131 132 133 134 135 136 137 138

%@test:1
%$ % Define a datasets.
%$ A = rand(10,2); B = randn(10,1);
%$
%$ % Define names
%$ A_name = {'A1';'A2'}; B_name = {'A1'};
%$
139
%$ % Instantiate two time series objects and merge.
140 141
%$ try
%$    ts1 = dseries(A,[],A_name,[]);
142 143 144
%$    ts1.tag('type');
%$    ts1.tag('type', 'A1', 'Stock');
%$    ts1.tag('type', 'A2', 'Flow');
145
%$    ts2 = dseries(B,[],B_name,[]);
146 147
%$    ts2.tag('type');
%$    ts2.tag('type', 'A1', 'Flow');
148 149 150 151 152 153
%$    ts3 = merge(ts1,ts2);
%$    t(1) = 1;
%$ catch
%$    t = 0;
%$ end
%$
154
%$ if t(1)
155 156 157
%$    t(2) = dassert(ts3.vobs,2);
%$    t(3) = dassert(ts3.nobs,10);
%$    t(4) = dassert(ts3.data,[B, A(:,2)],1e-15);
158
%$    t(5) = dassert(ts3.tags.type, {'Flow';'Flow'});
159 160 161 162 163 164 165 166 167 168 169
%$ end
%$ T = all(t);
%@eof:1

%@test:2
%$ % Define a datasets.
%$ A = rand(10,2); B = randn(10,1);
%$
%$ % Define names
%$ A_name = {'A1';'A2'}; B_name = {'B1'};
%$
170
%$ % Instantiate two time series objects and merge them.
171 172
%$ try
%$    ts1 = dseries(A,[],A_name,[]);
173 174 175
%$    ts1.tag('t1');
%$    ts1.tag('t1', 'A1', 'Stock');
%$    ts1.tag('t1', 'A2', 'Flow');
176
%$    ts2 = dseries(B,[],B_name,[]);
177 178
%$    ts2.tag('t2');
%$    ts2.tag('t2', 'B1', 1);
179 180 181 182 183 184 185 186 187 188
%$    ts3 = merge(ts1,ts2);
%$    t(1) = 1;
%$ catch
%$    t = 0;
%$ end
%$
%$ if length(t)>1
%$    t(2) = dassert(ts3.vobs,3);
%$    t(3) = dassert(ts3.nobs,10);
%$    t(4) = dassert(ts3.data,[A, B],1e-15);
189 190
%$    t(5) = dassert(ts3.tags.t1, {'Flow';'Flow';[]});
%$    t(6) = dassert(ts3.tags.t2, {[];[];1});
191 192
%$ end
%$ T = all(t);
Houtan Bastani's avatar
Houtan Bastani committed
193
%@eof:2