public class ffgibbs extends f_xj {
	double[][] A;	
	gibbsSpecies[] gs;
	double[][] n0;
	double[][] n00;
	double[][] n;
	double[][] del_lnnm;
	double[][] del_nm;
	double[][] lnnm;
	double nt;
	double lnnt;
	double del_lnnt;
	int NG;//Gas species number
	int l;//element number
	double[][] d_coeff;
	double[][] d_const;
	double[][] b0;
	double[][] b;
	double[][] mu;
	double[] mutemp;
	double P;
	double T;
	double T0;
	double[] Te;
	double lambda;	
	double lambda1;
	double lambda2;
	double etemp=0;
	double Tref=298.15;
	double G=0;
	double Gnew=0;
	double diff=0;
	double SIZE=25.328436;//18.420681;
	double ntahminilk;
	int it_max=100;
	int it_max0=100;
	int o2=-1;
	int n2=-1;
	//double[] error=new double[];	

		
	public ffgibbs(gibbsSpecies[] igs,double[][] in0,double iT,double iP){
		int nn=igs.length;  
		int nat=110;
		double B[][]=new double[nat][nn];		
		int nk=0;		
		for(int i=0;i<nn;i++)
		{ for(nk=0;nk<igs[i].atomList.length;nk++){B[igs[i].atomList[nk].number-1][i]=igs[i].atomList[nk].N;}}
		int natcount=0;
		boolean zeroflag[]=new boolean[110];
		for(int j=0;j<nat;j++)
		{zeroflag[j]=false;for(int i=0;i<nn;i++){if(B[j][i]!=0){zeroflag[j]=true;}};if(zeroflag[j]) natcount++;}
		A=new double[natcount][nn];		
		int k=0;
		for(int j=0;j<nat;j++)
		{if(zeroflag[j]){A[k]=B[j];k++;}}	
		n0=in0;
		n00=new double[n0.length][1];
		for(int i=0;i<n0.length;i++) n00[i][0]=in0[i][0];
		gs=igs;
		P=iP;
		T=iT;	
		for(int i=0;i<in0.length;i++) Te[i]=iT;		
		mu=new double[gs.length][1];
		mutemp=new double[gs.length];	
		l=A.length;
		NG=A[0].length;			
		//n=n0;
		//n=in;
		lambda=1;
		del_lnnm=new double[NG][1];
		del_nm=new double[NG][1];
		lnnm=new double[NG][1];					
		d_coeff=new double[l+1][l+1];
		d_const=new double[l+1][1];
		b=new double[l][1];
		nt=getnt(n0);
		ntahminilk=nt/n0.length;
		n=new double[n0.length][1];
		for(int i=0;i<n0.length;i++)
		{n[i][0]=ntahminilk;}
		nt=getnt(n);		
		b0=new double[l][1];
		for(int ii=0;ii<b0.length;ii++){
			for(int ij=0;ij<NG;ij++){
				b0[ii][0]+=A[ii][ij]*n0[ij][0];
			}	
		} 		 		
		calMu(n0);		
		}
		
		public ffgibbs(String igs[],double[][] in0,double iT,double iP,int iit_max)
		{
			     it_max=iit_max;
			     it_max0=it_max;
			     Te=new double[in0.length];
			     for(int i=0;i<in0.length;i++) Te[i]=iT;
			     setgibbs(igs,in0,iT,iP);			
		}	
		
		public ffgibbs(String igs[],double[][] in0,double iT,double iP,int iit_max,double[][] in)
		{
			P=iP;     
			it_max=iit_max;			     
			it_max0=it_max;
			n=in;			     
			Te=new double[in0.length];			    
			for(int i=0;i<in0.length;i++) Te[i]=iT;
			setgibbs(igs,in0,iP);			
		}
			
		public ffgibbs(String igs[],double[][] in0,double iTe[],double iT,double iP)
		{
		         it_max=500;
			     it_max0=it_max;
			     Te=new double[iTe.length];
			     for(int i=0;i<iTe.length;i++)			     
			     Te[i]=iTe[i];
			     setgibbs(igs,in0,iT,iP);
		}
		
