Single precision conversion errors?

I am creating an audio encoder using splines and the polyval function. I would like to be able to store all the polynomial coefficients as singles. The entire code works fine when the coefficients are stored as doubles. However, if I cast them as singles, their values change and the code breaks. I thought the break was coming from the polyval function, so I scratched it and evaluated the polynomials with my own code. The singles still have weird values though. I've attached the code I've been working with. Can anyone shed any light on how I could use single precision and not have the values change?
warning off all;
clc;
clf;
clear all;
[wave_data, Fs] = wavread('10 ms guitar.wav');
% Set display options for polyfit_constrained
options = optimset('lsqlin');
options = optimset(options, 'Display', 'off');
% Creates file to write to
writefile = 'outfile.dat';
fid = fopen(writefile, 'w');
% Low Pass Filter
fNorm = 16000 / (Fs/2);
[b, a] = butter(10, fNorm, 'low');
wave_data = filtfilt(b, a, wave_data);
differences = diff(wave_data);
flags = [];
xrange = [];
k = 1;
degree = 5;
minpoints = 6;
tic
% For loop plants flags at data index points when derivative changes sign
for i = 1:(length(differences) - 1)
if (differences(i) > 0 && differences (i + 1) < 0)...
|| (differences(i) < 0 && differences (i + 1) > 0)
flags(k) = i + 1;
if k ~= 1 && (flags(k) - flags(k - 1)) < minpoints
k = k;
else
k = k + 1;
end
%if size > 40
end
end
% For loop creates range of x-values and y-values for polynomial fitting
for j = 1:length(flags)
% If statement creates different x and y ranges for the first and last
% windows separately from all other windows
if j == 1
xrange = 1:flags(j);
yrange = wave_data(1:flags(j));
elseif j == length(flags)
xrange = (flags(j - 1) + 1):length(wave_data);
yrange = wave_data((flags(j - 1) + 1):length(wave_data));
else
xrange = (flags(j - 1) + 1):flags(j);
yrange = wave_data((flags(j - 1) + 1):flags(j));
end
polyval_coeffs = polyfit_constrained(xrange, yrange, degree, options)
s_polyval_coeffs = single(polyval_coeffs)
s_xrange = single(xrange);
ys = [];
yd = [];
for i=1:length(xrange)
x = xrange(i);
s_temp_y = s_polyval_coeffs(1)*x*x*x*x*x + s_polyval_coeffs(2)*x*x*x*x + s_polyval_coeffs(3)*x*x*x + s_polyval_coeffs(4)*x*x + s_polyval_coeffs(5)*x + s_polyval_coeffs(6);
ys = [ys; s_temp_y];
%x = xrange(i);
d_temp_y = polyval_coeffs(1)*x*x*x*x*x + polyval_coeffs(2)*x*x*x*x + polyval_coeffs(3)*x*x*x + polyval_coeffs(4)*x*x + polyval_coeffs(5)*x + polyval_coeffs(6);
yd = [yd; d_temp_y];
end
subplot(3,1,1);
plot(wave_data);
subplot(3,1,2);
plot(xrange, yd);
hold all;
subplot(3,1,3);
plot(xrange, ys);
hold all;
fwrite(fid, polyval_coeffs, 'double');
fwrite(fid, length(xrange), 'uint8');
end
fclose(fid);
toc

2 Comments

Can you be more specific about what you mean by "the code breaks"? Also, are you processing your values as singles, or do you always do the calculations as double and then cast the result to single at the end?
I always do the calculations as doubles and then cast at the end. Is there a better solution?
Also, when using doubles the audio quality is much better and the graph looks identical to the input. When using singles, the audio quality is terrible and all the polynomials seem to be pushed to straight lines when looking at the graph. Does that make more sense?

Sign in to comment.

Answers (1)

If problem appear in a program, this:
warning off all
is a bad idea. This suppresses warnings if the polynomial fitting is ill-conditioned and a normalization of the input data is recommended. If this happens in your code, using single values can lead to a loss of accuracy.
This:
polyval_coeffs(1)*x*x*x*x*x
is an instable method to evaluate a polynomial. Use the Horner-method instead.

1 Comment

I turned the warnings off because printing them slowed the run time down severely. Thanks for the tip though. The only warning I was getting was "Optimization Terminated." Do you think the situation you described is happening?

Sign in to comment.

Categories

Find more on Fourier Analysis and Filtering in Help Center and File Exchange

Asked:

on 27 Mar 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!