% =================================================================================  
%   File Name            :  generate_nndef.m                                     	
%   Creation date        :  November 22, 2003                                     
%   Last Modification    :  December 30, 2003                                     
%   Copyright 			 :  (c) 2003 Pejman Makhfi    http://www.makhfi.com
%
%   Comments             :  Matlab function to generate NNDef XML file from a
%							Neural Network object
%							Inputs: 
%								1) Network Variable Name
%								2) XML File Name
%							Output:
%								NNDef XML file
% =================================================================================  
%
% DISCLAIMER: THIS WORK IS PROVIDED "AS IS." THE COPYRIGHT HOLDER AND THE            
% CONTRIBUTING AUTHORS OF THIS WORK MAKE NO REPRESENTATIONS OR WARRANTIES (i)        
% EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,   
% FITNESS FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT; (ii) THAT THE         
% CONTENTS OF SUCH WORK ARE FREE FROM ERROR OR SUITABLE FOR ANY PURPOSE; NOR THAT    
% IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS,         
% COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. IN NO EVENT WILL THE COPYRIGHT HOLDER      
% AND THE CONTRIBUTORS TO THIS WORK BE LIABLE TO ANY PARTY FOR ANY DIRECT,           
% INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES FOR ANY USE OF THIS WORK, INCLUDING,    
% WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR   
% OTHER DATA ON YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN IF THE           
% COPYRIGHT HOLDER OR ANY CONTRIBUTORS TO THIS WORK IS EXPRESSLY ADVISED OF THE      
% POSSIBILITY OF SUCH DAMAGES.                                                       
%
% Permission to use and distribute the NNDEF DTD and its accompanying documentation  
% for any purpose and without fee is hereby granted in perpetuity, provided that     
% the above copyright notice and this paragraph appear in all copies.                
% The copyright holders make no representations about the suitability of the DTD     
% for any purpose.                                                                   
%
% ================================================================================= 

format long e;

net_name = input('Please, enter neural network name: ','s');

%check whether the object exists:
if (~exist(net_name,'var'))
    fprintf('Neural network %s does not exist',net_name);
    clear net_name;
    return;
else
    %obj exists, but is it a Neural net?
    obj=whos(net_name,'var');
    obj_class = obj(1).class;
    if (~strcmp(obj_class,'network'))
        disp ('This is not a network object');
        clear obj_class net_name obj;
        return;
    else
        %This is valid NN object, prompt for XML file name:
        [fname, path] = uiputfile( {'*.XML', 'NNDEF XML Files (*.xml)'},'Save NN Definition file as:');
        if(fname == 0)
            disp('Output file name not chosen');
            clear obj_class net_name obj fname path;
            return;
        else
            path = strcat(path,fname);
        end
    end
end

%Append ".XML" extnesion if not supplied:
if (isempty(strfind(upper(path), '.XML')))
    path = strcat(path,'.xml');
end

neural_net = eval(net_name);
[num_rows, ins] = size(neural_net.iw{1});
[outs,num_cols] = size(neural_net.lw{neural_net.numLayers, neural_net.numLayers-1});

if (strcmp(neural_net.adaptFcn,''))
    net_type = 'RBF';
else
     net_type = 'MLP';
end

fid = fopen(path,'w');

%perform XML content generation:
fprintf(fid, '<?xml version="1.0" encoding="UTF-8"?>\n'); 
fprintf(fid, '<!DOCTYPE NNDEF SYSTEM "http://www.makhfi.com/nndef_v1_0.dtd">\n');
fprintf(fid, '<NNDEF version="1.0">\n');
fprintf(fid, '	<Network Type="%s" Layers="%d" Inputs="%d" Outputs="%d" AutoScale="off">\n',net_type,neural_net.numLayers, ins,outs);
fprintf(fid, '		<Name>[PLEASE REPLACE]</Name>\n');
fprintf(fid, '		<Description>\n');
fprintf(fid, '		[PLEASE REPLACE]\n');
fprintf(fid, '		</Description>\n');
fprintf(fid, '		<CreatedOn>%s</CreatedOn>\n', datestr(now,23));
fprintf(fid, '		<Author>\n');
fprintf(fid, '			<Name>[PLEASE REPLACE]</Name>\n');
fprintf(fid, '			<Contact Type="E-mail">[PLEASE REPLACE]</Contact>\n');
fprintf(fid, '		</Author>\n');
fprintf(fid, '		<InputList>\n');
for j=1:ins
    fprintf(fid, '			<Input OrderId="%d" Name="input%d"    ScaleOffset="0" ScaleBy="100"/>\n',j,j);
end
fprintf(fid, '		</InputList>\n');
fprintf(fid, '		<OutputList>\n');
for j=1:outs
    fprintf(fid, '			<Output OrderId="%d" Name="output%d" ScaleOffset="0" RescaleBy="100"/>\n',j,j);
end
fprintf(fid, '		</OutputList>\n');
fprintf(fid, '	</Network>\n\n');



for j=1:neural_net.numLayers
    if j==1
        weights = neural_net.iw{1};      
    else
        weights = neural_net.lw{j, j-1};
    end
    [num_rows, num_cols] = size(weights);

    biases = neural_net.b{j};

    fprintf(fid, '	<Layer OrderId="%d" TransferFunction="%s" CombinationFunction="%s">\n',j,neural_net.layers{j}.transferFcn,neural_net.layers{j}.netInputFcn);
    for k=1:num_rows
        fprintf(fid, '        <Neuron OrderId="%d">\n',k);
        fprintf(fid, '			<InputWeights>\n');
        for m = 1:num_cols
            fprintf(fid, '				<Weight OrderId="%d" Value="%.15f"/>\n',m,weights(k,m));
        end
        fprintf(fid, '			</InputWeights>\n');
        fprintf(fid, '			<Bias Value="%.15f"/>\n',biases(k));
        fprintf(fid, '		</Neuron>\n');
    end
    fprintf(fid, '	</Layer>\n');
end

fprintf(fid, '</NNDEF>\n');


fclose(fid);
clear obj_class net_name obj fname path neural_net num_rows num_cols ins outs net_type fid weights biases;