		public ffgibbs(String igs[],double[][] in0,double iTe[],double iT,double iP,int iit_max){
			     it_max=iit_max;
			     it_max0=it_max;
			     Te=new double[iTe.length];
			     for(int i=0;i<iTe.length;i++)			     
			     Te[i]=iTe[i];
			     setgibbs(igs,in0,iT,iP);			
		}			
		
		public ffgibbs(String igs[],double[] inx0,double iTe[],double iT,double iP,int iit_max){
			  setgibbs(igs,inx0,iTe,iT,iP,iit_max);}

		public ffgibbs(String igs[],double[] inx0,double iTe[],double iT,double iP){
			     setgibbs(igs,inx0,iTe,iT,iP,100);}
	
		public void setgibbs(String igs[],double[] inx0,double iTe[],double iT,double iP,int iit_max){
			     it_max=iit_max;
			     it_max0=it_max;
			     Te=new double[iTe.length];
			     for(int i=0;i<iTe.length;i++)			     
			     Te[i]=iTe[i];
			     double[][]	in0=new double[inx0.length][1];	
		         for(int i=0;i<inx0.length;i++)
		         {in0[i][0]=inx0[i];}		
			     setgibbs(igs,in0,iT,iP);			
		}
		
		public double set_Q(String igs[],double[] inx0,double iTe[],double Q,double iP,int iit_max)
		{
		setgibbs(igs,inx0,iTe,1000.0,iP,iit_max);
		double T1=Tad(Q);
		setgibbs(igs,inx0,iTe,T1,iP,iit_max);
		return T1;
		}

	    public double set_Q(String igs[],double[] inx0,double iTe[],double Q,double iP)
		{return set_Q(igs,inx0,iTe,Q,iP,500);}

		public void setgibbs(String igs[],double[] inx0,double iTe[],double iT,double iP)
		{ setgibbs(igs,inx0,iTe,iT,iP,500);}
		
		
		
		public void setgibbs(String igs[],double[][] in0,double iT,double iP){
			gs=new gibbsSpecies[igs.length];		
			for(int i=0;i<igs.length;i++){
				gs[i]=new gibbsSpecies(igs[i],"gas");
			}
	    	int nn=igs.length;
			int nat=110;
			double B[][]=new double[nat][nn];
			int nk=0;		
			for(int i=0;i<nn;i++){
				for(nk=0;nk<gs[i].atomList.length;nk++){
					B[gs[i].atomList[nk].number-1][i]=gs[i].atomList[nk].N;
					}
				}
			int natcount=0;
			boolean zeroflag[]=new boolean[110];
			for(int j=0;j<nat;j++)
			{zeroflag[j]=false;for(int i=0;i<nn;i++){if(B[j][i]!=0){zeroflag[j]=true;}};if(zeroflag[j]) natcount++;}
			A=new double[natcount][nn];		
			int k=0;
			for(int j=0;j<nat;j++)
			{if(zeroflag[j]){A[k]=B[j];k++;}}
			n0=in0;
			n00=new double[n0.length][1];
			for(int i=0;i<n0.length;i++) n00[i][0]=in0[i][0];
			P=iP;
			T=iT;
			T0=iT;	
			mu=new double[gs.length][1];
			mutemp=new double[gs.length];	
			l=A.length;
			NG=A[0].length;			
			lambda=1;
			del_lnnm=new double[NG][1];
			del_nm=new double[NG][1];
			lnnm=new double[NG][1];					
			d_coeff=new double[l+1][l+1];
			d_const=new double[l+1][1];
			b=new double[l][1];
			nt=getnt(n0);
			ntahminilk=nt/n0.length;
			n=new double[n0.length][1];
			for(int i=0;i<n0.length;i++){
				n[i][0]=ntahminilk;
			}
			nt=getnt(n);					
			b0=new double[l][1];
			for(int ii=0;ii<b0.length;ii++){
				for(int ij=0;ij<NG;ij++){
					double carpim=A[ii][ij]*n0[ij][0];	
					b0[ii][0]+=carpim;		
				}						
			}   		
			calMu(n0);
		}
		
