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

3 4
% Overloads the minus operator for dseries objects.
%
5
% INPUTS
6 7 8
% - o [dseries]
% - p [dseries]
%
9
% OUTPUTS
10 11
% - q [dseries]
%
12
% EXAMPLE
13 14 15 16 17 18 19
% Define a dseries object:
%
% >> a = dseries(transpose(1:5));
%
% Then we have
%
%  >> a-a
20
%
21
%  ans is a dseries object:
22
%
23
%     | minus(Variable_1;Variable_1)
24 25 26 27 28
%  1Y | 0
%  2Y | 0
%  3Y | 0
%  4Y | 0
%  5Y | 0
29

30
% Copyright (C) 2012-2017 Dynare Team
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
%
% 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/>.

47 48 49
if isnumeric(o) && (isscalar(o) ||  isvector(o))
    if ~isdseries(p)
        error('dseries:WrongInputArguments', 'Second input argument must be a dseries object!')
50
    end
51 52
    q = copy(p);
    q.data = bsxfun(@minus, o, p.data);
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
    if isscalar(o)
        for i=1:vobs(q)
            if isempty(q.ops{i})
                q.ops(i) = {sprintf('minus(%s, %s)', matrix2string(o), p.name{i})};
            else
                q.ops(i) = {sprintf('minus(%s, %s)', matrix2string(o), p.ops{i})};
            end
        end
        return
    end
    if isvector(o)
        for i=1:vobs(q)
            if isrow(o)
                oo = o(i);
            else
                oo = o;
            end
            if isempty(q.ops{i})
                q.ops(i) = {sprintf('minus(%s, %s)', matrix2string(oo), p.name{i})};
            else
                q.ops(i) = {sprintf('minus(%s, %s)', matrix2string(oo), p.ops{i})};
            end
        end
        return
    end
78 79
end

80 81
if isnumeric(p) && (isscalar(p) || isvector(p))
    if ~isdseries(o)
82 83
        error('dseries::minus: First input argument must be a dseries object!')
    end
84
    q = copy(o);
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    q.data = bsxfun(@minus, o.data, p);
    if isscalar(p)
        for i=1:vobs(q)
            if isempty(q.ops{i})
                q.ops(i) = {sprintf('minus(%s, %s)', o.name{i}, matrix2string(p))};
            else
                q.ops(i) = {sprintf('minus(%s, %s)', o.ops{i}, matrix2string(p))};
            end
        end
        return
    end
    if isvector(p)
        for i=1:vobs(q)
            if isrow(p)
                pp = p(i);
            else
                pp = p;
            end
            if isempty(q.ops{i})
                q.ops(i) = {sprintf('minus(%s, %s)', o.name{i}, matrix2string(pp))};
            else
                q.ops(i) = {sprintf('minus(%s, %s)', o.ops{i}, matrix2string(pp))};
            end
        end
        return
    end
end

if isdseries(o) && isempty(o)
    q = -copy(p);
    for i=1:vobs(q)
        q.ops(i) = {sprintf('minus(dseries(), %s)', q.ops{i}(8:end-1))};
    end
    return
end

if isdseries(p) && isempty(p)
    q = copy(o);
123 124 125
    return
end

126
if ~isequal(vobs(o), vobs(p)) && ~(isequal(vobs(o),1) || isequal(vobs(p),1))
127 128 129 130 131
    if isempty(inputname(1))
        error('dseries:WrongInputArguments', 'Cannot substract the two dseries objects (wrong number of variables)!')
    else
        error('dseries:WrongInputArguments', 'Cannot substract %s and %s (wrong number of variables)!', inputname(1), inputname(2))
    end
132
else
133 134 135 136 137 138
    if vobs(o)>vobs(p)
        ido = 1:vobs(o);
        idp = ones(1:vobs(o));
    elseif vobs(o)<vobs(p)
        ido = ones(1,vobs(p));
        idp = 1:vobs(p);
139
    else
140 141
        ido = 1:vobs(o);
        idp = ido;
142 143 144
    end
end

145
if ~isequal(frequency(o),frequency(p))
146 147 148 149 150
    if isempty(inputname(1))
        error('dseries:WrongInputArguments', 'Cannot substract the two dseries objects (frequencies are different)!')
    else
        error('dseries:WrongInputArguments', 'Cannot substract %s and %s (frequencies are different)!', inputname(1), inputname(2))
    end
151 152
end

153 154
if ~isequal(nobs(o), nobs(p)) || ~isequal(firstdate(o),firstdate(p))
    [o, p] = align(o, p);
