Skip to content
Snippets Groups Projects
dtw.cpp 32.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Martin Rusek's avatar
    Martin Rusek committed
    		
    		size_t jEnd = i >= B.size() ? B.size() + 1 : i + 2;
    		for (size_t j = 1; j < jEnd; j++)
    		{
    
    			node2<double> l = m2[j - 1];	//l
    			node2<double> u = m2[j];		//u
    			node2<double> d = m1[j - 1];	//d
    
    Martin Rusek's avatar
    Martin Rusek committed
    
    			double min = std::min({ l.value, u.value, d.value });
    
    			//m3[j] = calcul::distance_dtw(A[a], B[j - 1]) + min;
    			m3[j] = calcul::distance_dtw_simd(A[a], B[j - 1], simds, rest) + min;
    						
    			//cout << a - 1 << ", " << j - 1 << ", " << j - 1 << ", " << j << ", " << j - 1 << endl;
    			
    			if (min == d.value)
    				m3[j].pathSize = d.pathSize + 1;
    			else if (u.value < l.value)
    				m3[j].pathSize = u.pathSize + 1;
    			else if (l.value < u.value)
    				m3[j].pathSize = l.pathSize + 1;
    			else
    			{
    				if (l.pathSize < u.pathSize)
    					m3[j].pathSize = l.pathSize + 1;
    				else if (u.pathSize < l.pathSize)
    					m3[j].pathSize = u.pathSize + 1;
    				else
    				{
    					double coefA = A.size() / (double)a;
    					double coefB = B.size() / (double)j;
    
    					if (coefA > coefB)
    						m3[j].pathSize = l.pathSize + 1;
    					else
    						m3[j].pathSize = u.pathSize + 1;
    
    				}
    			}
    			a--;
    		}
    		//cout << a - 1 << ", " << j - 1 << ", " << j - 1 << ", " << j << ", " << j - 1 << endl;
    		m1.swap(m2);
    		m2.swap(m3);
    
    		m3[0].value = constant::MAX_double;
    
    Martin Rusek's avatar
    Martin Rusek committed
    	}
    		
    	rotate(m2.begin(), m2.begin() + 1, m2.end());
    
    Martin Rusek's avatar
    Martin Rusek committed
    	for (size_t i = 1; i < B.size(); i++) 
    	{
    		size_t a = A.size() - 1;
    		size_t jEnd = A.size() - i;
    			// A.size() - (i - lenDiff);
    
    		if (B.size() > A.size()) 
    		{
    			if(i > lenDiff)
    				jEnd = A.size() - (i - lenDiff);
    			else
    				jEnd = A.size();
    		}
    		else
    			jEnd = std::min(A.size(), B.size()) - i; // -1 for decreasing size of last triangle
    		
    		for (size_t j = 0; j < jEnd/* A.size() - i*/; j++)
    		{
    
    			node2<double> l = m2[j];			//l
    			node2<double> u = m2[j + 1];		//u
    			node2<double> d = m1[j + 1];		//d
    
    Martin Rusek's avatar
    Martin Rusek committed
    
    			//__m256d v256 = _mm256_set_pd(l.value, u.value, d.value, dMAX)
    			//__mm256_min
    			
    			double min = std::min({l.value, u.value, d.value });
    
    			//m3[j] = calcul::distance_dtw(A[a], B[j + i]) + min;//l,u,d
    			m3[j] = calcul::distance_dtw_simd(A[a], B[j + i], simds, rest) + min;
    
    			//cout << a << ", " << j << ", " << j << ", " << j + 1 << ", " << j + 1 << endl;
    			
    			if (min == d.value)
    				m3[j].pathSize = d.pathSize + 1;
    			else if (u.value < l.value)
    				m3[j].pathSize = u.pathSize + 1;
    			else if (l.value < u.value)
    				m3[j].pathSize = l.pathSize + 1;
    			else
    			{
    				if (l.pathSize < u.pathSize)
    					m3[j].pathSize = l.pathSize + 1;
    				else if (u.pathSize < l.pathSize)
    					m3[j].pathSize = u.pathSize + 1;
    				else
    				{
    					double coefA = A.size() / (double)a + 1;
    					double coefB = B.size() / (double)j + 1;
    
    					if (coefA > coefB)
    						m3[j].pathSize = l.pathSize + 1;
    					else
    						m3[j].pathSize = u.pathSize + 1;
    
    				}
    			}
    			a--;
    		}
    		m1.swap(m2);
    		m2.swap(m3);
    	}
    
    
    	result_path back;
    
    Martin Rusek's avatar
    Martin Rusek committed
    	//back.path     = m2[0].path;
    	back.scoreRaw = m2[0].value;
    
    	back.start.col = 0;
    	back.start.row = 0;
    	back.end.col = (int)B.size();
    	back.end.row = (int)A.size();
    
    	return back;
    
    }
    
    vtr2<double> dtw::tserie_merge(vtr2<double> const &A, vtr2<double> const &B, result_path const &warping)
    {
    	vtr2<double> result;
    	vtr<double> tmpPoint(A[0].size());
    	//warping.convert_toCoords();
    
    	for (size_t i = 0; i < A[0].size(); i++)
    		tmpPoint[i] = (A[0][i] + B[0][i]) / 2;
    	result.push_back(tmpPoint);
    
    	for (size_t i = 1; i < warping.pathCoords.size(); i++)
    	{
    		if (warping.pathCoords[i].row - warping.pathCoords[i - 1].row == 0 || warping.pathCoords[i].col - warping.pathCoords[i - 1].col == 0)
    			continue;
    		else
    			for (size_t k = 0; k < A[0].size(); k++)
    				tmpPoint[k] = (A[warping.pathCoords[i].row - 1][k] + B[warping.pathCoords[i].col - 1][k]) / 2;			
    		
    		result.push_back(tmpPoint);
    	}
    
    	return result;
    }
    
    //vtr2<double> dtw::tserie_merge(vtr3<double> const &tset, result_path const &warping)
    //{
    //	vtr2<double> result;
    //	warping.convert_toCoords();
    //
    //	for (size_t i = 0; i < warping.pathCoords.size(); i++)
    //	{
    //
    //	}
    //
    //	return result;
    //}
    
    //vtr<tspoint> dtw::tserie_merge(vtr<tspoint> const &A, vtr<tspoint> const &B, result_path const &warping)
    //{
    //	vtr<tspoint> result;
    //	tspoint tmp(A[0].size());
    //	//warping.convert_toCoords();
    //
    //	tmp = (A[0] + B[0]) / 2;
    //	result.push_back(tmp);
    //
    //	for (size_t i = 1; i < warping.pathCoords.size(); i++)
    //	{
    //		if (warping.pathCoords[i].row - warping.pathCoords[i - 1].row == 0 || warping.pathCoords[i].col - warping.pathCoords[i - 1].col == 0)
    //			continue;
    //		else
    //			tmp = (A[warping.pathCoords[i].row] + B[warping.pathCoords[i].col]) / 2;
    //
    //		result.push_back(tmp);
    //	}
    //
    //	return result;
    //}