		public void setgibbs(String igs[],double[][] in0,double iP){
			gs=new gibbsSpecies[igs.length];		
			for(int i=0;i<igs.length;i++){
				gs[i]=new gibbsSpecies(igs[i],"gas");
			}
	    	int nn=igs.length;
			int nat=110;
			double B[][]=new double[nat][nn];
			int nk=0;		
			for(int i=0;i<nn;i++){
				for(nk=0;nk<gs[i].atomList.length;nk++){
					B[gs[i].atomList[nk].number-1][i]=gs[i].atomList[nk].N;
					}
				}
			int natcount=0;
			boolean zeroflag[]=new boolean[110];
			for(int j=0;j<nat;j++)
			{zeroflag[j]=false;for(int i=0;i<nn;i++){if(B[j][i]!=0){zeroflag[j]=true;}};if(zeroflag[j]) natcount++;}
			A=new double[natcount][nn];		
			int k=0;
			for(int j=0;j<nat;j++)
			{if(zeroflag[j]){A[k]=B[j];k++;}}
			n0=in0;
			n00=new double[n0.length][1];
			for(int i=0;i<n0.length;i++) n00[i][0]=in0[i][0];
			P=iP;				
			mu=new double[gs.length][1];
			mutemp=new double[gs.length];	
			l=A.length;
			NG=A[0].length;			
			lambda=1;
			del_lnnm=new double[NG][1];
			del_nm=new double[NG][1];
			lnnm=new double[NG][1];					
			d_coeff=new double[l+1][l+1];
			d_const=new double[l+1][1];
			b=new double[l][1];
			nt=getnt(n0);
			ntahminilk=nt/n0.length;
			n=new double[n0.length][1];
			for(int i=0;i<n0.length;i++){
				n[i][0]=ntahminilk;
			}
			nt=getnt(n);					
			b0=new double[l][1];
			for(int ii=0;ii<b0.length;ii++){
				for(int ij=0;ij<NG;ij++){
					b0[ii][0]+=A[ii][ij]*n0[ij][0];	
									System.out.println(b0[ii][0]);			
				}	
			}   		
			//calMu(n0);
		}
		
		public void setN0(double[][] in0)
		{
			//n00=new double[n0.length][1];
		    for(int i=0;i<n0.length;i++) n0[i][0]=in0[i][0];
		}
		
		public void setN0Default()
		{
			//n00=new double[n0.length][1];
		    for(int i=0;i<n0.length;i++) n0[i][0]=n00[i][0];
		    b0=getb(n00);
		}
		
		public void setT(double iTeq)
		{
			T=iTeq;
			calMu(n0);			
		}
		
		public void setTDefault()
		{
			T=T0;	
		}
		 
		public void setNmax(int iit_max){ it_max=iit_max;}
		 
		public void setNmaxDefault(){
			it_max=it_max0;	
		}
							