155 156
end

157
q = dseries();
158

159 160 161 162
q.dates = o.dates;
q_vobs = max(vobs(o), vobs(p));
q.name = cell(q_vobs,1);
q.tex = cell(q_vobs,1);
163
q.ops = cell(q_vobs,1);
164
for i=1:q_vobs
165 166 167
    q.name(i) = {o.name{ido(i)}};
    q.tex(i) = {o.tex{ido(i)}};
    q.ops(i) = {sprintf('minus(%s, %s)', o.name{ido(i)}, p.name{idp(i)})};
168
end
169

170
q.data = bsxfun(@minus, o.data, p.data);
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

%@test:1
%$ % Define a datasets.
%$ A = rand(10,2); B = randn(10,1);
%$
%$ % Define names
%$ A_name = {'A1';'A2'}; B_name = {'B1'};
%$
%$ t = zeros(5,1);
%$
%$ % Instantiate a time series object.
%$ try
%$    ts1 = dseries(A,[],A_name,[]);
%$    ts2 = dseries(B,[],B_name,[]);
%$    ts3 = ts1-ts2;
%$    t(1) = 1;
%$ catch
%$    t = 0;
%$ end
%$
%$ if length(t)>1
%$    t(2) = dassert(ts3.vobs,2);
%$    t(3) = dassert(ts3.nobs,10);
%$    t(4) = dassert(ts3.data,[A(:,1)-B, A(:,2)-B],1e-15);
195
%$    t(5) = dassert(ts3.name,{'A1'; 'A2'});
196
%$    t(6) = dassert(ts1.data, A, 1e-15);
197
%$    t(7) = dassert(ts3.ops,{'minus(A1, B1)';'minus(A2, B1)'});
198 199 200 201
%$ end
%$ T = all(t);
%@eof:1

202
%@test:2
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
%$ % Define a datasets.
%$ A = rand(10,2); B = randn(5,1);
%$
%$ % Define names
%$ A_name = {'A1';'A2'}; B_name = {'B1'};
%$
%$ t = zeros(5,1);
%$
%$ % Instantiate a time series object.
%$ try
%$    ts1 = dseries(A,[],A_name,[]);
%$    ts2 = dseries(B,[],B_name,[]);
%$    ts3 = ts1-ts2;
%$    t(1) = 1;
%$ catch
%$    t = 0;
%$ end
%$
%$ if length(t)>1
%$    t(2) = dassert(ts3.vobs,2);
%$    t(3) = dassert(ts3.nobs,10);
%$    t(4) = dassert(ts3.data,[A(1:5,1)-B(1:5), A(1:5,2)-B(1:5) ; NaN(5,2)],1e-15);
225 226
%$    t(5) = dassert(ts3.name,{'A1';'A2'});
%$    t(6) = dassert(ts3.ops,{'minus(A1, B1)';'minus(A2, B1)'});
227 228
%$ end
%$ T = all(t);
229
%@eof:2
230

231
%@test:3
232 233 234 235 236 237
%$ ts1 = dseries(ones(3,1));
%$ ts2 = ts1-1;
%$ ts3 = 2-ts1;
%$ t(1) = isequal(ts2.data, zeros(3,1));
%$ t(2) = isequal(ts3.data, ts1.data);
%$ T = all(t);
238
%@eof:3
239

240
%@test:4
241 242 243 244 245 246
%$ ts1 = dseries(ones(3,2));
%$ ts2 = ts1-1;
%$ ts3 = 2-ts1;
%$ t(1) = isequal(ts2.data, zeros(3,2));
%$ t(2) = isequal(ts3.data, ts1.data);
%$ T = all(t);
247
%@eof:4
248

249
%@test:5
250 251 252 253 254 255
%$ ts1 = dseries(ones(3,2));
%$ ts2 = ts1-ones(3,1);
%$ ts3 = 2*ones(3,1)-ts1;
%$ t(1) = isequal(ts2.data, zeros(3,2));
%$ t(2) = isequal(ts3.data, ts1.data);
%$ T = all(t);
256
%@eof:5
257

258
%@test:6
259 260 261 262 263 264
%$ ts1 = dseries(ones(3,2));
%$ ts2 = ts1-ones(1,2);
%$ ts3 = 2*ones(1,2)-ts1;
%$ t(1) = isequal(ts2.data, zeros(3,2));
%$ t(2) = isequal(ts3.data, ts1.data);
%$ T = all(t);
265
%@eof:6