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
			//adjacent_difference (x.begin(), x.end() , diffX.begin());
			//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..
Can you please help me?
Thank you

Recommended Answers

All 3 Replies

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!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.