hello, im just trying to translate a 1d TV denoising function for matlab, which can be found here http://cnx.org/content/m31292/latest/, to C++. Here's my attempt:

inline
vector<double> tvDenoising(vector<double> data, double lambda, int Nit)
{

vector<double> J (Nit);

int N = data.size();

vector<double> z (N-1);
fill (z.begin(),z.end(), double(0));

vector<double> diffZ (N-1);

//vector<double> frstEl (1);
//vector<double> lastEl (1);

vector<double> x (N);
vector<double> diffX (N);

double alpha=4;

for (int k=0; k < Nit; k++)
{
//adjacent_difference (z.begin(), z.end() , diffZ.begin());  //computing adjacent difference of elements of z
//diffZ.erase(diffZ.begin()); //erase first element

vector<double> diffZ = diff(z);

for (unsigned int i=0; i<diffZ.size(); i++)
{
diffZ[i] = -diffZ[i];
}

double frstEl = -z[0]; // 1st element of z
double lastEl = z.back(); //last element of z

diffZ.insert(diffZ.begin(), frstEl); //creation of complete Dtz
diffZ.insert(diffZ.end(), lastEl);

for (unsigned int j=0; j < data.size(); j++)
{
x[j] = data[j] - ((lambda/2)*diffZ[j]); //creation of x
}

//Filling the difference vector
//diffX.erase(diffX.begin());

vector<double> diffX = diff(x);

vector<double> absdiffX (diffX.size());
for (unsigned int i = 0; i < diffX.size(); i++)
{	absdiffX[i] = fabs(diffX[i]);	}

vector<double> X_Y_diff_sq ;
for (unsigned int i=0; i<x.size(); i++)
{
double abs_diff = fabs(x[i] - data[i]);
X_Y_diff_sq.push_back(abs_diff*abs_diff);
}

double sum1 = sumv(X_Y_diff_sq);
double sum2 = sumv(absdiffX);

J[k] = sum1 + lambda*sum2;

for (unsigned int m=0; m < z.size(); m++)
{
z[m] = z[m] + (2/(lambda*alpha*diffX[m]));
}

for (unsigned int n=0; n < z.size(); n++)  //clipping the values
{
double a = min(z[n], double(1));
z[n] = max(a,double(-1));
}
/**/
//diffZ.erase (diffZ.begin(),diffZ.end());
//diffX.erase (diffX.begin(),diffX.end());

}

return x;

}

where diff() and sumv() are these two functions:

inline
vector<double> diff(vector<double> data)
{
vector<double> vect_diff;
for (unsigned int i=1; i<data.size(); i++)
{
vect_diff.push_back(data[i]-data[i-1]);
}
return vect_diff;
}

inline
double sumv(vector<double> data)
{
double vect_sum = 0;
for (unsigned int i=0; i<data.size(); i++)
{
vect_sum += data[i];
}
return vect_sum;
}

Still don't get what i'm mistaking..My TV denoising doesnt work..
Thank you

2
Contributors
3
Replies
4
Views
7 Years
Discussion Span
Last Post by archduke83

Nobody?

Line 78, you messed up the operation priority. It should be:

z[m] = z[m] + (2/(lambda*alpha))*diffX[m];

To match the matlab version.

BTW, if you plan to use this C++ implementation, you have some serious cleaning up to do. You have way too much temporary memory allocations and passing vectors around function calls. Consider doing pass-by-reference and merging your loops together. For example, line 59 to 70, you first traverse a vector to fill another one with the absolute values, traverse that vector to square it into another vector, and finally pass the vector (by-value) to a summation function. Why not make one loop that takes each element of the original vector, square it and sum it (no additional memory and just one single, clean loop, which would also turn your 11 lines into only 3 lines or so).

Yes, you're absolutely right..i was just so confused about my code i tried everything..even splitting up every single step to see what was working or not.
I'm a complete beginner..have a lot of work to do!
Thank you, i will try with your corrections and let you know!

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.