www.pudn.com > Image_segment.rar > LevelSetMethods.cpp


//Copyright (c) 2004-2005, Baris Sumengen 
//All rights reserved. 
// 
// CIMPL Matrix Performance Library 
// 
//Redistribution and use in source and binary 
//forms, with or without modification, are 
//permitted provided that the following 
//conditions are met: 
// 
//    * No commercial use is allowed.  
//    This software can only be used 
//    for non-commercial purposes. This  
//    distribution is mainly intended for 
//    academic research and teaching. 
//    * Redistributions of source code must 
//    retain the above copyright notice, this 
//    list of conditions and the following 
//    disclaimer. 
//    * Redistributions of binary form must 
//    mention the above copyright notice, this 
//    list of conditions and the following 
//    disclaimer in a clearly visible part  
//    in associated product manual,  
//    readme, and web site of the redistributed  
//    software. 
//    * Redistributions in binary form must 
//    reproduce the above copyright notice, 
//    this list of conditions and the 
//    following disclaimer in the 
//    documentation and/or other materials 
//    provided with the distribution. 
//    * The name of Baris Sumengen may not be 
//    used to endorse or promote products 
//    derived from this software without 
//    specific prior written permission. 
// 
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 
//HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
//EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
//NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
//MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
//PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
//CONTRIBUTORS BE LIABLE FOR ANY 
//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
//OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
//HOWEVER CAUSED AND ON ANY THEORY OF 
//LIABILITY, WHETHER IN CONTRACT, STRICT 
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
//OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
//POSSIBILITY OF SUCH DAMAGE. 
 
 
 
