function [DTStatus,TData,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,VariableData,Transformation,SkipInversionTest)
% CalcTransformData: Computes transformation of a matrix with data using the variables individual
%                    transformation functions.
%
% USAGE:
%
%       [DTStatus,TData,ErrorStr,HeaderStr] = CalcTransformData(VariableNames,VariableData,Transformation,SkipInversionTest)
%
% REQUIRED INPUT:  VariableNames (string matrix) with the names for the variables that should
%                                be checked if they can be transformed and inverted.
%
%                  VariableData (matrix) of dimension Txk, where T is the number of observations
%                                and k is the number of variables. The latter must be equal to
%                                the number of rows in the string matrix VariableNames.
%
%                  Transformation (structure) with field names. The field name to use is determined
%                                by CurrVariable. This field name has subfields "fcn", "annualizefcn",
%                                "initial", "x", "invertfcn", "invertinitial", and "invertx".
%
% OPTIONAL INPUT:  SkipInversionTest (boolean) that determines if the function should perform an inversion
%                                test or not. If not specified, then the variable is set to 0, i.e, don't
%                                skip the inversion test.
%
% REQUIRED OUTPUT: DTStatus (boolean) that is 1 if all the transformations and invertion were
%                                successful and 0 otherwise.
%
%                  TData (matrix) of dimension Txk with the transformed data.
%
%                  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-2008 European Central Bank.
%
%                       First version: October 30, 2007.
%                        This version: December 18, 2008.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% 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:
%
% * 14-11-2007: The input variables "FirstObs" and "LastObs" were added. The output variables "ErrorStr"
%               and "HeaderStr" were also added.
%
% * 19-11-2007: Updated the documentation.
%
% * 20-11-2007: The inputs "FirstObs" and "LastObs" have been removed.
%
% * 16-1-2008:  Added the optional input variable "SkipInversionTest". This test can prove hazardous when
%               comparison data are used since the initial conditions of the inversion may not be the correct
%               ones, thereby leading to an unwanted negative outsome of the inversion test.
%
% * 23-5-2008:  Updated the documentation.
%
% * 18-12-2008: Updated the documentation.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%

%
% initialize
%
DTStatus = 0;
TData = [];
ErrorStr = '';
HeaderStr = '';
if nargin==3;
   SkipInversionTest = 0;
end;
%
% test if the number of variables match
%
if size(VariableNames,1)~=size(VariableData,2);
   VariableData = VariableData';
   if size(VariableNames,1)~=size(VariableData,2);
      return;
   end;
end;
%
% create a potential output candidate
%
DataMatrix = NaN*ones(size(VariableData));
[T k] = size(DataMatrix);
%
NumTransforms = 0;
for i=1:k;
   %
   % compute the transformation
   %
   y = VariableData(:,i);
   CurrVariable = StringTrim(VariableNames(i,:));
   [z,Status,ErrorStr,HeaderStr,FcnStr] = TransformData(y,Transformation,CurrVariable,0);
   if Status==0;
      %
      % transformation went OK. Now try to invert the results
      %
      if length(z)>length(y);
         z = z(length(z)-length(y)+1:length(z));
      end;
      if SkipInversionTest==0;
         [yalt,InvStatus,ErrorStr,HeaderStr] = InvertTransformData(z,Transformation,CurrVariable);
      else;
         InvStatus = 0;
         yalt = y;
      end;
      %
      % check if we have too few observations for the inversion
      %
      if (InvStatus==0)&(length(yalt)<length(y));
         InvStatus = 1;
         ErrorStr = ['Too few observation when inverting the transformation of "' CurrVariable '" relative to the original number of observations.'];
         HeaderStr = 'Bad Inversion Function';
      end;
      %
      if InvStatus==0;
         %
         % The invertion went fine.
         %
         if length(yalt)>length(y);
            yalt = yalt(length(yalt)-length(y)+1:length(yalt));
         end;
         %
         % check if inversion error is small enough to be neglected
         %
         if max(abs(y-yalt))<1.0e-010;
            %
            % now we can add the data to DataMatrix
            %
            DataMatrix(T-length(z)+1:T,i) = z;
            NumTransforms = NumTransforms+1;
         else;
            InvStatus = 1;
            ErrorStr = ['The error when inverting the transformation of "' CurrVariable '" is greater than 1.0e-010. The transformation and inversion functions are therefore not used by YADA for the current application.'];
            HeaderStr = 'Bad Inversion Function';
            break;
         end;
      else;
         %
         % inversion failed
         %
         break;
      end;
   else;
      break;
   end;
end;
%
% check if transformed data should be supplied as output along with the
% indicator that everything went "sufficiently" well
%
if NumTransforms==k;
   DTStatus = 1;
   TData = DataMatrix;
end;

%
% end of CalcTransformData.m
%
