% Joshua Mack, Sam Bellestri, Nia Simmonds IREECE 2015
% convertPlotAndPSNR_xToTheY:
%   Takes in the test domain used in a given testbench file along with the corresponding exponent and fractional widths of the floating-point format and number of iterations
%   And then looks for a corresponding results textfile of the form "(numIters)iterations(expWidth + fracWidth + 1)bits_xToTheY.txt" 
%   inside the "FloP_xToTheY_VivadoResults" directory within your current Matlab operating directory.
%   If it doesn't the file, it displays an error message and exits, and if the file doesn't have the number of points as specified by xPoints * yPoints,
%   Then it also returns an error and exits. 

function myPSNR = convertPlotAndPSNR_xToTheY(xLower, xUpper, xPoints, yPoints, expWidth, fracWidth, numIters)
    
    % Declare some variables
    dataWidth = expWidth+fracWidth+1;
    q = quantizer('float', [dataWidth expWidth]);
    xRange = linspace(xLower, xUpper, xPoints); 
    % yRange = linspace(yLower, yUpper, yPoints);
    fileName = [num2str(numIters), 'iterations', num2str(dataWidth), 'bits_xToTheY.txt'];
    
    % Attempt to open the results file. If not found, print an error and exit with psnr = -123456, 
    % which indicates for the corresponding "UltimateTestScript" that the current test case needs to be repeated.
    file1 = fopen(['./FloP_xToTheY_VivadoResults/', fileName], 'r');
    if file1 == -1
        fprintf('----------------------------------------------------\n');
        display(['xToTheY results not found for ', num2str(expWidth+fracWidth+1), ' bits, ', num2str(numIters), ' iterations.']);
        fprintf('----------------------------------------------------\n');
        myPSNR = -123456;
        return;
    end

    % Scan the values into a cell array of strings
    s1 = textscan(file1,'%s');
    fclose(file1);
    
    myPowStrs = s1{1};

    % If we don't have xPoints * yPoints data points, print an error and exit with psnr = -123456, 
    % which indicates for the corresponding "UltimateTestScript" that the current test case needs to be repeated.
    if length(myPowStrs) ~= xPoints*yPoints
        fprintf('----------------------------------------------------\n');
        display(['The Vivado simulator failed for ', num2str(expWidth+fracWidth+1), ' bits, ', num2str(numIters), ' iterations.']);
        fprintf('----------------------------------------------------\n');
        myPSNR = -123456;
        return;
    end
    
    myXToTheYs = zeros(xPoints, yPoints);
    
    % Extract the numerical values from the strings
    % (j, i) because 'surf' wants things in the order surf(yVals, xVals, zVals) 
    % So switch x and y to make it right.
    valNum = 1;
    for i = 1:1:xPoints
        for j = 1:1:yPoints
            myXToTheYs(j, i) = bin2num(q, cell2mat(myPowStrs(valNum)));
            valNum = valNum + 1;
        end
    end

    % Generate reference Matlab values. Note that y varies along the entire interval of convergence allowed for M = 5 at each given x value.
    matlabPows = zeros(xPoints, yPoints);
    for i = 1:1:xPoints
        yRange = linspace(-12.42644/log(xRange(i)), 12.42644/log(xRange(i)), yPoints);
        for j = 1:1:yPoints
            matlabPows(j, i) = xRange(i)^yRange(j);
        end
    end
    
    % Calculate PSNR and exit.
    maxVal = max(matlabPows(:));
    myPSNR = psnr(myXToTheYs, matlabPows, maxVal);
    display(myPSNR);
    return;
    
end