SeparableFilter KernelFilter::AsSeparableFilter( float tolerance ) const { if ( IsEmpty() ) return SeparableFilter(); FSVD svd( coefficients ); // Find the largest singular value int i = svd.IndexOfLargestSingularValue(); // Scaling factor to preserve the original filter weight float k = Sqrt( svd.W[i] ); // Column vector FVector v = svd.U.ColumnVector( i ); v *= k; // Row vector FVector h = svd.V.ColumnVector( i ); h *= k; // Product matrix FMatrix A = FMatrix::FromColumnVector( v ) * FMatrix::FromRowVector( h ); // Verify separability const float* a = A.Begin(); const float* b = coefficients.Begin(); const float* c = coefficients.End(); for ( ; b < c; ++a, ++b ) if ( Abs( *a - *b ) > tolerance ) return SeparableFilter(); return SeparableFilter( h, v, filterName ); }