function [CDataT,CSteadyStateT,CHistT,CMeasureErrorT,CShocksT,CApproxErrorT,Status,ErrorStr,HeaderStr] = CalcTransformDecomposition(CData,CSteadyState,CHist,CMeasureError,CShocks,CTransformation,CSSTransformation,CHistTransformation,CMETransformation,CShocksTransformation,VariableNames,ShockNames)
% CalcTransformDecomposition: Applies suitable transformation functions to observed variable decompositions.
%
% USAGE:
%
%       [CDataT,CSteadyStateT,CHistT,CMeasureErrorT,CShocksT,CApproxErrorT,Status,ErrorStr,HeaderStr] = CalcTransformDecomposition(CData,CSteadyState,CHist,CMeasureError,CShocks,CTransformation,CSSTransformation,CHistTransformation,CMETransformation,CShocksTransformation,VariableNames,ShockNames)
%
% REQUIRED INPUT:  CData (matrix) of dimension cxT with data to transform.
%
%                  CSteadyState (matrix) of dimension cxT with the steady-state term in the decomposition of CData.
%
%                  CHist (matrix) of dimension cxT with the historical term in the decomposition of CData.
%
%                  CMeasureError (matrix) of dimension cxT with the measurement error term in the decomposition of CData.
%
%                  CShocks (3D matrix) of dimension cxTxq with the q economic shock terms in the decomposition of CData.
%
%                  CTransformation  (structure) with field names. The field name to use is determined by CurrVariable.
%                                   This field name has subfields "fcn", "partial", "annualizefcn", "initial", "x",
%                                   "invertfcn", "invertinitial", and "invertx". Used to transform CData.
%
%                  CSSTransformation (structure) with field names. The field name to use is determined by CurrVariable.
%                                   This field name has subfields "fcn", "partial", "annualizefcn", "initial", "x",
%                                   "invertfcn", "invertinitial", and "invertx". Used to transform CData.
%
%                  CHistTransformation (structure) with field names. The field name to use is determined by CurrVariable.
%                                   This field name has subfields "fcn", "partial", "annualizefcn", "initial", "x",
%                                   "invertfcn", "invertinitial", and "invertx". Used to transform CHist.
%
%                  CMETransformation (structure) with field names. The field name to use is determined by CurrVariable.
%                                   This field name has subfields "fcn", "partial", "annualizefcn", "initial", "x",
%                                   "invertfcn", "invertinitial", and "invertx". Used to transform CMeasureError.
%
%                  CShocksTransformation (structure) with field names. The field name to use is determined by CurrVariable.
%                                   This field name has subfields "fcn", "partial", "annualizefcn", "initial", "x",
%                                   "invertfcn", "invertinitial", and "invertx". Used to transform CShocks.
%
%                  VariableNames (string matrix) with the names of the variables.
%
%                  ShockNames (string matrix) with the names of the economic shocks.
%
% REQUIRED OUTPUT: CDataT (matrix) of dimension cxT with the transformation of CData.
%
%                  CSteadyStateT (matrix) of dimension cxT with "steady state" and approximation errors for the transformation
%                                   of the decomposition of CData. Equal to CDataT-(CHistT+CMeasureErrorT+
%                                   CShocksT(:,:,1)+...+CShocks(:,:,q)).
%
%                  CHistT (matrix) of dimension cxT with the first order Taylor expansion term that is due to CHist.
%
%                  CMeasureErrorT (matrix) of dimension cxT with the first order Taylor expansion term that is due
%                                   to CMeasureError.
%
%                  CShocksT (3D matrix) of diemsnion cxTxq with the first order Taylor expansion term that is due
%                                   to CShocks.
%
%                  CApproxErrorT (matrix) of dimension cxT with the difference between CDataT and the sum of
%                                   CSteadyStateT, CHistT, CMeasureErrorT, COtherT and the q shocks in CShocksT.
%
%                  Status (boolean) that indicates if all transformation went well (1) or not (0).
%
%                  ErrorStr (string vector) with error messages (if any).
%
%                  HeaderStr (string vector) with a suitable header message (if any).
%
%
%                       Written by: Anders Warne
%                                   New Area Wide Model Project
%                                   DG-R/EMO
%                                   European Central Bank (ECB)
%                                   Email: anders.warne@ecb.europa.eu
%                                   Copyright © 2006-2009 European Central Bank.
%
%                       First version: July 31, 2008.
%                        This version: January 23, 2009.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LICENSE INFORMATION:
%
%      YADA 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.
%
%      This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
%
%      YADA is released under the GNU General Public License, Version 3,
%      29 June 2007 <http://www.gnu.org/licenses/>. The current release of
%      the program was last modified by the ECB on the "This version" date
%      above.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% CHANGELOG:
%
% * 01-08-2008: Fixed bugs with break calls instead of return calls.
%
% * 08-08-2008: Added the calls to ChangeTransformationExogenous.
%
% * 18-12-2008: Updated the documentation.
%
% * 23-01-2009: Added the input variables "CSteadyState" and "CSSTransformation" and the output
%               variable "CApproxErrorT".
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

