Optimizing code from spectral subtraction algorithm

This is part of the code from a spectral subtraction algorithm. I'm trying to optimize it for Android.

Matlab code:

function Seg=segment(signal,W,SP,Window)

% SEGMENT chops a signal to overlapping windowed segments
% A= SEGMENT(X,W,SP,WIN) returns a matrix which its columns are segmented
% and windowed frames of the input one dimentional signal, X. W is the
% number of samples per window, default value W=256. SP is the shift
% percentage, default value SP=0.4. WIN is the window that is multiplied by
% each segment and its length should be W. the default window is hamming
% window.
% 06-Sep-04
% Esfandiar Zavarehei

if nargin<3
SP=.4;
end
if nargin<2
W=256;
end
if nargin<4
Window=hamming(W);
end
Window=Window(:); %make it a column vector

L=length(signal);
SP=fix(W.*SP);
N=fix((L-W)/SP +1); %number of segments

Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
hw=repmat(Window,1,N);
Seg=signal(Index).*hw;

Java code:

public class MatrixAndSegments
{
public int numberOfSegments;
public double[][] res;

public MatrixAndSegments(int numberOfSegments,double[][] res)
{
this.numberOfSegments = numberOfSegments;
this.res = res;
}
}

public MatrixAndSegments segment (double[] signal_in,int samplesPerWindow, double        shiftPercentage, double[] window)
{
//default shiftPercentage = 0.4
//default samplesPerWindow = 256  //W
//default window = hanning

int L = signal_in.length;
shiftPercentage = fix(samplesPerWindow * shiftPercentage); //SP
int numberOfSegments = fix ( (L - samplesPerWindow)/ shiftPercentage + 1); //N

double[][] reprowMatrix =  reprowtrans(samplesPerWindow,numberOfSegments);
double[][] repcolMatrix = repcoltrans(numberOfSegments, shiftPercentage,samplesPerWindow );

//Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
double[][] index = new double[samplesPerWindow+1][numberOfSegments+1];

for (int x = 1;  x < samplesPerWindow+1; x++ )
{
for (int y = 1 ; y < numberOfSegments + 1; y++) //numberOfSegments was 3
{
index[x][y] = reprowMatrix[x][y] + repcolMatrix[x][y];
}
}

//hamming window
double[] hammingWindow = this.HammingWindow(samplesPerWindow);
double[][] HW = repvector(hammingWindow, numberOfSegments);

double[][] seg = new double[samplesPerWindow][numberOfSegments];
for (int y = 1 ; y < numberOfSegments + 1; y++)
{
for (int x = 1; x < samplesPerWindow+1; x++)
{
seg[x-1][y-1] = signal_in[ (int)index[x][y]-1 ] * HW[x-1][y-1];
}
}
MatrixAndSegments Matrixseg = new MatrixAndSegments(numberOfSegments,seg);
return Matrixseg;

}

public int fix(double val) {
if (val < 0) {
return (int) Math.ceil(val);
}
return (int) Math.floor(val);
}

public double[][] repvector(double[] vec, int replications)
{
double[][] result = new double[vec.length][replications];

for (int x = 0; x < vec.length; x++) {
for (int y = 0; y < replications; y++) {
result[x][y] = vec[x];
}
}

return result;
}

public double[][] reprowtrans(int end, int replications)
{
double[][] result = new double[end +1][replications+1];

for (int x = 1; x <= end; x++) {
for (int y = 1; y <= replications; y++) {
result[x][y] = x ;
}
}

return result;
}

public double[][] repcoltrans(int end, double multiplier, int replications)
{
double[][] result = new double[replications+1][end+1];

for (int x = 1; x <= replications; x++) {
for (int y = 1; y <= end ; y++) {
result[x][y] = (y-1)*multiplier;
}
}

return result;
}

public double[] HammingWindow(int size)
{
double[] window = new double[size];
for (int i = 0; i < size; i++)
{

window[i] =  0.54-0.46 * (Math.cos(2.0 * Math.PI * i / (size-1)));
}
return window;
}
• you could start by flattening your double[][] to double[]. If every little bit counts, there's some RAM and speed you can gain by it. – Arne Aug 24 '12 at 13:09
• does it need optimization for android? have you profiled the code? – Denis Tulskiy Aug 25 '12 at 13:25

I don't have a clue about spectral subtraction, so just some minor, general notes about code:

1. public int fix(double val) {
if (val < 0) {
return (int) Math.ceil(val);
}
return (int) Math.floor(val);
}

It should be called truncate.

2. A few variables could be renamed to follow the Java code conventions.

• Variables, parameters:
• signal_in to inputSignal or signal
• HW to hw
• seg maybe to segments or segment (?)
• Matrixseg to matrixSeg
• Methods:
• HammingWindow to calculateHammingWindow

(Effective Java, 2nd edition, Item 56: Adhere to generally accepted naming conventions and The Java Language Specification, Java SE 7 Edition, 6.1 Declarations).

3. This comments looks unnecessary:

// hamming window
double[] hammingWindow = this.HammingWindow(samplesPerWindow);

(Clean Code by Robert C. Martin: Chapter 4: Comments, Noise Comments)

The this. prefix also unnecessary.

• hw could have a better name. I don't know why he have hammingWindows and then HW, when it's looks like the same thing but does not represent the same data (double[] vs double[][]). Maybe switch the two name so that the one who is used more often would have a complete name ? – Marc-Andre Mar 10 '14 at 14:35