		public void getEq(){
			//System.out.println(l+"  "+NG);
			nt=getnt(n0);
			ntahminilk=nt/n0.length;
			for(int i=0;i<n0.length;i++){
				n[i][0]=ntahminilk;
			}
			nt=getnt(n);
		    b0=getb(n0);	
			double emax=1e-13;
			double etest=1;
			int it_counter=0;
			double temp1=0;
			double temp2=0;
			lnnt=0;		
			for(int i=0;i<gs.length;i++) gs[i].getmu0(T,P);						
			while(it_counter<it_max && etest>emax){
				temp1=0;					
				for(int k=0;k<l;k++){				
					for(int i=0;i<l;i++){					
							for(int j=0;j<NG;j++){
								temp1+=A[k][j]*A[i][j]*n[j][0];							
							}						
							d_coeff[k][i]=temp1;									
							temp1=0;						
					}					
				}		
				for(int k=0;k<l;k++){
					for(int j=0;j<NG;j++){
						temp2+=A[k][j]*n[j][0];	
					}
					d_coeff[k][l]=temp2;
					temp2=0;	
				}
				temp1=0;
				temp2=0;
				for(int i=0;i<l;i++){
					for(int j=0;j<NG;j++){
						temp1+=A[i][j]*n[j][0];	
					}	
					d_coeff[l][i]=temp1;
					temp1=0;
				}   				
				d_coeff[l][l]=getnt(n)-nt;   			    
				b=getb(n);				
				calMu(n);
				for(int k=0;k<l;k++) {					
					for(int j=0;j<NG;j++){
						temp1+=A[k][j]*n[j][0]*mu[j][0]/(8.3145*T);	
					}
					d_const[k][0]=b0[k][0]-b[k][0]+temp1;
					temp1=0;			
				}				
				temp1=0;
				for(int j=0;j<NG;j++){
						temp1+=n[j][0]*mu[j][0]/(8.3145*T);	
					}
				d_const[l][0]=temp1+nt-getnt(n);
				double[][] x=Matrix.AXB(d_coeff,d_const);
				del_lnnt=x[l][0];
				temp2=0;
				for(int j=0;j<NG;j++){					
					for(int i=0;i<l;i++){
						temp2+=A[i][j]*x[i][0];
					}
					del_lnnm[j][0]=temp2+x[l][0]-mu[j][0]/(8.3145*T);
					temp2=0;				
				}
				for(int i=0;i<del_lnnm.length;i++){
					lnnm[i][0]=Math.log(n[i][0]);
					del_nm[i][0]=Math.exp(del_lnnm[i][0]);	
				}   
				///////////////////////////////////////////////////////////////////////////////////////////////////
				double q=0;
				double max=0;
				double min=1e10;
				double s=0;
				for(int i=0;i<NG;i++){					
					if((lnnm[i][0]-Math.log(getnt(n)))>-SIZE){
						max= Math.abs(del_lnnm[i][0])>Math.abs(max) ?  del_lnnm[i][0] :max ;	
					}
					else {
						s=del_lnnm[i][0]>0 ? (Math.abs((-1*(lnnm[i][0]-Math.log(getnt(n)))-9.2103404)/(del_lnnm[i][0]-del_lnnt))) : 1000;
						min= s>min ? min : s;	
					}						
				}				
				q=(5*Math.abs(del_lnnt)>Math.abs(max)) ? (5*Math.abs(del_lnnt)):Math.abs(max);	
				//System.out.println("q= "+q);				
				lambda1=2/q;
				lambda2=min;
				//System.out.println("lambda1= "+lambda1+"  lambda2= "+lambda2);
				lambda= (lambda1<lambda2) ? (1<lambda1 ? 1 : lambda1) : (1<lambda2 ? 1 : lambda2);
				G=getG(n);
				for(int i=0;i<NG;i++){
					lnnm[i][0]+=lambda*del_lnnm[i][0];
					n[i][0]=Math.exp(lnnm[i][0]);
				}				
				lnnt+=lambda*del_lnnt;
				nt=Math.exp(lnnt);				
				//System.out.println("\nGtot= "+getG(n));
				Gnew=getG(n);
				etest=etest();				
				//}
				//////////////////////////////////////////////////////////////////////////////////////////////////							
				it_counter++;
			}   
		}
		
		public double delQ(){
			double Q=0;
			double href=0;
			for(int i=0;i<n.length;i++){
				//System.out.println(Te[i]);													
				Q+=gs[i].ht(T0)*n[i][0]-gs[i].ht(Te[i])*n0[i][0];			}			
			return Q;//Kj		
		}
		
