Example #1
0
			static std::pair<uint32_t,uint32_t> lcs(std::string const & a, std::string const & b)
			{
				/* concatenate a and b into string c */
				std::string c(a.size()+b.size()+2,' ');
				for ( uint64_t i = 0; i < a.size(); ++i )
					c[i] = a[i]+2;
				c[a.size()] = 0;
				for ( uint64_t i = 0; i < b.size(); ++i )
					c[a.size()+1+i] = b[i]+2;
				c[c.size()-1] = 1;
				
				// allocate suffix sorting
				::libmaus::autoarray::AutoArray<int32_t> SA(c.size(),false);
				
				// perform suffix sorting
				typedef ::libmaus::suffixsort::DivSufSort<32,uint8_t *,uint8_t const *,int32_t *,int32_t const *,8> sort_type;
				typedef sort_type::saidx_t saidx_t;
				sort_type::divsufsort(reinterpret_cast<uint8_t const *>(c.c_str()), SA.get(), c.size());

				// compute LCP array
				::libmaus::autoarray::AutoArray<int32_t> LCP = ::libmaus::suffixsort::SkewSuffixSort<uint8_t,int32_t>::lcpByPlcp(
					reinterpret_cast<uint8_t const *>(c.c_str()), c.size(), SA.get());

				// compute psv and nsv arrays for simulating parent operation on suffix tree
				::libmaus::autoarray::AutoArray<int32_t> const prev = ::libmaus::sv::PSV::psv(LCP.get(),LCP.size());
				::libmaus::autoarray::AutoArray<int32_t> const next = ::libmaus::sv::NSV::nsv(LCP.get(),LCP.size());
				
				#if defined(LCS_DEBUG)
				for ( uint64_t i = 0; i < c.size(); ++i )
				{
					std::cerr << i << "\t" << LCP[i] << "\t" << prev[i] << "\t" << next[i] << "\t";
					for ( std::string::const_iterator ita = c.begin()+SA[i]; ita != c.end(); ++ita )
						if ( isalnum(*ita) )
							std::cerr << *ita;
						else
							std::cerr << "<" << static_cast<int>(*ita) << ">" ;
					std::cerr << std::endl;
				}
				
				std::cerr << "---" << std::endl;
				#endif

				int32_t const n = c.size();
				// queue all suffix tree leafs
				std::deque < QNode > Q;
				for ( int32_t i = 0; i < n; ++i )
					Q.push_back ( QNode(i,i,0, (SA[i]< static_cast<int32_t>(a.size()+1)) ? 1:2, 1 ) );

				// construct hash for tree nodes we have seen so far
				typedef ::libmaus::util::unordered_set < QNode , HashQNode >::type hash_type;
				typedef hash_type::iterator hash_iterator_type;
				typedef hash_type::const_iterator hash_const_iterator_type;
				hash_type H(n);
				
				// we simulate a bottom up traversal of the generalised suffix tree for a and b
				while ( Q.size() )
				{
					// get node and compute parent
					QNode const I = Q.front(); Q.pop_front();
					QNode P = parent(I,LCP.get(),prev.get(),next.get(),n);

					// have we seen this node before?
					hash_iterator_type it = H.find(P);

					// no, insert it
					if ( it == H.end() )
					{
						it = H.insert(P).first;
					}
					// yes, update symbol mask and extend visited interval
					else
					{
						it->symmask |= I.symmask;
						it->fill += (I.right-I.left+1);
					}
					
					// if this is not the root and the node is full (we have seen all its children), 
					// then put it in the queue
					if ( P.right-P.left + 1 < n && it->isFull() )
						Q.push_back(P);
				}
				
				// maximum lcp value
				int32_t maxlcp = 0;
				uint32_t maxpos = 0;
				
				// consider all finished nodes
				for ( hash_const_iterator_type it = H.begin(); it != H.end(); ++it )
				{
					#if defined(LCS_DEBUG)
					std::cerr << *it << std::endl;
					#endif
					
					// we need to have nodes from both strings a and b under this
					// node (sym mask has bits for 1 and 2 set) and the lcp value must be 
					// larger than what we already have
					if ( it->symmask == 3 && it->depth > maxlcp )
					{
						maxlcp = it->depth;
						maxpos = SA[it->left];
					}
				}
				
				return std::pair<uint32_t,uint32_t>(maxlcp,maxpos);
			}
void QTransferFunction::AddNode(const float& Intensity, const float& Opacity, const QColor& Diffuse, const QColor& Specular, const QColor& Emission, const float& Roughness)
{
	AddNode(QNode(this, Intensity, Opacity, Diffuse, Specular, Emission, Roughness));
}
Example #3
0
			// compute parent node using prev and next arrays
			static inline QNode parent(QNode const & I, int32_t const * LCP, int32_t const * prev, int32_t const * next, int32_t const n)
			{
				int32_t const k = ( (I.right+1 >= n) || (LCP[I.left] > LCP[I.right+1]) ) ? I.left : (I.right+1);
				return QNode(prev[k],next[k]-1,LCP[k],I.symmask,I.right-I.left+1);
			}