#include "./LevelSetMethods.h" 
 
 
namespace LevelSetMethods 
{ 
 
 
	Matrix ExtractCurve(Matrix phi) 
	{ 
		Matrix curve(phi.Rows(), phi.Columns(), 0); 
 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int i=4;i<=endR-4;i++) 
		{ 
			for(int j=4;j<=endC-4;j++) 
			{ 
				if(phi.ElemNC(i+1,j)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i+1,j) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i-1,j)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i-1,j) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i,j+1)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i,j+1) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i,j-1)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i,j-1) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
			} 
		} 
 
		return curve; 
	} 
 
 
	Matrix ExtractCurve(Matrix phi) 
	{ 
		Matrix curve(phi.Rows(), phi.Columns(), 0); 
 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int i=4;i<=endR-4;i++) 
		{ 
			for(int j=4;j<=endC-4;j++) 
			{ 
				if(phi.ElemNC(i+1,j)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i+1,j) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i-1,j)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i-1,j) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i,j+1)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i,j+1) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
				if(phi.ElemNC(i,j-1)*phi.ElemNC(i,j) <= 0) 
				{ 
					curve.ElemNC(i,j-1) = 1; 
					curve.ElemNC(i,j) = 1; 
				} 
			} 
		} 
 
		return curve; 
	} 
 
 
 
 
	Matrix& ExtendConst2D(Matrix& phi, int size) 
	{ 
		if(size < 1 || size >3) 
		{ 
			cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl; 
			Utility::RunTimeError("Extension size should be between 1 and 3!"); 
		} 
 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		// Extrapolate first layer 
		for(int i=3;i<=endR-3;i++) 
		{ 
			phi.ElemNC(i,2) = phi.ElemNC(i,3); 
			phi.ElemNC(i,endC-2) = phi.ElemNC(i,endC-3); 
		} 
		for(int j=3;j<=endC-3;j++) 
		{ 
			phi.ElemNC(2,j) = phi.ElemNC(3,j); 
			phi.ElemNC(endR-2,j) = phi.ElemNC(endR-3,j); 
		} 
		// May be useful for kappa  
		phi.ElemNC(2,2) = phi.ElemNC(3,3); 
		phi.ElemNC(2,endC-2) = phi.ElemNC(3,endC-3); 
		phi.ElemNC(endR-2,2) = phi.ElemNC(endR-3,3); 
		phi.ElemNC(endR-2,endC-2) = phi.ElemNC(endR-3,endC-3); 
 
		// Extend second layer 
		if(size>=2) 
		{ 
			for(int i=2;i<=endR-2;i++) 
			{ 
				phi.ElemNC(i,1) = phi.ElemNC(i,2); 
				phi.ElemNC(i,endC-1) = phi.ElemNC(i,endC-2); 
			} 
			for(int j=2;j<=endC-2;j++) 
			{ 
				phi.ElemNC(1,j) = phi.ElemNC(2,j); 
				phi.ElemNC(endR-1,j) = phi.ElemNC(endR-2,j); 
			} 
		} 
 
 
		// Extend third layer 
		if(size>=3) 
		{ 
			for(int i=1;i<=endR-1;i++) 
			{ 
				phi.ElemNC(i,0) = phi.ElemNC(i,1); 
				phi.ElemNC(i,endC-0) = phi.ElemNC(i,endC-1); 
			} 
			for(int j=1;j<=endC-1;j++) 
			{ 
				phi.ElemNC(0,j) = phi.ElemNC(1,j); 
				phi.ElemNC(endR-0,j) = phi.ElemNC(endR-1,j); 
			} 
		} 
 
 
		return phi; 
	} 
 
	Matrix& Extend2D(Matrix& phi, int size) 
	{ 
		if(size < 1 || size >3) 
		{ 
			cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl; 
			Utility::RunTimeError("Extension size should be between 1 and 3!"); 
		} 
 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		// Extrapolate first layer 
		for(int i=3;i<=endR-3;i++) 
		{ 
			phi.ElemNC(i,2) = 2*phi.ElemNC(i,3) - phi.ElemNC(i,4); 
			phi.ElemNC(i,endC-2) = 2*phi.ElemNC(i,endC-3) - phi.ElemNC(i,endC-4); 
		} 
		for(int j=3;j<=endC-3;j++) 
		{ 
			phi.ElemNC(2,j) = 2*phi.ElemNC(3,j) - phi.ElemNC(4,j); 
			phi.ElemNC(endR-2,j) = 2*phi.ElemNC(endR-3,j) - phi.ElemNC(endR-4,j); 
		} 
		// May be useful for kappa  
		phi.ElemNC(2,2) = 2*phi.ElemNC(3,3) - phi.ElemNC(4,4); 
		phi.ElemNC(2,endC-2) = 2*phi.ElemNC(3,endC-3) - phi.ElemNC(4,endC-4); 
		phi.ElemNC(endR-2,2) = 2*phi.ElemNC(endR-3,3) - phi.ElemNC(endR-4,4); 
		phi.ElemNC(endR-2,endC-2) = 2*phi.ElemNC(endR-3,endC-3) - phi.ElemNC(endR-4,endC-4); 
 
 
		// Extrapolate second layer 
		if(size>=2) 
		{ 
			for(int i=2;i<=endR-2;i++) 
			{ 
				phi.ElemNC(i,1) = 2*phi.ElemNC(i,2) - phi.ElemNC(i,3); 
				phi.ElemNC(i,endC-1) = 2*phi.ElemNC(i,endC-2) - phi.ElemNC(i,endC-3); 
			} 
			for(int j=2;j<=endC-2;j++) 
			{ 
				phi.ElemNC(1,j) = 2*phi.ElemNC(2,j) - phi.ElemNC(3,j); 
				phi.ElemNC(endR-1,j) = 2*phi.ElemNC(endR-2,j) - phi.ElemNC(endR-3,j); 
			} 
		} 
 
 
		// Extrapolate third layer 
		if(size>=3) 
		{ 
			for(int i=1;i<=endR-1;i++) 
			{ 
				phi.ElemNC(i,0) = 2*phi.ElemNC(i,1) - phi.ElemNC(i,2); 
				phi.ElemNC(i,endC-0) = 2*phi.ElemNC(i,endC-1) - phi.ElemNC(i,endC-2); 
			} 
			for(int j=1;j<=endC-1;j++) 
			{ 
				phi.ElemNC(0,j) = 2*phi.ElemNC(1,j) - phi.ElemNC(2,j); 
				phi.ElemNC(endR-0,j) = 2*phi.ElemNC(endR-1,j) - phi.ElemNC(endR-2,j); 
			} 
		} 
 
		return phi; 
	} 
 
 
	Matrix& Extend2D(Matrix& phi, int size) 
	{ 
		if(size < 1 || size >3) 
		{ 
			cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl; 
			Utility::RunTimeError("Extension size should be between 1 and 3!"); 
		} 
 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		// Extrapolate first layer 
		for(int i=3;i<=endR-3;i++) 
		{ 
			phi.ElemNC(i,2) = 2*phi.ElemNC(i,3) - phi.ElemNC(i,4); 
			phi.ElemNC(i,endC-2) = 2*phi.ElemNC(i,endC-3) - phi.ElemNC(i,endC-4); 
		} 
		for(int j=3;j<=endC-3;j++) 
		{ 
			phi.ElemNC(2,j) = 2*phi.ElemNC(3,j) - phi.ElemNC(4,j); 
			phi.ElemNC(endR-2,j) = 2*phi.ElemNC(endR-3,j) - phi.ElemNC(endR-4,j); 
		} 
		// May be useful for kappa  
		phi.ElemNC(2,2) = 2*phi.ElemNC(3,3) - phi.ElemNC(4,4); 
		phi.ElemNC(2,endC-2) = 2*phi.ElemNC(3,endC-3) - phi.ElemNC(4,endC-4); 
		phi.ElemNC(endR-2,2) = 2*phi.ElemNC(endR-3,3) - phi.ElemNC(endR-4,4); 
		phi.ElemNC(endR-2,endC-2) = 2*phi.ElemNC(endR-3,endC-3) - phi.ElemNC(endR-4,endC-4); 
 
 
		// Extrapolate second layer 
		if(size>=2) 
		{ 
			for(int i=2;i<=endR-2;i++) 
			{ 
				phi.ElemNC(i,1) = 2*phi.ElemNC(i,2) - phi.ElemNC(i,3); 
				phi.ElemNC(i,endC-1) = 2*phi.ElemNC(i,endC-2) - phi.ElemNC(i,endC-3); 
			} 
			for(int j=2;j<=endC-2;j++) 
			{ 
				phi.ElemNC(1,j) = 2*phi.ElemNC(2,j) - phi.ElemNC(3,j); 
				phi.ElemNC(endR-1,j) = 2*phi.ElemNC(endR-2,j) - phi.ElemNC(endR-3,j); 
			} 
		} 
 
 
		// Extrapolate third layer 
		if(size>=3) 
		{ 
			for(int i=1;i<=endR-1;i++) 
			{ 
				phi.ElemNC(i,0) = 2*phi.ElemNC(i,1) - phi.ElemNC(i,2); 
				phi.ElemNC(i,endC-0) = 2*phi.ElemNC(i,endC-1) - phi.ElemNC(i,endC-2); 
			} 
			for(int j=1;j<=endC-1;j++) 
			{ 
				phi.ElemNC(0,j) = 2*phi.ElemNC(1,j) - phi.ElemNC(2,j); 
				phi.ElemNC(endR-0,j) = 2*phi.ElemNC(endR-1,j) - phi.ElemNC(endR-2,j); 
			} 
		} 
 
		return phi; 
	} 
 
 
 
 
 
 
 
 
 
 
	void Evolve2DNormalENO1(Matrix& phi, float dx, float dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				float phi_x_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				float phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				float phi_y_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				float phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalENO2(Matrix& phi, float dx, float dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				float phi_x_p = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				float phi_y_p = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalENO3(Matrix& phi, float dx, float dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x_p = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				float phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y_p = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				float phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalWENO(Matrix& phi, float dx, float dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x_p = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				float phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y_p = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				float phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
 
 
 
 
 
	void Evolve2DNormalENO1(Matrix& phi, double dx, double dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				double phi_x_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				double phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				double phi_y_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				double phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalENO2(Matrix& phi, double dx, double dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				double phi_x_p = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				double phi_y_p = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalENO3(Matrix& phi, double dx, double dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x_p = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				double phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y_p = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				double phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalWENO(Matrix& phi, double dx, double dy, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x_p = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				double phi_x = SelectDerNormal(phi_x_m, phi_x_p, Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y_p = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				double phi_y = SelectDerNormal(phi_y_m, phi_y_p, Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	void Evolve2DVectorENO1(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
	void Evolve2DVectorENO2(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
	void Evolve2DVectorENO3(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
	void Evolve2DVectorWENO(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
 
 
 
 
	void Evolve2DVectorENO1(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
	void Evolve2DVectorENO2(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
	void Evolve2DVectorENO3(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
	void Evolve2DVectorWENO(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x, phi_y; 
				if(u.ElemNC(i,j)>0) 
				{ 
					phi_x = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				} 
				else if(u.ElemNC(i,j)<0) 
				{ 
					phi_x = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				} 
				else 
				{ 
					phi_x = 0; 
				} 
 
 
				if(v.ElemNC(i,j)>0) 
				{ 
					phi_y = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				} 
				else if(v.ElemNC(i,j)<0) 
				{ 
					phi_y = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				} 
				else 
				{ 
					phi_y = 0; 
				} 
 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y; 
			} 
		} 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	void Evolve2DNormalVectorENO1SignedDistance(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				float phi_x_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				float phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				float phi_y_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				float phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalVectorENO2SignedDistance(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				float phi_x_p = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				float phi_y_p = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
	void Evolve2DNormalVectorENO3SignedDistance(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x_p = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				float phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y_p = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				float phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
	void Evolve2DNormalVectorWENOSignedDistance(Matrix& phi, float dx, float dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float phi_x_m = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				float phi_x_p = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				float phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float phi_y_m = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				float phi_y_p = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				float phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				float absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (float)fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (float)fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
 
 
 
	void Evolve2DNormalVectorENO1SignedDistance(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO1Minus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), dx); 
				double phi_x_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				double phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO1Minus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), dy); 
				double phi_y_p = DerENO1Plus(phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				double phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
	void Evolve2DNormalVectorENO2SignedDistance(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO2Minus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), dx); 
				double phi_x_p = DerENO2Plus(phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO2Minus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), dy); 
				double phi_y_p = DerENO2Plus(phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
	void Evolve2DNormalVectorENO3SignedDistance(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerENO3Minus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x_p = DerENO3Plus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				double phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerENO3Minus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y_p = DerENO3Plus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				double phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
	void Evolve2DNormalVectorWENOSignedDistance(Matrix& phi, double dx, double dy, Matrix& u, Matrix& v, Matrix& Vn, Matrix& delta, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double phi_x_m = DerWENOMinus(phi.ElemNC(i,j-3), phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), dx); 
				double phi_x_p = DerWENOPlus(phi.ElemNC(i,j-2), phi.ElemNC(i,j-1), phi.ElemNC(i,j), phi.ElemNC(i,j+1), phi.ElemNC(i,j+2), phi.ElemNC(i,j+3), dx); 
				double phi_x = SelectDerNormalVectorSD(phi_x_m, phi_x_p, u.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double phi_y_m = DerWENOMinus(phi.ElemNC(i-3,j), phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), dy); 
				double phi_y_p = DerWENOPlus(phi.ElemNC(i-2,j), phi.ElemNC(i-1,j), phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+2,j), phi.ElemNC(i+3,j), dy); 
				double phi_y = SelectDerNormalVectorSD(phi_y_m, phi_y_p, v.ElemNC(i,j), Vn.ElemNC(i,j)); 
 
				double absGradPhi = sqrt(phi_x*phi_x+phi_y*phi_y); 
				H1Abs.ElemNC(i,j) = (double)fabs( u.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_x*phi_x/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				H2Abs.ElemNC(i,j) = (double)fabs( v.ElemNC(i,j) + Vn.ElemNC(i,j)*phi_y*phi_y/(absGradPhi+(absGradPhi>1e-19?0:1)) ); 
				delta.ElemNC(i,j) = u.ElemNC(i,j)*phi_x + v.ElemNC(i,j)*phi_y + Vn.ElemNC(i,j)*absGradPhi; 
			} 
		} 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	float Getdt2DNormal(float alpha, float dx, float dy, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = H1Abs.Rows()-1; 
		int endC = H1Abs.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
	float Getdt2DNormalVector(float alpha, float dx, float dy, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = H1Abs.Rows()-1; 
		int endC = H1Abs.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
 
	float Getdt2DVector(float alpha, float dx, float dy, Matrix& u, Matrix& v) 
	{ 
		int endR = u.Rows()-1; 
		int endC = u.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = fabs(u.ElemNC(i,j))/dx + fabs(v.ElemNC(i,j))/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
 
 
	float Getdt2DKappa(float alpha, float dx2, float dy2, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = (2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
	float Getdt2DVectorKappa(float alpha, float dx, float dy, float dx2, float dy2, Matrix& u, Matrix& v, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = fabs(u.ElemNC(i,j))/dx + fabs(v.ElemNC(i,j))/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
	float Getdt2DNormalKappa(float alpha, float dx, float dy, float dx2, float dy2, Matrix& H1Abs, Matrix& H2Abs, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
	float Getdt2DNormalVectorKappa(float alpha, float dx, float dy, float dx2, float dy2, Matrix& H1Abs, Matrix& H2Abs, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		float maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return (float)(alpha/(maxs+(maxs>1e-19?0:1))); 
	} 
 
 
 
 
 
 
 
 
	double Getdt2DNormal(double alpha, double dx, double dy, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = H1Abs.Rows()-1; 
		int endC = H1Abs.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
	double Getdt2DNormalVector(double alpha, double dx, double dy, Matrix& H1Abs, Matrix& H2Abs) 
	{ 
		int endR = H1Abs.Rows()-1; 
		int endC = H1Abs.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
 
	double Getdt2DVector(double alpha, double dx, double dy, Matrix& u, Matrix& v) 
	{ 
		int endR = u.Rows()-1; 
		int endC = u.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = fabs(u.ElemNC(i,j))/dx + fabs(v.ElemNC(i,j))/dy; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
 
 
	double Getdt2DKappa(double alpha, double dx2, double dy2, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = (2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
	double Getdt2DVectorKappa(double alpha, double dx, double dy, double dx2, double dy2, Matrix& u, Matrix& v, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = fabs(u.ElemNC(i,j))/dx + fabs(v.ElemNC(i,j))/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
	double Getdt2DNormalKappa(double alpha, double dx, double dy, double dx2, double dy2, Matrix& H1Abs, Matrix& H2Abs, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
	double Getdt2DNormalVectorKappa(double alpha, double dx, double dy, double dx2, double dy2, Matrix& H1Abs, Matrix& H2Abs, Matrix& b) 
	{ 
		int endR = b.Rows()-1; 
		int endC = b.Columns()-1; 
		double maxs = 0.0; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double temp = H1Abs.ElemNC(i,j)/dx + H2Abs.ElemNC(i,j)/dy +  
					(2*b.ElemNC(i,j))/dx2 + (2*b.ElemNC(i,j))/dy2; 
				maxs = maxs>=temp?maxs:temp; 
			} 
		} 
		return alpha/(maxs+(maxs>1e-19?0:1)); 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
	void Evolve2DKappa(Matrix& phi, float dx, float dy, float dx2, float dy2, Matrix& b, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				float kappaAbsPhi = KappaAbsPhi2D(phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+1,j+1),  
					phi.ElemNC(i,j+1), phi.ElemNC(i-1,j+1), phi.ElemNC(i-1,j), phi.ElemNC(i-1,j-1),  
					phi.ElemNC(i,j-1), phi.ElemNC(i+1,j-1), dx, dy, dx2, dy2); 
				delta.ElemNC(i,j) = b.ElemNC(i,j)*kappaAbsPhi; 
			} 
		} 
	} 
 
 
 
 
	inline float KappaAbsPhi2D(float phi_i_j, float phi_ip1_j, float phi_ip1_jp1,  
		float phi_i_jp1, float phi_im1_jp1, float phi_im1_j, float phi_im1_jm1,  
		float phi_i_jm1, float phi_ip1_jm1, float dx, float dy, float dx2, float dy2) 
	{ 
		float phi_x = (phi_i_jp1 - phi_i_jm1)/(2*dx); 
		float phi_y = (phi_ip1_j - phi_im1_j)/(2*dy); 
		float phi_xx = (phi_i_jp1 - 2*phi_i_j + phi_i_jm1)/dx2; 
		float phi_yy = (phi_ip1_j - 2*phi_i_j + phi_im1_j)/dy2; 
		float phi_xy = (phi_ip1_jp1 + phi_im1_jm1 - phi_ip1_jm1 - phi_im1_jp1)/(4*dx*dy); 
		float absGradPhiSq = (phi_x*phi_x + phi_y*phi_y); 
		float kappaAbsPhi = (phi_xx*phi_y*phi_y - 2*phi_y*phi_x*phi_xy  
			+ phi_yy*phi_x*phi_x)/(absGradPhiSq + (float)(absGradPhiSq>1e-19?0:1)); 
		return kappaAbsPhi; 
 
	} 
 
 
 
 
	void Evolve2DKappa(Matrix& phi, double dx, double dy, double dx2, double dy2, Matrix& b, Matrix& delta) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				double kappaAbsPhi = KappaAbsPhi2D(phi.ElemNC(i,j), phi.ElemNC(i+1,j), phi.ElemNC(i+1,j+1),  
					phi.ElemNC(i,j+1), phi.ElemNC(i-1,j+1), phi.ElemNC(i-1,j), phi.ElemNC(i-1,j-1),  
					phi.ElemNC(i,j-1), phi.ElemNC(i+1,j-1), dx, dy, dx2, dy2); 
				delta.ElemNC(i,j) = b.ElemNC(i,j)*kappaAbsPhi; 
			} 
		} 
	} 
 
 
 
 
	inline double KappaAbsPhi2D(double phi_i_j, double phi_ip1_j, double phi_ip1_jp1,  
		double phi_i_jp1, double phi_im1_jp1, double phi_im1_j, double phi_im1_jm1,  
		double phi_i_jm1, double phi_ip1_jm1, double dx, double dy, double dx2, double dy2) 
	{ 
		double phi_x = (phi_i_jp1 - phi_i_jm1)/(2*dx); 
		double phi_y = (phi_ip1_j - phi_im1_j)/(2*dy); 
		double phi_xx = (phi_i_jp1 - 2*phi_i_j + phi_i_jm1)/dx2; 
		double phi_yy = (phi_ip1_j - 2*phi_i_j + phi_im1_j)/dy2; 
		double phi_xy = (phi_ip1_jp1 + phi_im1_jm1 - phi_ip1_jm1 - phi_im1_jp1)/(4*dx*dy); 
		double absGradPhiSq = (phi_x*phi_x + phi_y*phi_y); 
		double kappaAbsPhi = (phi_xx*phi_y*phi_y - 2*phi_y*phi_x*phi_xy  
			+ phi_yy*phi_x*phi_x)/(absGradPhiSq + (double)(absGradPhiSq>1e-19?0:1)); 
		return kappaAbsPhi; 
 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	void ReinitSignedDistanceENO1(Matrix& phi, float dx, float dy, float alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, float dx, float dy, float alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, float dx, float dy, float alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, float dx, float dy, float alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, double dx, double dy, double alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, double dx, double dy, double alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, double dx, double dy, double alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, double dx, double dy, double alpha, int iterations) 
	{ 
		Matrix S_phi_0 = phi*InvSqrtI(phi*phi + dx*dx); 
		Matrix delta(phi.Rows(), phi.Columns()); 
		Matrix H1Abs(phi.Rows(), phi.Columns()); 
		Matrix H2Abs(phi.Rows(), phi.Columns()); 
		for(int k=0;k& phi, Matrix& delta, float dt) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				phi.ElemNC(i,j) -= dt*delta.ElemNC(i,j); 
			} 
		} 
	} 
	void AddPhi2D(Matrix& phi, Matrix& delta, float dt) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				phi.ElemNC(i,j) += dt*delta.ElemNC(i,j); 
			} 
		} 
	} 
 
 
	void SubtractPhi2D(Matrix& phi, Matrix& delta, double dt) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				phi.ElemNC(i,j) -= dt*delta.ElemNC(i,j); 
			} 
		} 
	} 
	void AddPhi2D(Matrix& phi, Matrix& delta, double dt) 
	{ 
		int endR = phi.Rows()-1; 
		int endC = phi.Columns()-1; 
		for(int j=3;j<=endC-3;j++) 
		{ 
			for(int i=3;i<=endR-3;i++) 
			{ 
				phi.ElemNC(i,j) += dt*delta.ElemNC(i,j); 
			} 
		} 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	inline float SelectDerNormal(float phi_x_m, float phi_x_p, float Vn) 
	{ 
		float phi_x; 
		float VnPhi_m = Vn*phi_x_m; 
		float VnPhi_p = Vn*phi_x_p; 
		if(VnPhi_m <= 0 && VnPhi_p <= 0) 
		{ 
			phi_x = phi_x_p; 
		} 
		else if(VnPhi_m >= 0 && VnPhi_p >= 0) 
		{ 
			phi_x = phi_x_m; 
		} 
		else if(VnPhi_m <= 0 && VnPhi_p >= 0) 
		{ 
			phi_x = 0; 
		} 
		else if(VnPhi_m >= 0 && VnPhi_p <= 0) 
		{ 
			if(fabs(VnPhi_p) >= fabs(VnPhi_m)) 
			{ 
				phi_x = phi_x_p; 
			} 
			else 
			{ 
				phi_x = phi_x_m; 
			} 
		} 
		return phi_x; 
	} 
 
 
	inline float SelectDerNormalVectorSD(float phi_x_m, float phi_x_p, float u, float Vn) 
	{ 
		float phi_x; 
 
		float H1_m = u + Vn*phi_x_m; 
		float H1_p = u + Vn*phi_x_p; 
 
		if(H1_m <= 0 && H1_p <= 0) 
		{ 
			phi_x = phi_x_p; 
		} 
		else if(H1_m >= 0 && H1_p >= 0) 
		{ 
			phi_x = phi_x_m; 
		} 
		else if(H1_m <= 0 && H1_p >= 0) 
		{ 
			phi_x = -u/Vn; 
		} 
		else if(H1_m >= 0 && H1_p <= 0) 
		{ 
			if(fabs(H1_p) >= fabs(H1_m)) 
			{ 
				phi_x = phi_x_p; 
			} 
			else 
			{ 
				phi_x = phi_x_m; 
			} 
		} 
		return phi_x; 
	} 
 
	inline double SelectDerNormal(double phi_x_m, double phi_x_p, double Vn) 
	{ 
		double phi_x; 
		double VnPhi_m = Vn*phi_x_m; 
		double VnPhi_p = Vn*phi_x_p; 
		if(VnPhi_m <= 0 && VnPhi_p <= 0) 
		{ 
			phi_x = phi_x_p; 
		} 
		else if(VnPhi_m >= 0 && VnPhi_p >= 0) 
		{ 
			phi_x = phi_x_m; 
		} 
		else if(VnPhi_m <= 0 && VnPhi_p >= 0) 
		{ 
			phi_x = 0; 
		} 
		else if(VnPhi_m >= 0 && VnPhi_p <= 0) 
		{ 
			if(fabs(VnPhi_p) >= fabs(VnPhi_m)) 
			{ 
				phi_x = phi_x_p; 
			} 
			else 
			{ 
				phi_x = phi_x_m; 
			} 
		} 
		return phi_x; 
	} 
 
 
	inline double SelectDerNormalVectorSD(double phi_x_m, double phi_x_p, double u, double Vn) 
	{ 
		double phi_x; 
 
		double H1_m = u + Vn*phi_x_m; 
		double H1_p = u + Vn*phi_x_p; 
 
		if(H1_m <= 0 && H1_p <= 0) 
		{ 
			phi_x = phi_x_p; 
		} 
		else if(H1_m >= 0 && H1_p >= 0) 
		{ 
			phi_x = phi_x_m; 
		} 
		else if(H1_m <= 0 && H1_p >= 0) 
		{ 
			phi_x = -u/Vn; 
		} 
		else if(H1_m >= 0 && H1_p <= 0) 
		{ 
			if(fabs(H1_p) >= fabs(H1_m)) 
			{ 
				phi_x = phi_x_p; 
			} 
			else 
			{ 
				phi_x = phi_x_m; 
			} 
		} 
		return phi_x; 
	} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
	// for (+) derivative v1 = phi_i, for (-) derivative v2 = phi_i 
	inline float DerENO1Minus(float v1, float v2, float dx) 
	{ 
		return (v2-v1)/dx; 
	} 
	inline float DerENO1Plus(float v1, float v2, float dx) 
	{ 
		return (v2-v1)/dx; 
	} 
 
	// v3 = phi_i 
	inline float DerENO2Minus(float v1, float v2, float v3, float v4, float dx) 
	{ 
		float D1_1 = (v2-v1); 
		float D1_2 = (v3-v2); 
		float D1_3 = (v4-v3); 
 
		float D2_1 = 0.5f*(D1_2-D1_1); 
		float D2_2 = 0.5f*(D1_3-D1_2); 
 
		float absD2_1 = fabs(D2_1); 
		float absD2_2 = fabs(D2_2); 
		float Q2p; 
		if(absD2_1 <= absD2_2) 
		{ 
			Q2p = D2_1; 
		} 
		else 
		{ 
			Q2p = D2_2; 
		} 
 
		return (D1_2 + Q2p)/dx; 
	} 
 
	// v2 = phi_i 
	inline float DerENO2Plus(float v1, float v2, float v3, float v4, float dx) 
	{ 
		float D1_1 = (v2-v1); 
		float D1_2 = (v3-v2); 
		float D1_3 = (v4-v3); 
 
		float D2_1 = 0.5f*(D1_2-D1_1); 
		float D2_2 = 0.5f*(D1_3-D1_2); 
 
		float absD2_1 = fabs(D2_1); 
		float absD2_2 = fabs(D2_2); 
		float Q2p; 
		if(absD2_1 <= absD2_2) 
		{ 
			Q2p = -D2_1; 
		} 
		else 
		{ 
			Q2p = -D2_2; 
		} 
 
		return (D1_2 + Q2p)/dx; 
	} 
 
	// v4 = phi_i 
	inline float DerENO3Minus(float v1, float v2, float v3, float v4, float v5, float v6, float dx) 
	{ 
		float D1_1 = (v2-v1); 
		float D1_2 = (v3-v2); 
		float D1_3 = (v4-v3); 
		float D1_4 = (v5-v4); 
		float D1_5 = (v6-v5); 
 
		float D2_1 = 0.5f*(D1_2-D1_1); 
		float D2_2 = 0.5f*(D1_3-D1_2); 
		float D2_3 = 0.5f*(D1_4-D1_3); 
		float D2_4 = 0.5f*(D1_5-D1_4); 
 
		float D3_1 = (D2_2-D2_1)/3; 
		float D3_2 = (D2_3-D2_2)/3; 
		float D3_3 = (D2_4-D2_3)/3; 
 
		float absD2_2 = fabs(D2_2); 
		float absD2_3 = fabs(D2_3); 
		float Q2p; 
		float Q3p; 
		if(absD2_2 <= absD2_3) 
		{ 
			Q2p = D2_2; 
			float cstar; 
			float absD3_1 = fabs(D3_1); 
			float absD3_2 = fabs(D3_2); 
			if(absD3_1 <= absD3_2) 
			{ 
				cstar = D3_1; 
			} 
			else 
			{ 
				cstar = D3_2; 
			} 
			Q3p = cstar*2; 
		} 
		else 
		{ 
			Q2p = D2_3; 
			float cstar; 
			float absD3_2 = fabs(D3_2); 
			float absD3_3 = fabs(D3_3); 
			if(absD3_2 <= absD3_3) 
			{ 
				cstar = D3_2; 
			} 
			else 
			{ 
				cstar = D3_3; 
			} 
			Q3p = -cstar; 
		} 
 
		return (D1_3 + Q2p + Q3p)/dx; 
	} 
 
	// v3 = phi_i 
	inline float DerENO3Plus(float v1, float v2, float v3, float v4, float v5, float v6, float dx) 
	{ 
		float D1_1 = (v2-v1); 
		float D1_2 = (v3-v2); 
		float D1_3 = (v4-v3); 
		float D1_4 = (v5-v4); 
		float D1_5 = (v6-v5); 
 
		float D2_1 = 0.5f*(D1_2-D1_1); 
		float D2_2 = 0.5f*(D1_3-D1_2); 
		float D2_3 = 0.5f*(D1_4-D1_3); 
		float D2_4 = 0.5f*(D1_5-D1_4); 
 
		float D3_1 = (D2_2-D2_1)/3; 
		float D3_2 = (D2_3-D2_2)/3; 
		float D3_3 = (D2_4-D2_3)/3; 
 
		float absD2_2 = fabs(D2_2); 
		float absD2_3 = fabs(D2_3); 
		float Q2p; 
		float Q3p; 
		if(absD2_2 <= absD2_3) 
		{ 
			Q2p = -D2_2; 
			float cstar; 
			float absD3_1 = fabs(D3_1); 
			float absD3_2 = fabs(D3_2); 
			if(absD3_1 <= absD3_2) 
			{ 
				cstar = D3_1; 
			} 
			else 
			{ 
				cstar = D3_2; 
			} 
			Q3p = -cstar; 
		} 
		else 
		{ 
			Q2p = -D2_3; 
			float cstar; 
			float absD3_2 = fabs(D3_2); 
			float absD3_3 = fabs(D3_3); 
			if(absD3_2 <= absD3_3) 
			{ 
				cstar = D3_2; 
			} 
			else 
			{ 
				cstar = D3_3; 
			} 
			Q3p = cstar*2; 
		} 
 
		return (D1_3 + Q2p + Q3p)/dx; 
	} 
 
 
	// vv4 = phi_i 
	inline float DerWENOMinus(float vv1, float vv2, float vv3, float vv4, float vv5, float vv6, float dx) 
	{ 
		float v1 = (vv2-vv1)/dx; 
		float v2 = (vv3-vv2)/dx; 
		float v3 = (vv4-vv3)/dx; 
		float v4 = (vv5-vv4)/dx; 
		float v5 = (vv6-vv5)/dx; 
 
		float data_x_1 = (2*v1 - 7*v2 + 11*v3)/6; 
		float data_x_2 = (-v2 + 5*v3 + 2*v4)/6; 
		float data_x_3 = (2*v3 + 5*v4 - v5)/6; 
 
		float dummy1 = v1-2*v2+v3; 
		float dummy2 = v1-4*v2+3*v3; 
		float dummy3 = v2-2*v3+v4; 
		float dummy4 = v2-v4; 
		float dummy5 = v3-2*v4+v5; 
		float dummy6 = 3*v3-4*v4+v5; 
		float dummy_c = 13/12; 
		double S1 = dummy_c*dummy1*dummy1 + 0.25*dummy2*dummy2; 
		double S2 = dummy_c*dummy3*dummy3 + 0.25*dummy4*dummy4; 
		double S3 = dummy_c*dummy5*dummy5 + 0.25*dummy6*dummy6; 
 
		float m = v1*v1; 
		float temp = v2*v2; 
		m = m>=temp?m:temp; 
		temp = v3*v3; 
		m = m>=temp?m:temp; 
		temp = v4*v4; 
		m = m>=temp?m:temp; 
		temp = v5*v5; 
		m = m>=temp?m:temp; 
		double epsil = m*1e-6 + 1e-199; 
 
		double alpha1 = 0.1/((S1+epsil)*(S1+epsil)); 
		double alpha2 = 0.6/((S2+epsil)*(S2+epsil)); 
		double alpha3 = 0.3/((S3+epsil)*(S3+epsil)); 
		return (float)((alpha1*data_x_1 + alpha2*data_x_2 + alpha3*data_x_3)/(alpha1+alpha2+alpha3)); 
	} 
 
	// v3 = phi_i 
	inline float DerWENOPlus(float vv1, float vv2, float vv3, float vv4, float vv5, float vv6, float dx) 
	{ 
 
		float v5 = (vv2-vv1)/dx; 
		float v4 = (vv3-vv2)/dx; 
		float v3 = (vv4-vv3)/dx; 
		float v2 = (vv5-vv4)/dx; 
		float v1 = (vv6-vv5)/dx; 
 
		float data_x_1 = (2*v1 - 7*v2 + 11*v3)/6; 
		float data_x_2 = (-v2 + 5*v3 + 2*v4)/6; 
		float data_x_3 = (2*v3 + 5*v4 - v5)/6; 
 
		float dummy1 = v1-2*v2+v3; 
		float dummy2 = v1-4*v2+3*v3; 
		float dummy3 = v2-2*v3+v4; 
		float dummy4 = v2-v4; 
		float dummy5 = v3-2*v4+v5; 
		float dummy6 = 3*v3-4*v4+v5; 
		float dummy_c = 13/12; 
		double S1 = dummy_c*dummy1*dummy1 + 0.25*dummy2*dummy2; 
		double S2 = dummy_c*dummy3*dummy3 + 0.25*dummy4*dummy4; 
		double S3 = dummy_c*dummy5*dummy5 + 0.25*dummy6*dummy6; 
 
		float m = v1*v1; 
		float temp = v2*v2; 
		m = m>=temp?m:temp; 
		temp = v3*v3; 
		m = m>=temp?m:temp; 
		temp = v4*v4; 
		m = m>=temp?m:temp; 
		temp = v5*v5; 
		m = m>=temp?m:temp; 
		double epsil = m*1e-6 + 1e-199; 
 
		double alpha1 = 0.1/((S1+epsil)*(S1+epsil)); 
		double alpha2 = 0.6/((S2+epsil)*(S2+epsil)); 
		double alpha3 = 0.3/((S3+epsil)*(S3+epsil)); 
		return (float)((alpha1*data_x_1 + alpha2*data_x_2 + alpha3*data_x_3)/(alpha1+alpha2+alpha3)); 
	} 
 
 
 
 
 
 
	// for (+) derivative v1 = phi_i, for (-) derivative v2 = phi_i 
	inline double DerENO1Minus(double v1, double v2, double dx) 
	{ 
		return (v2-v1)/dx; 
	} 
	inline double DerENO1Plus(double v1, double v2, double dx) 
	{ 
		return (v2-v1)/dx; 
	} 
 
	// v3 = phi_i 
	inline double DerENO2Minus(double v1, double v2, double v3, double v4, double dx) 
	{ 
		double D1_1 = (v2-v1); 
		double D1_2 = (v3-v2); 
		double D1_3 = (v4-v3); 
 
		double D2_1 = 0.5f*(D1_2-D1_1); 
		double D2_2 = 0.5f*(D1_3-D1_2); 
 
		double absD2_1 = fabs(D2_1); 
		double absD2_2 = fabs(D2_2); 
		double Q2p; 
		if(absD2_1 <= absD2_2) 
		{ 
			Q2p = D2_1; 
		} 
		else 
		{ 
			Q2p = D2_2; 
		} 
 
		return (D1_2 + Q2p)/dx; 
	} 
 
	// v2 = phi_i 
	inline double DerENO2Plus(double v1, double v2, double v3, double v4, double dx) 
	{ 
		double D1_1 = (v2-v1); 
		double D1_2 = (v3-v2); 
		double D1_3 = (v4-v3); 
 
		double D2_1 = 0.5f*(D1_2-D1_1); 
		double D2_2 = 0.5f*(D1_3-D1_2); 
 
		double absD2_1 = fabs(D2_1); 
		double absD2_2 = fabs(D2_2); 
		double Q2p; 
		if(absD2_1 <= absD2_2) 
		{ 
			Q2p = -D2_1; 
		} 
		else 
		{ 
			Q2p = -D2_2; 
		} 
 
		return (D1_2 + Q2p)/dx; 
	} 
 
	// v4 = phi_i 
	inline double DerENO3Minus(double v1, double v2, double v3, double v4, double v5, double v6, double dx) 
	{ 
		double D1_1 = (v2-v1); 
		double D1_2 = (v3-v2); 
		double D1_3 = (v4-v3); 
		double D1_4 = (v5-v4); 
		double D1_5 = (v6-v5); 
 
		double D2_1 = 0.5f*(D1_2-D1_1); 
		double D2_2 = 0.5f*(D1_3-D1_2); 
		double D2_3 = 0.5f*(D1_4-D1_3); 
		double D2_4 = 0.5f*(D1_5-D1_4); 
 
		double D3_1 = (D2_2-D2_1)/3; 
		double D3_2 = (D2_3-D2_2)/3; 
		double D3_3 = (D2_4-D2_3)/3; 
 
		double absD2_2 = fabs(D2_2); 
		double absD2_3 = fabs(D2_3); 
		double Q2p; 
		double Q3p; 
		if(absD2_2 <= absD2_3) 
		{ 
			Q2p = D2_2; 
			double cstar; 
			double absD3_1 = fabs(D3_1); 
			double absD3_2 = fabs(D3_2); 
			if(absD3_1 <= absD3_2) 
			{ 
				cstar = D3_1; 
			} 
			else 
			{ 
				cstar = D3_2; 
			} 
			Q3p = cstar*2; 
		} 
		else 
		{ 
			Q2p = D2_3; 
			double cstar; 
			double absD3_2 = fabs(D3_2); 
			double absD3_3 = fabs(D3_3); 
			if(absD3_2 <= absD3_3) 
			{ 
				cstar = D3_2; 
			} 
			else 
			{ 
				cstar = D3_3; 
			} 
			Q3p = -cstar; 
		} 
 
		return (D1_3 + Q2p + Q3p)/dx; 
	} 
 
	// v3 = phi_i 
	inline double DerENO3Plus(double v1, double v2, double v3, double v4, double v5, double v6, double dx) 
	{ 
		double D1_1 = (v2-v1); 
		double D1_2 = (v3-v2); 
		double D1_3 = (v4-v3); 
		double D1_4 = (v5-v4); 
		double D1_5 = (v6-v5); 
 
		double D2_1 = 0.5f*(D1_2-D1_1); 
		double D2_2 = 0.5f*(D1_3-D1_2); 
		double D2_3 = 0.5f*(D1_4-D1_3); 
		double D2_4 = 0.5f*(D1_5-D1_4); 
 
		double D3_1 = (D2_2-D2_1)/3; 
		double D3_2 = (D2_3-D2_2)/3; 
		double D3_3 = (D2_4-D2_3)/3; 
 
		double absD2_2 = fabs(D2_2); 
		double absD2_3 = fabs(D2_3); 
		double Q2p; 
		double Q3p; 
		if(absD2_2 <= absD2_3) 
		{ 
			Q2p = -D2_2; 
			double cstar; 
			double absD3_1 = fabs(D3_1); 
			double absD3_2 = fabs(D3_2); 
			if(absD3_1 <= absD3_2) 
			{ 
				cstar = D3_1; 
			} 
			else 
			{ 
				cstar = D3_2; 
			} 
			Q3p = -cstar; 
		} 
		else 
		{ 
			Q2p = -D2_3; 
			double cstar; 
			double absD3_2 = fabs(D3_2); 
			double absD3_3 = fabs(D3_3); 
			if(absD3_2 <= absD3_3) 
			{ 
				cstar = D3_2; 
			} 
			else 
			{ 
				cstar = D3_3; 
			} 
			Q3p = cstar*2; 
		} 
 
		return (D1_3 + Q2p + Q3p)/dx; 
	} 
 
 
	// vv4 = phi_i 
	inline double DerWENOMinus(double vv1, double vv2, double vv3, double vv4, double vv5, double vv6, double dx) 
	{ 
		double v1 = (vv2-vv1)/dx; 
		double v2 = (vv3-vv2)/dx; 
		double v3 = (vv4-vv3)/dx; 
		double v4 = (vv5-vv4)/dx; 
		double v5 = (vv6-vv5)/dx; 
 
		double data_x_1 = (2*v1 - 7*v2 + 11*v3)/6; 
		double data_x_2 = (-v2 + 5*v3 + 2*v4)/6; 
		double data_x_3 = (2*v3 + 5*v4 - v5)/6; 
 
		double dummy1 = v1-2*v2+v3; 
		double dummy2 = v1-4*v2+3*v3; 
		double dummy3 = v2-2*v3+v4; 
		double dummy4 = v2-v4; 
		double dummy5 = v3-2*v4+v5; 
		double dummy6 = 3*v3-4*v4+v5; 
		double dummy_c = 13/12; 
		double S1 = dummy_c*dummy1*dummy1 + 0.25*dummy2*dummy2; 
		double S2 = dummy_c*dummy3*dummy3 + 0.25*dummy4*dummy4; 
		double S3 = dummy_c*dummy5*dummy5 + 0.25*dummy6*dummy6; 
 
		double m = v1*v1; 
		double temp = v2*v2; 
		m = m>=temp?m:temp; 
		temp = v3*v3; 
		m = m>=temp?m:temp; 
		temp = v4*v4; 
		m = m>=temp?m:temp; 
		temp = v5*v5; 
		m = m>=temp?m:temp; 
		double epsil = m*1e-6 + 1e-199; 
 
		double alpha1 = 0.1/((S1+epsil)*(S1+epsil)); 
		double alpha2 = 0.6/((S2+epsil)*(S2+epsil)); 
		double alpha3 = 0.3/((S3+epsil)*(S3+epsil)); 
		return (double)((alpha1*data_x_1 + alpha2*data_x_2 + alpha3*data_x_3)/(alpha1+alpha2+alpha3)); 
	} 
 
	// v3 = phi_i 
	inline double DerWENOPlus(double vv1, double vv2, double vv3, double vv4, double vv5, double vv6, double dx) 
	{ 
 
		double v5 = (vv2-vv1)/dx; 
		double v4 = (vv3-vv2)/dx; 
		double v3 = (vv4-vv3)/dx; 
		double v2 = (vv5-vv4)/dx; 
		double v1 = (vv6-vv5)/dx; 
 
		double data_x_1 = (2*v1 - 7*v2 + 11*v3)/6; 
		double data_x_2 = (-v2 + 5*v3 + 2*v4)/6; 
		double data_x_3 = (2*v3 + 5*v4 - v5)/6; 
 
		double dummy1 = v1-2*v2+v3; 
		double dummy2 = v1-4*v2+3*v3; 
		double dummy3 = v2-2*v3+v4; 
		double dummy4 = v2-v4; 
		double dummy5 = v3-2*v4+v5; 
		double dummy6 = 3*v3-4*v4+v5; 
		double dummy_c = 13/12; 
		double S1 = dummy_c*dummy1*dummy1 + 0.25*dummy2*dummy2; 
		double S2 = dummy_c*dummy3*dummy3 + 0.25*dummy4*dummy4; 
		double S3 = dummy_c*dummy5*dummy5 + 0.25*dummy6*dummy6; 
 
		double m = v1*v1; 
		double temp = v2*v2; 
		m = m>=temp?m:temp; 
		temp = v3*v3; 
		m = m>=temp?m:temp; 
		temp = v4*v4; 
		m = m>=temp?m:temp; 
		temp = v5*v5; 
		m = m>=temp?m:temp; 
		double epsil = m*1e-6 + 1e-199; 
 
		double alpha1 = 0.1/((S1+epsil)*(S1+epsil)); 
		double alpha2 = 0.6/((S2+epsil)*(S2+epsil)); 
		double alpha3 = 0.3/((S3+epsil)*(S3+epsil)); 
		return (double)((alpha1*data_x_1 + alpha2*data_x_2 + alpha3*data_x_3)/(alpha1+alpha2+alpha3)); 
	} 
 
 
 
 
 
 
 
 
};