		public double delQ_T(double innerT){
			double Q=0;
			double href=0;
			setT(innerT);			
			setNmax(500);			
			getEq();			
			for(int i=0;i<n.length;i++){
				Q+=gs[i].ht(innerT)*n[i][0]-gs[i].ht(Te[i])*n0[i][0];	
			}
			setTDefault();
			setNmaxDefault();
			return Q;//Kj				
		}	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////		
		public double Airad(double iQ,double ix1,double ix2){			
			for(int i=0;i<gs.length;i++){
				//System.out.println("LK[i].Formula= "+LK[i].Formula);
				if(gs[i].Formula.equals("O2")){
					o2 = i;					
					break;		
				}
				//System.out.println("o2= "+o2);
			}
		for(int i=0;i<gs.length;i++){
				//System.out.println("LK[i].Formula= "+LK[i].Formula);
				if(gs[i].Formula.equals("N2")){
					n2 = i;
					break;		
				}
			}
			if(o2!=-1 && n2!=-1){
				 //Ridder Metodu ile lineer olmayan denklemlerin köklerinin bulunmas?
		         //referans : Numerical Recipes in C, second edition, William H. Press, 
		         //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery
		         //cambridge university press	
		  double[][] x_bracket=new double[2][1]; 
		  x_bracket=delQAirBracket(iQ,ix1,ix2);	
		  double x1=x_bracket[0][0];
		  double x2=x_bracket[1][0];
		  //System.out.println("x1= "+x1+" x2= "+x2);
		  int MAXIT=50;
		    double xacc=1.0e-4;int j;
			double fl,fh,xl,xh,swap,dx,del,ff;
			double rtf=x1;
			fl=delQAir(x1)-iQ;
			fh=delQAir(x2)-iQ;
			//System.out.println("fl= "+fl+" fh= "+fh);
		    if (fl*fh > 0.0)System.out.println("Kök s?n?rlar? do?ru olarak seçilmemi? \n sonuç hatal? olabilir"); 
			if (fl < 0.0) {
				xl=x1;
				xh=x2;
			} else {
				xl=x2;
				xh=x1;
				swap=fl;
				fl=fh;
				fh=swap;
			}
			dx=xh-xl;
			for (j=1;j<=MAXIT;j++) {
				rtf=xl+dx*fl/(fl-fh);
				ff=delQAir(rtf)-iQ;
				if (ff < 0.0) {
					del=xl-rtf;
					xl=rtf;
					fl=ff;
				} else {
					del=xh-rtf;
					xh=rtf;
					fh=ff;
				}
				//System.out.println("rtf= "+rtf);
				dx=xh-xl;
				//System.out.println("xl= "+xl+" xh= "+xh);
			//System.out.println("fl= "+fl+" fh= "+fh);
				if (Math.abs(del) < xacc || ff == 0.0) return rtf;
			}
			System.out.println("Uyarı maximum iterasyon sayısı aşıldı \n"+
		   " çözüm geçerli olmıyabilir");			
		    return rtf; 		
			}else {
				System.out.println("Girdiğiniz karışım O2 ve N2 içermelidir !");
				System.exit(1);
			}
			return 0;			
		}
				
		public double delQAir(double x){
			for(int i=0;i<n0.length;i++) n0[i][0]=n00[i][0];			
			n0[o2][0]=x;
			n0[n2][0]=x*79/21;
			//System.out.println("n0=\n");
			//for(int i=0;i<n0.length;i++) System.out.println(LK[i].Formula+"  "+n0[i][0]);
			System.out.println("T= "+T);
			return delQ_T(T);			
		} 
		
		public double delQAir(double x,int ii,int ij){
			for(int i=0;i<n0.length;i++){ 
				//System.out.println("n00=\n"+Matrix.toString(n00));
				n0[i][0]=n00[i][0];				
			}
			n0[ii][0]=x;
			n0[ij][0]=x*79/21;			
			//System.out.println("n0=\n");
			//for(int i=0;i<n0.length;i++) System.out.println(LK[i].Formula+"  "+n0[i][0]);
			return delQ_T(T);			
		} 
		