%
% initialize
%
CDataT = [];
CSteadyStateT = [];
CHistT = [];
CMeasureErrorT = [];
CShocksT = [];
CApproxErrorT = [];
Status = 0;
ErrorStr = '';
HeaderStr = '';
%
% compute the transformation for CData
%
[DTStatus,DataT,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,CData',CTransformation,1);
if DTStatus==0;
   return;
end;
if max(max(isnan(DataT)))==1;
   NaNPosition = max(isnan(DataT) .* (ones(size(DataT,1),1)*(1:size(DataT,2))));
   NaNPosition = min(NaNPosition(NaNPosition>0));
   ErrorStr = ['YADA obtained an NaN value for "' StringTrim(VariableNames(NaNPosition,:)) '" when attempting to transform the scenario data. The plots will therefore display the decompositions for the untransformed data.'];
   HeaderStr = 'YADA - Transformation Error';
   return;
end;
CDataT = DataT';
%
% compute the transformation for the CSteadyState
%
[DTStatus,DataT,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,CSteadyState',CSSTransformation,1);
if DTStatus==0;
   return;
end;
if max(max(isnan(DataT)))==1;
   NaNPosition = max(isnan(DataT) .* (ones(size(DataT,1),1)*(1:size(DataT,2))));
   NaNPosition = min(NaNPosition(NaNPosition>0));
   ErrorStr = ['YADA obtained an NaN value for "' StringTrim(VariableNames(NaNPosition,:)) '" when attempting to transform the steady-state term in the decomposition of the scenario data. The plots will therefore display the decompositions for the untransformed data.'];
   HeaderStr = 'YADA - Transformation Error';
   return;
end;
CSteadyStateT = DataT';
%
% setup the x-variables
%
CHistTransformation = ChangeTransformExogenous(CHistTransformation,VariableNames,CHist);
%
% now try to apply the transformation to CHist (where the partial is evaluated using CData
% and the partial is multiplied by CHist in x.
%
[DTStatus,DataT,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,CData',CHistTransformation,1);
if DTStatus==0;
   return;
end;
if max(max(isnan(DataT)))==1;
   NaNPosition = max(isnan(DataT) .* (ones(size(DataT,1),1)*(1:size(DataT,2))));
   NaNPosition = min(NaNPosition(NaNPosition>0));
   ErrorStr = ['YADA obtained an NaN value for "' StringTrim(VariableNames(NaNPosition,:)) '" when attempting to transform the history term in the decomposition of the scenario data. The plots will therefore display the decompositions for the untransformed data.'];
   HeaderStr = 'YADA - Transformation Error';
   return;
end;
CHistT = DataT';
%
% setup the x-variables
%
CMETransformation = ChangeTransformExogenous(CMETransformation,VariableNames,CMeasureError);
%
% now try to apply the transformation to CMeasureError (where the partial is evaluated using CData
% and the partial is multiplied by CHist in x.
%
[DTStatus,DataT,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,CData',CMETransformation,1);
if DTStatus==0;
   return;
end;
if max(max(isnan(DataT)))==1;
   NaNPosition = max(isnan(DataT) .* (ones(size(DataT,1),1)*(1:size(DataT,2))));
   NaNPosition = min(NaNPosition(NaNPosition>0));
   ErrorStr = ['YADA obtained an NaN value for "' StringTrim(VariableNames(NaNPosition,:)) '" when attempting to transform the measurement error term in the decomposition of the scenario data. The plots will therefore display the decompositions for the untransformed data.'];
   HeaderStr = 'YADA - Transformation Error';
   return;
end;
CMeasureErrorT = DataT';
%
% now try to apply the transformation to CShocks (where the partial is evaluated using CData
% and the partial is multiplied by CHist in x.
%
BadShock = 0;
CShocksT = zeros(size(CShocks,3),size(CData,2),size(CShocks,3));
OldCShocksTransformation = CShocksTransformation;
for j=1:size(CShocks,3);
   %
   % setup the x-variables for the individual shocks
   %
   CShocksTransformation = ChangeTransformExogenous(OldCShocksTransformation,VariableNames,CShocks(:,:,j));
   %
   % now try to apply the transformation to CShocks term j (where the partial is evaluated using CData
   % and the partial is multiplied by CHist in x.
   %
   [DTStatus,DataT,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,CData',CShocksTransformation,1);
   if DTStatus==0;
      break;
   end;
   if max(max(isnan(DataT)))==1;
      BadShock = j;
      break;
   end;
   CShocksT(:,:,j) = DataT';
end;
if DTStatus==0;
   return;
end;
if max(max(isnan(DataT)))==1;
   NaNPosition = max(isnan(DataT) .* (ones(size(DataT,1),1)*(1:size(DataT,2))));
   NaNPosition = min(NaNPosition(NaNPosition>0));
   ErrorStr = ['YADA obtained an NaN value for "' StringTrim(VariableNames(NaNPosition,:)) '" when attempting to transform the term for the economic shock "' StringTrim(ShockNames(BadShock,:)) '" in the decomposition of the scenario data. The plots will therefore display the decompositions for the untransformed data.'];
   HeaderStr = 'YADA - Transformation Error';
   return;
end;
%
% now we can compute the steady state+approximation error term
%
ShockPart = zeros(size(CDataT));
for j=1:size(CShocksT,3);
   ShockPart = ShockPart+CShocksT(:,:,j);
end;
CApproxErrorT = CDataT-(CSteadyStateT+CHistT+CMeasureErrorT+ShockPart);
Status = 1;

%
% end of CalcTransformDecomposition.m
%
