% Joshua Mack, Sam Bellestri, Nia Simmonds IREECE 2015
% convertPlotAndPSNR_coshX_sinhX:
%   Takes in the test domain used in a given testbench file along with the corresponding exponent and fractional widths of the format and number of iterations
%   And then looks for a corresponding results textfiles of the form "(numIters)iterations(expWidth+fracWidth+1)bits_cosh.txt" and "(numIters)iterations(expWidth+fracWidth+1)bits_sinh.txt"
%   inside the "FloP_coshX_VivadoResults" and "FloP_sinhX_VivadoResults" directories within your current Matlab operating directory.
%   If it doesn't find one of the files, it displays an error message, and if each file doesn't have the number of points as specified by xPoints,
%   Then it also returns an error and exits. 

function [coshPSNR, sinhPSNR] = convertPlotAndPSNR_coshX_sinhX(xLower, xUpper, xPoints, expWidth, fracWidth, numIters)
    
    % Define some variables.
    dataWidth = expWidth+fracWidth+1;
    q = quantizer('float', [dataWidth expWidth]);
    xRange = linspace(xLower, xUpper, xPoints); 
    
    fileName1 = [num2str(numIters), 'iterations', num2str(dataWidth), 'bits_cosh.txt'];
    fileName2 = [num2str(numIters), 'iterations', num2str(dataWidth), 'bits_sinh.txt'];
    
    % Attempt to open the coshX file.
    file1 = fopen(['./FloP_coshX_VivadoResults/', fileName1], 'r');
    if file1 == -1
        % If file fails to open, report an error and return psnr values of -123456, the error value used in the corresponding UltimateTestScript file
        % to indicate that a given simulation should repeat.
        display(['Cosh results failed to open for ', num2str(dataWidth), ' bits, ', num2str(numIters), ' iterations.']);
        coshPSNR = -123456;
        sinhPSNR = -123456;
        return;
    end
    % Read the values if it successfully opened.
    s1 = textscan(file1,'%s');
    fclose(file1);

    % Attempt to open the sinhX file.
    file2 = fopen(['./FloP_sinhX_VivadoResults/', fileName2], 'r');
    if file1 == -1
        % If file fails to open, report an error and return psnr values of -123456, the error value used in the corresponding UltimateTestScript file
        % to indicate that a given simulation should repeat.
        display(['Sinh results failed to open for ', num2str(dataWidth), ' bits, ', num2str(numIters), ' iterations.']);
        coshPSNR = -123456;
        sinhPSNR = -123456;
        return;
    end
    % Read the values if it successfully opened.
    s2 = textscan(file2,'%s');
    fclose(file2);
    
    % Extract the strings into cell arrays.
    myCoshStrs = s1{1};
    mySinhStrs = s2{1};

    % If the cell arrays don't have xPoints values, then report an error and indicate for the corresponding UltimateTestScript to repeat this test case. 
    if length(myCoshStrs) ~= xPoints && length(mySinhStrs) ~= xPoints
        display(['The Vivado simulator failed for ', num2str(dataWidth), ' bits, ', num2str(numIters), ' iterations.']);
        coshPSNR = -123456;
        sinhPSNR = -123456;
        return;
    end
    
    % Allocate memory.
    myCoshs = zeros(xPoints, 1);
    mySinhs = zeros(xPoints, 1);
    
    % Read the numerical values from the strings.
    for i = 1:1:xPoints
        myCoshs(i) = bin2num(q, cell2mat(myCoshStrs(i)));
        mySinhs(i) = bin2num(q, cell2mat(mySinhStrs(i)));
    end
    
    % Optional section that can be uncommented to enable plotting.
    % figure();
    % subplot(1, 2, 1);
    % plot(xRange, myCoshs); hold on;
    % subplot(1, 2, 2);
    % plot(xRange, mySinhs); hold on;

    % Allocate memory for the matlab comparison values.
    matlabCoshs = zeros(xPoints, 1);
    matlabSinhs = zeros(xPoints, 1);
    for i = 1:1:xPoints
        matlabCoshs(i) = cosh(xRange(i));
        matlabSinhs(i) = sinh(xRange(i));
    end
    
    % Max value is defined as the maximum value attained inside the current test range.
    % Calculate maximums, calculate PSNR values, and display PSNR values.
    maxCosh = max(cosh(xRange));
    maxSinh = max(sinh(xRange));
    coshPSNR = psnr(myCoshs, matlabCoshs, maxCosh);
    sinhPSNR = psnr(mySinhs, matlabSinhs, maxSinh);
    
    fprintf('Cosh PSNR: %f\nSinh PSNR: %f\n\n', coshPSNR, sinhPSNR);
    return;
    
end