1function o = insert(o, p, id) % --*-- Unitary tests --*--
2
3% Adds a variable in a dseries object.
4%
5% INPUTS
6% - o    [dseries]
7% - p    [dseries]
8% - id   [integer]   vector of indices.
9%
10% OUTPUTS
11% - o    [dseries]
12
13% Copyright (C) 2013-2017 Dynare Team
14%
15% This file is part of Dynare.
16%
17% Dynare is free software: you can redistribute it and/or modify
18% it under the terms of the GNU General Public License as published by
19% the Free Software Foundation, either version 3 of the License, or
20% (at your option) any later version.
21%
22% Dynare is distributed in the hope that it will be useful,
23% but WITHOUT ANY WARRANTY; without even the implied warranty of
24% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25% GNU General Public License for more details.
26%
27% You should have received a copy of the GNU General Public License
28% along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
29
30[n, message] = common_strings_in_cell_arrays(o.name, p.name);
31
32if n
33    if isempty(inputname(1))
34        error(['dseries::insert: Variable(s) ' message ' already exist in dseries object!'])
35    else
36        error(['dseries::insert: Variable(s) ' message ' already exist in ''' inputname(1) '''!'])
37    end
38end
39
40if ~isequal(frequency(o),frequency(p))
41    if isempty(inputname(1))
42        error(['dseries::insert: dseries objects must have common frequencies!'])
43    else
44        error(['dseries::insert: ''' inputname(1) ''' and ''' inputname(2) ''' dseries objects must have common frequencies!'])
45    end
46end
47
48% Keep the second input argument constant.
49p = copy(p);
50
51% Add NaNs if necessary.
52[o, p] = align(o, p);
53
54n = length(id);
55
56% Get tag names in p
57ptagnames = fieldnames(p.tags);
58
59if n>1
60    [id, jd] = sort(id);
61    p.data = p.data(:,jd);
62    p.name = p.name(jd);
63    p.tex = p.tex(jd);
64    p.ops = p.ops(jd);
65    if ~isempty(ptagnames)
66        for i = 1:length(ptagnames)
67            p.tags.(ptagnames{i}) = p.tags.(ptagnames{i})(jd);
68        end
69    end
70end
71
72% Get tag names in o
73otagnames = fieldnames(o.tags);
74
75% Merge tag names
76if isempty(otagnames) && isempty(ptagnames)
77    notags = true;
78else
79    notags = false;
80    dtagnames_o = setdiff(ptagnames, otagnames);
81    dtagnames_p = setdiff(otagnames, ptagnames);
82    if ~isempty(dtagnames_o)
83        % If p has tags that are not in o...
84        for i=1:length(dtagnames_o)
85            o.tags.(dtagnames_o{i}) = cell(vobs(o), 1);
86        end
87    end
88    if ~isempty(dtagnames_p)
89        % If o has tags that are not in p...
90        for i=1:length(dtagnames_p)
91            p.tags.(dtagnames_p{i}) = cell(vobs(p), 1);
92        end
93    end
94end
95
96% Update list of tag names in o.
97otagnames = fieldnames(o.tags);
98
99for i=1:n
100    o.data = insert_column_vector_in_a_matrix(o.data, p.data(:,i),id(i));
101    o.name = insert_object_in_a_one_dimensional_cell_array(o.name, p.name{i}, id(i));
102    o.tex = insert_object_in_a_one_dimensional_cell_array(o.tex, p.tex{i}, id(i));
103    o.ops = insert_object_in_a_one_dimensional_cell_array(o.ops, p.ops{i}, id(i));
104    if ~notags
105        for j=1:length(otagnames)
106            o.tags.(otagnames{j}) = insert_object_in_a_one_dimensional_cell_array(o.tags.(otagnames{j}), p.tags.(otagnames{j}){i}, id(i));
107        end
108    end
109    id = id+1;
110end
111
112%@test:1
113%$ % Define a datasets.
114%$ A = rand(10,3); B = rand(5,2);
115%$
116%$ % Define names.
117%$ A_name = {'A1'; 'A2';'A3'};
118%$ B_name = {'B1'; 'B2'};
119%$
120%$ % Define initial dates.
121%$ A_init = '1950Q1';
122%$ B_init = '1950Q3';
123%$
124%$ % Instantiate two dseries objects.
125%$ ts1 = dseries(A, A_init, A_name,[]);
126%$ ts2 = dseries(B, B_init, B_name,[]);
127%$ ts1.tag('t1');
128%$ ts1.tag('t1','A1',1);
129%$ ts1.tag('t1','A2',1);
130%$ ts1.tag('t1','A3',0);
131%$ ts2.tag('t1');
132%$ ts2.tag('t1','B1',1);
133%$ ts2.tag('t1','B2',1);
134%$ ts2.tag('t2');
135%$ ts2.tag('t2','B1','toto');
136%$ ts2.tag('t2','B2','titi');
137%$
138%$ try
139%$    ts1 = insert(ts1,ts2,[1,2]);
140%$    t(1) = 1;
141%$ catch
142%$    t = 0;
143%$ end
144%$
145%$
146%$ if t(1)
147%$    t(2) = dassert(ts1.name,{'B1';'A1';'B2';'A2';'A3'});
148%$    t(3) = dassert(ts1.nobs,10);
149%$    eB = [NaN(2,2); B; NaN(3,2)];
150%$    t(4) = dassert(ts1.data,[eB(:,1), A(:,1), eB(:,2), A(:,2:3)], 1e-15);
151%$    t(5) = dassert(ts1.tags.t1,{1; 1; 1; 1; 0});
152%$    t(6) = dassert(ts1.tags.t2,{'toto'; []; 'titi'; []; []});
153%$ end
154%$ T = all(t);
155%@eof:1
156
157%@test:2
158%$ % Define a datasets.
159%$ A = rand(10,3); B = rand(5,2);
160%$
161%$ % Define names.
162%$ A_name = {'A1'; 'A2';'A3'};
163%$ B_name = {'B1'; 'B2'};
164%$
165%$ % Define initial dates.
166%$ A_init = '1950Q1';
167%$ B_init = '1950Q3';
168%$
169%$ % Instantiate two dseries objects.
170%$ ts1 = dseries(A, A_init, A_name,[]);
171%$ ts2 = dseries(B, B_init, B_name,[]);
172%$
173%$ try
174%$    ts1.insert(ts2,[1,2]);
175%$    t(1) = 1;
176%$ catch
177%$    t = 0;
178%$ end
179%$
180%$ if length(t)>1
181%$    t(2) = dassert(ts1.vobs,{'B1';'A1';'B2';'A3'});
182%$    t(3) = dassert(ts1.nobs,10);
183%$    eB = [NaN(2,2); B; NaN(3,2)];
184%$    t(4) = dassert(ts1.data,[eB(:,1), A(:,1), eB(:,2), A(:,2:3)], 1e-15);
185%$    t(5) = dassert(ts2.data, B);
186%$ end
187%$ T = all(t);
188%@eof:2