function [signal_in, signal_kvant, signal_out, signal_kvant_out, psnr, psnr_kvant, koef1, koef2] = signal_dequanting_impl(delka_signalu, ridkost, baze, wavelet, hloubka_decom, pocet_hladin)

global rozdeleni;
global delta;

disp(['Delka signalu: ' num2str(delka_signalu)]);
disp(['Ridkost: ' num2str(ridkost)]);
disp(strcat('Baze: ', baze));
disp(strcat('Wavelet: ', wavelet));
disp(['Hloubka Dekompozice: ' num2str(hloubka_decom)]);
disp(['Pocet kvant.hladin: ' num2str(pocet_hladin)]);



N = delka_signalu;
k = ridkost;
J = hloubka_decom;


% krty krty krt...
switch baze
    case 'DCT'
    U = dctmtx(N)';    
     
    case 'DWT'
    [Lo_D,Hi_D,Lo_R,Hi_R] = w_filters(wavelet); 
     U = dwtmatrix(Lo_D,Hi_D,J,N)';
   
    
end
    
%% Original_signal

x_signal = zeros(N, 1);
perm = randperm(N); %random positions of nonzeros
%vector of coordinates contains random values from [-1,1] at nonzero positions
indexes = perm(1:k);
x_signal(indexes) = 2*rand(k,1)-1;

signal_in = U * x_signal;

max_in = max(signal_in);
min_in = min(signal_in);

%% Coeficient_orig

switch baze
    case 'DCT'
         koef1 = abs(dct(signal_in));
    
    case 'DWT'
         koef1 = x_signal;
    
end

%% Quantized_signal

%parametrs of quantisation
delta = (max_in-min_in+0.1)/(pocet_hladin-2);         %sirka hladin
rozdeleni = (min_in-(delta/2)-0.1:delta:max_in+(delta/2));   % 0.1 pro osetreni pripadu kdyby nastala rovnost signal_kvant(i) = rozdeleni(1)+(delta/2)

% quantisation of signal
signal_kvant = signal_in;
for i = 1:N
    for j = 1:pocet_hladin
         if signal_kvant(i) < rozdeleni(j)+(delta/2) && signal_kvant(i)>= rozdeleni(j)-(delta/2)
            signal_kvant(i) = rozdeleni(j);
        end
    end
end


%% Dequantisation

f = (ones([1 2*N]));

y = signal_kvant;

s = (delta/2)*(ones([N 1]))-y;
t = (delta/2)*(ones([N 1]))+y;
b = [s t];
b = b(:);


A = [U -U; -U U];

lb = zeros(2*N,1);          %hledane hodnoty jsou kladne


w = linprog(f,A,b,[],[],lb);   %l1-minimization by linear programming 

uv = reshape(w,N,2);
u = uv(:, 1);
v = uv(:, 2);
sparse_coord_lin = v-u;        
signal_out = U*sparse_coord_lin;                      %reconstructed sparse vector of coordinates

%% Coeficient_dequant

switch baze
    case 'DCT'
         koef2 = abs(dct(signal_out));
    
    case 'DWT'
         koef2 = sparse_coord_lin;
    
end

%% PSNR
signal_in    = double(signal_in);
signal_out = double(signal_out);
absD = abs(signal_in-signal_out);
moc    = absD.^2;
mse  = sum(moc(:))/numel(signal_in);
psnr = 10*log10((max(signal_in)-min(signal_in))^2/mse);


%% quant_original vs. quant_recontr.

% quantisation of signal
signal_kvant_out = signal_out;
for i = 1:N
    for j = 1:pocet_hladin
        
         if  signal_kvant_out(i) < rozdeleni(j)+(delta/2) && signal_kvant_out(i)>= rozdeleni(j)-(delta/2)
             signal_kvant_out(i) = rozdeleni(j);
        
        end
    end
end

%% PSNR_kvant
%max_out = max(abs(signal_kvant));
signal_kvant    = double(signal_kvant);
signal_kvant_out = double(signal_kvant_out);
absD = abs(signal_kvant-signal_kvant_out);
moc    = absD.^2;
mse  = sum(moc(:))/numel(signal_kvant);
psnr_kvant= 10*log10((max(signal_kvant)-min(signal_kvant))^2/mse);