		public  double[][] delQAirBracket(double iQ,double x1,double x2){			
			// koklerin yer aldığı alt bölgeleri saptar
			// n : verilen bölgeyi böldüğümüz alt bölge sayısı
			// x1,x2 : sınır değerleri
			// nbb = aranan bölgedeki köksayısı	
			int n=4;
			int nbb=1; 
			int nb;			
			int i;
			double x,fp,fc,dx;
			double xb[][]=new double[2][nbb];
			nb=0;
			dx=(x2-x1)/n;
			x=x1;
			//System.out.println("x= "+x);
			fp=delQAir(x1)-iQ;
			//System.out.println("x1= "+x1+" fp= "+fp);
			for (i=1;i<=n;i++) 
			{
				x+=dx;
				fc=delQAir(x)-iQ;
				//System.out.println("x= "+x+" fc= "+fc);
				// eğer kök olan bölge bulunduysa.....
				if (fc*fp < 0.0 || fp==0) {
					xb[0][nb]=x-dx;
					xb[1][nb]=x;
					nb++;
				}
				fp=fc;
				if (nbb == nb) return xb;
			}	
		if( nb == 0)
		System.out.println("arama tamamlandı kök olan bölge bulunamadı");			
		else if(nb<nbb){
			System.out.println("arama tamamland? sadece "+nb+" adet kök bulundu \n"+
		    "siz "+nbb+" adet kök için arama yapt?rd?n?z");			
		   double xc[][]=new double[2][nb];
		   for (i=0;i<nb;i++) {xc[0][i]=xb[0][i];xc[1][i]=xb[1][i];}
		   return xc;
		  }
		return xb;
	}
		
//////////////////////////////////////////////////////////////////////////////////////////////////////////////				
		public  double[][] TadBracket(double iQ){			
			// koklerin yer ald??? alt bölgeleri saptar
			// n : verilen bölgeyi böldü?ümüz alt bölge say?s?
			// x1,x2 : s?n?r de?erleri
			// nbb = aranan bölgedeki köksayısı	
			int n=4;
			int nbb=1; 
			int nb;
			double x1=298;
			double x2=5000;
			int i;
			double x,fp,fc,dx;
			double xb[][]=new double[2][nbb];
			nb=0;
			dx=(x2-x1)/n;
			x=x1;
			fp=delQ_T(x1)-iQ;
			//System.out.println("x1= "+x1+" fp= "+fp);
			for (i=1;i<=n;i++) 
			{
				x+=dx;
				fc=delQ_T(x)-iQ;
				//System.out.println("x= "+x+" fc= "+fc);
				// eger kök olan bölge bulunduysa.....
				if (fc*fp < 0.0 || fp==0) {
					xb[0][nb]=x-dx;
					xb[1][nb]=x;
					nb++;
				}
				fp=fc;
				if (nbb == nb) return xb;
			}	
		if( nb == 0)
		System.out.println("arama tamamland? kök olan bölge bulunamad?");			
		else if(nb<nbb){
			System.out.println("arama tamamland? sadece "+nb+" adet kök bulundu \n"+
		    "siz "+nbb+" adet kök için arama yapt?rd?n?z");			
		   double xc[][]=new double[2][nb];
		   for (i=0;i<nb;i++) {xc[0][i]=xb[0][i];xc[1][i]=xb[1][i];}
		   return xc;
		  }
		return xb;
	}
	
	public  double Tad(double iQ)
	{
		  // Ridder Metodu ile lineer olmayan denklemlerin köklerinin bulunmas?
		  //referans : Numerical Recipes in C, second edition, William H. Press, 
		  //Saul A. Teukolsky, William T. Vetterling, Brian P. Flannery
		  //cambridge university press	
		  double[][] x_bracket=new double[2][1]; 
		  x_bracket=TadBracket(iQ);	
		  double x1=x_bracket[0][0];
		  double x2=x_bracket[1][0];
		  //System.out.println("x1= "+x1+" x2= "+x2);
		  int MAXIT=50;
		    double xacc=1.0e-4;int j;
			double fl,fh,xl,xh,swap,dx,del,ff;
			double rtf=x1;
			fl=delQ_T(x1)-iQ;
			fh=delQ_T(x2)-iQ;
			//System.out.println("fl= "+fl+" fh= "+fh);
		    if (fl*fh > 0.0)System.out.println("Kök s?n?rlar? do?ru olarak seçilmemi? \n sonuç hatal? olabilir"); 
			if (fl < 0.0) {
				xl=x1;
				xh=x2;
			} else {
				xl=x2;
				xh=x1;
				swap=fl;
				fl=fh;
				fh=swap;
			}
			//System.out.println("xl= "+xl+" xh= "+xh);
			//System.out.println("fl= "+fl+" fh= "+fh);
			dx=xh-xl;
			for (j=1;j<=MAXIT;j++) {
				rtf=xl+dx*fl/(fl-fh);
				ff=delQ_T(rtf)-iQ;
				if (ff < 0.0) {
					del=xl-rtf;
					xl=rtf;
					fl=ff;
				} else {
					del=xh-rtf;
					xh=rtf;
					fh=ff;
				}
				//System.out.println("rtf= "+rtf);
				dx=xh-xl;
				//System.out.println("xl= "+xl+" xh= "+xh);
			//System.out.println("fl= "+fl+" fh= "+fh);
			//System.out.println("n=\n"+Matrix.toString(n));
				if (Math.abs(del) < xacc || ff == 0.0) return rtf;
			}
			System.out.println("Uyarı maximum iterasyon sayısı aşıldı \n"+
		   " çözüm geçerli olm?yabilir");			
		    return rtf; 
	}	
		public void calMu(double[][] in){
			for(int i=0;i<mu.length;i++){
				mu[i][0]=gs[i].mu(T,P,in[i][0],getnt(in));
			}	
		}
		

		public double[][] getb(double[][] in){
			//System.out.println("A= \n"+Matrix.toString(A));
			//System.out.println("in= \n"+Matrix.toString(in));
			double inner_b[][]=new double[A.length][1];
			for(int ii=0;ii<inner_b.length;ii++){
				inner_b[ii][0]=0;
				for(int ij=0;ij<NG;ij++){
					//System.out.println("A[ii][ij]= "+A[ii][ij]+" n0[ij][0]="+n0[ij][0] );   				
					inner_b[ii][0]+=A[ii][ij]*in[ij][0];			
				}
			}
			return inner_b;
		}
		
		public double etest(){			
			double[][] e=new double[NG+2][1];
			double inner_etest=0;
			//System.out.println("n=\n "+Matrix.toString(n));
			//System.out.println("deln=\n "+Matrix.toString(del_lnnm));
			for(int j=0;j<NG;j++){
				//System.out.println(""+del_lnnm[j][0]+"  "+n[j][0]+" "+getnt(n));
				e[j][0]=n[j][0]*Math.abs(del_lnnm[j][0])/getnt(n);	
				//System.out.println(j+". eleman  "+e[j][0]);				
			}  
			e[NG][0]=nt*Math.abs(del_lnnt)/getnt(n);
			//System.out.println("toplam n. eleman  "+e[NG][0]);
			e[NG+1][0]=Math.abs(G-Gnew)/Math.abs(G);
			double etest1=Matrix.normEns(Matrix.substract(b0,getb(n)));			
			double etest0=Matrix.normEns(e);
			if(etest0>1e-5){
				if(etest1>1e-6){
					inner_etest= etest1<etest0 ? etest0 : etest1;	
					return inner_etest;
				}
				else return etest0;
			}
			else{
				if(etest1>1e-6)	return etest1;				
				else{ 
					inner_etest= etest1<etest0 ? etest0 : etest1;	
					return inner_etest;
				}	
			}
			//return etest1;			
		}		
		public double getnt(double[][] jn){
			double nt_inner=0;
			for(int i=0;i<jn.length;i++) nt_inner+=jn[i][0];
			return nt_inner;		
	 	}		 	
	 	public double getG(double[][] in){
			calMu(in);
		 	double munt=0;
			for(int j=0;j<mu.length;j++) mu[j][0]*=in[j][0];
		 	for(int i=0;i<mu.length;i++) munt+=mu[i][0];
			return munt;		
	 	}
	 	public double[][] getSolution(){
            return n;
        }
                public int geto2Index(){
                    return o2;
                }
                  public int getn2Index(){
                    return n2;
                }
}    