예제 #1
0
파일: gsl.c 프로젝트: xushiwei/pure-lang
int wrap_gsl_matrix_complex_scale(gsl_matrix_complex *a, pure_expr *x)
{
  double d;
  gsl_complex z;
  if (pure_is_double(x, &d)) {
    z.dat[0] = d; z.dat[1] = 0.0;
    return gsl_matrix_complex_scale(a, z);
  } else if (pure_is_complex(x, z.dat))
    return gsl_matrix_complex_scale(a, z);
  else
    return 0;
}
예제 #2
0
static int _equalf(CMATRIX *a, double f)
{
	bool result;
	
	if (COMPLEX(a))
	{
		if (f == 0.0)
			return gsl_matrix_complex_isnull(CMAT(a));
		
		gsl_matrix_complex *m = gsl_matrix_complex_alloc(WIDTH(a), HEIGHT(a));
		gsl_matrix_complex_set_identity(m);
		gsl_matrix_complex_scale(m, gsl_complex_rect(f, 0));
		result = gsl_matrix_complex_equal(CMAT(a), m);
		gsl_matrix_complex_free(m);
	}
	else
	{
		if (f == 0.0)
			return gsl_matrix_isnull(MAT(a));
		
		gsl_matrix *m = gsl_matrix_alloc(WIDTH(a), HEIGHT(a));
		gsl_matrix_set_identity(m);
		gsl_matrix_scale(m, f);
		result = gsl_matrix_equal(MAT(a), m);
		gsl_matrix_free(m);
	}
	
	return result;
}
예제 #3
0
/*
 * Calculate the matrix exponent of A and store in eA.
 * Algorithm: Truncated Talyor series.
 *
 * WARNING: Large errors possible and it's slow.
 */
int 
gsl_ext_expm_complex(gsl_matrix_complex *A, gsl_matrix_complex *eA)
{
    int i;
    gsl_complex alpha, beta, z;
    gsl_matrix_complex *I, *T;
    
    I = gsl_matrix_complex_alloc(A->size1, A->size2);
    T = gsl_matrix_complex_alloc(A->size1, A->size2);
    
    GSL_SET_COMPLEX(&alpha, 1.0, 0.0);
    GSL_SET_COMPLEX(&beta,  0.0, 0.0);
    
    gsl_matrix_complex_set_identity(I);
    gsl_matrix_complex_set_identity(eA);
    
    for (i = 50; i > 0; i--)
    {
        GSL_SET_COMPLEX(&z, 1.0 / i, 0.0);
        gsl_matrix_complex_scale(eA, z);
        
        gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, alpha, eA, A, beta, T);    
        gsl_matrix_complex_add(T, I);
        gsl_matrix_complex_memcpy(eA, T);
    }
    
    return 0;
}
예제 #4
0
/* 
 *      FUNCTION  
 *         Name:  entropy_of_state
 *  Description:  Calculate the Von Neumann entropy of state 'rho'
 * 
 */
double entropy_of_state ( const gsl_vector* rho )
{
	double entr = 0 ;

	/* Finding the eigenvalues */
	gsl_eigen_herm_workspace* rho_ei = gsl_eigen_herm_alloc(2);
	gsl_matrix_complex* dens = gsl_matrix_complex_calloc (2,2);
	gsl_matrix_complex_set (dens, 0, 0, gsl_complex_rect(1+VECTOR(rho, 3),0));
	gsl_matrix_complex_set (dens,0,1,gsl_complex_rect(VECTOR(rho,1),-VECTOR(rho,2)));
	gsl_matrix_complex_set (dens,1,0,gsl_complex_rect(VECTOR(rho,1),VECTOR(rho,2)));
	gsl_matrix_complex_set (dens,1,1,gsl_complex_rect(1-VECTOR(rho,3),0));
	gsl_matrix_complex_scale (dens, gsl_complex_rect(0.5,0));
	gsl_vector* eigenvalues = gsl_vector_calloc(2) ;
	gsl_eigen_herm (dens, eigenvalues, rho_ei) ;
	
	/* Calculating entropy */
	double norm = gsl_hypot3( VECTOR(rho,1), VECTOR(rho,2),	VECTOR(rho,3) ) ;
	if ( gsl_fcmp(norm, 1, 1e-9) > 0 )
		entr = 0 ;
	else
		entr = - (VECTOR(eigenvalues,0)*gsl_sf_log(VECTOR(eigenvalues,0)) +
			VECTOR(eigenvalues,1)*gsl_sf_log(VECTOR(eigenvalues,1))) ;

	return (entr);
}		/* -----  end of function entropy_of_state  ----- */
예제 #5
0
void
qdpack_matrix_scale(qdpack_matrix_t *op, qdpack_complex z)
{
    if (op == NULL)
        return;

    gsl_matrix_complex_scale(op->data, z);
}
예제 #6
0
static void matrix_complex_add_identity(gsl_matrix_complex *m, gsl_complex c)
{
	gsl_matrix_complex *id = gsl_matrix_complex_alloc(m->size1, m->size2);
	gsl_matrix_complex_set_identity(id);
	gsl_matrix_complex_scale(id, c);
	gsl_matrix_complex_add(m, id);
	gsl_matrix_complex_free(id);
}
예제 #7
0
static int
do_ccmul(lua_State *L, mMatComplex *a, double b_re, double b_im)
{
    mMatComplex *r = qlua_newMatComplex(L, a->l_size, a->r_size);
    gsl_complex z;

    gsl_matrix_complex_memcpy(r->m, a->m);
    GSL_SET_COMPLEX(&z, b_re, b_im);
    gsl_matrix_complex_scale(r->m, z);

    return 1;
}
예제 #8
0
static CMATRIX *_divo(CMATRIX *a, void *b, bool invert)
{
	bool complex = COMPLEX(a);
	CMATRIX *m;
	gsl_complex c;
	
	if (!GB.Is(b, CLASS_Complex))
		return NULL;
	
	c = ((CCOMPLEX *)b)->number;
	
	if (invert)
	{
		void *inv = matrix_invert(MAT(a), complex);
		
		if (!inv)
		{
			GB.Error(GB_ERR_ZERO);
			return NULL;
		}
		
		m = MATRIX_create_from(inv, complex);
	}
	else
	{
		if (GSL_REAL(c) == 0 && GSL_IMAG(c) == 0)
		{
			GB.Error(GB_ERR_ZERO);
			return NULL;
		}
		
		c = gsl_complex_inverse(c);
		m = MATRIX_make(a);
	}
	
	MATRIX_ensure_complex(m);
	gsl_matrix_complex_scale(CMAT(m), c);
	
	return m;
}
예제 #9
0
static int _equalo(CMATRIX *a, void *b)
{
	bool result;
	CCOMPLEX *c;
	
	if (!GB.Is(b, CLASS_Complex))
		return -1;
	
	c = (CCOMPLEX *)b;
	
	if (GSL_IMAG(c->number) == 0.0)
		return _equalf(a, GSL_REAL(c->number));
	
	if (!COMPLEX(a))
		return FALSE;
	
	gsl_matrix_complex *m = gsl_matrix_complex_alloc(WIDTH(a), HEIGHT(a));
	gsl_matrix_complex_set_identity(m);
	gsl_matrix_complex_scale(m, c->number);
	result = gsl_matrix_complex_equal(CMAT(a), m);
	gsl_matrix_complex_free(m);
	return result;
}
예제 #10
0
static CMATRIX *_divf(CMATRIX *a, double f, bool invert)
{
	bool complex = COMPLEX(a);
	CMATRIX *m;
	
	if (invert)
	{
		void *inv = matrix_invert(MAT(a), complex);
		
		if (!inv)
		{
			GB.Error(GB_ERR_ZERO);
			return NULL;
		}
		
		m = MATRIX_create_from(inv, complex);
	}
	else
	{
		if (f == 0.0)
		{
			GB.Error(GB_ERR_ZERO);
			return NULL;
		}
		
		f = 1 / f;
		m = MATRIX_make(a);
	}
	
	if (complex)
		gsl_matrix_complex_scale(CMAT(m), gsl_complex_rect(f, 0));
	else
		gsl_matrix_scale(MAT(m), f);
	
	return m;
}
예제 #11
0
bool Matrix_Scale(gsl_matrix_complex *A, double _Complex s){
	gsl_matrix_complex_scale(A, c2g(s));
	return true;
	}
예제 #12
0
bool Matrix_Scale(gsl_matrix_complex *A, gsl_complex s){
	gsl_matrix_complex_scale(A, s);
	return true;
	}
예제 #13
0
int main(int argc, char * argv[])
{
	int num,i,*states,num_e,j,k;
	double *entry, *dos_vec, *eval_vec;
	double coef;
	char tmpc;
	gsl_vector *eval;
	gsl_matrix_view m;
	gsl_eigen_symm_workspace *w;
	gsl_matrix_complex * matrix2;
	gsl_complex z;
	gsl_permutation * p;
	char name[25];
	FILE *out;

	
	if ((out = fopen(argv[1],"r")) != NULL)
	{
		num = 0;
		printf("reading from file: %s....\n",argv[1]);
		while(fscanf(out,"%lf",&coef) != EOF) num++;
		if (modf(sqrt(num),&coef) != 0)
		{
			printf("not a square matrix!\n\n");
			return 1;
		}
		//printf("%d\n",num);
		fseek(out,0,SEEK_SET);
		num = sqrt(num);
		entry = (double *)malloc(sizeof(double) * num * num);
		i = 0;
		while (i < (num * num))
		{
			*(entry + i) = 0;
			i++;
		}
		i = 0;
		printf("loading matrix into memory...\n");
		while(fscanf(out,"%lf",&coef) != EOF)
		{
			*(entry + i) = coef;
			printf("entry %d = %g\n",i + 1,coef);
			i++;
		}
		flags += NUMPRINT;
		flags += READFROMFILE;
	}
	
	if (argc < 6 && (flags & READFROMFILE) == 0)
	{
		printf("usage: no. of layers, slope of cone/no. of atoms per layer, on-site energy, hopping parameter, model, (option)\n");
		printf("\n Models are:\n1: Nanotube, square lattice\n2: Nanotube, hex lattice (armchair)\n");
		printf("3: Nanohorn, square lattice\n4: Nanohorn hex lattice\n5: Nanotube, hex lattice (zig-zag)\n");
		printf("\nOptions are: p - print symbolically\n             n - print numerically\n\n");
		return 1;
	}
	else if ((flags & READFROMFILE) != 0)
	{
		
	}
	else
	{
		num = atoi(argv[1]); 
		Epsilon = atol(argv[3]);
		Gamma = atol(argv[4]);
		switch(atoi(argv[5]))
		{
			case 1: flags = flags + CNT_SQUARE;
				Alpha = atoi(argv[2]);
				num *= Alpha;
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 2: flags = flags + CNT_HEX_ARM;
				Alpha = atoi(argv[2]);
				i = Alpha;
				if ((i % 2) != 0)
				{
					printf("no. of atoms per layer must be even, changing to %d\n",i + 1);
					Alpha += 1;
				}
				num *= (Alpha);
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 3: flags = flags + HORN_SQUARE;
				i = 1;
				num_e = 0;
				while (i <= num)
				{
					num_e += i;
					i++;
			}
				num = num_e;
				entry = (double *)malloc(sizeof(double) * num * num);
				break;
			case 4: flags = flags + HORN_HEX;
				num = 0;
				entry = NULL;
				break;
			case 5: flags = flags + CNT_HEX_ZIG;
				Alpha = atoi(argv[2]);
				i = Alpha;
				while ((i % 4) != 0)
				{
					i++;
				}
				Alpha = i;
				num *= Alpha;
				entry = (double *)malloc(sizeof(double) * num * num);	
				break;
			default: printf("No valid model choice!\n");
				return 1;
				break;
				  
		}
		i = 0;
		while (i < (num * num))
		{
			*(entry + i) = 0;
			i++;
		}
	printf("Alpha = %g\n",Alpha);
	}
	printf("%d atoms\n",num);
	if (argc > 6)
	{
		if (strcmp("p\0",argv[6]) == 0) 
		{
			//printf("print");
			flags = flags + PRINT;
		}
		if (strcmp("n\0", argv[6]) == 0)
		{
			flags = flags + NUMPRINT;
		}	
	}
	eval = gsl_vector_alloc(num);


	//printf("flags %d\n",flags); 
	//k = (flags & PRINT);
	//printf("print ? %d\n",k); 
	//printf("%lf",Alpha);
	//printf("%d",num);
	
	if (entry == NULL)
	{
		printf("could not allocate memory\n");
		return 1;

	}
	i = 0;
	if ((flags & READFROMFILE) == 0) 
	{
		printf("Populating Matrix...\n");
		PopulateMatrix(entry,num);
		out = fopen("matrix","w");
		i = 0;
		while (i < (num * num))
		{
			fprintf(out,"%3.5lf ",*(entry + i));
			if (((i + 1) % num) == 0) fprintf(out,"\n");
			i++;
		}
		fclose(out);
	}
	else
	{
		
	}
	printf("Printing Matrix\n");
	
	PrintMatrix(entry,num);

	//CalcEigenvalues(entry,num,eval);
	
	
	
	//Eigenvalue Calculation
	m = gsl_matrix_view_array (entry,num,num);
	//printf("87\n");
        w = gsl_eigen_symm_alloc (num);
	//printf("89\n");
	printf("Solving Eigenvalue equation....\n");
        if(gsl_eigen_symm (&m.matrix, eval, w)) 
	{
		printf("an error occurred solving the eigenvalue equation\n");
		return 1;
	}	
	//printf("\nworkspace location = %#x",w);
	gsl_eigen_symm_free(w);


	
	printf("\n\n");
	//if (flags & NUMPRINT != 0 || flags & PRINT != 0)
	printf("Eigenvalues found. ");
	eval_vec = malloc(sizeof(double) * num);
	i = 0;
	while (i < num)
	{
		*(eval_vec + i) = gsl_vector_get(eval,i);
		i++;
	}
	gsl_vector_free(eval);
	tmpc = 0;
	printf("Ordering Eigenvalues...\n");
	qsort(eval_vec,num,sizeof(double),comparedouble);
	division = ((*(eval_vec + num - 1) - *eval_vec) / num) * 10 * INTERVAL;
	num_e = ((*(eval_vec + num - 1) - *eval_vec))/ division;
	num_e++; //just in case
	while ((flags & FINISHED) == 0)
	{
		if (tmpc != -1) printf("(s)ave in file, (q)uit and discard, (p)rint (!), (d)ensity of states: ");
		scanf("%c",&tmpc);
		if (tmpc == 'p' || tmpc == 'P')
		{
			i = 0;
			while (i < num)
			{
				printf("Eigenvalue %d\t: %g\n",(i + 1),*(eval_vec + i));
				i++;
			}
			printf("\n");
			tmpc = -1;
		}
		else if (tmpc == 'q' || tmpc == 'Q')
		{
			printf("\nexiting...\n\n");
			flags += FINISHED;
		}
		else if (tmpc == 'd' || tmpc == 'D')
		{
			tmpc = 0;
			dos_vec = malloc(sizeof(double) * num_e);
			states = malloc(sizeof(int) * num_e);
			printf("\nCalculating density of states...\n");
			Calculate(eval_vec,num,dos_vec,states);
			i = 0;
			printf("\n");
			out = fopen("dostube","w");
			while (i < num_e && *(states + i) >= 0)
			{
				printf("Energy: % .5lf\tNo. of states: %d\n",*(dos_vec + i),*(states + i));
				fprintf(out,"% .5lf\t%d\n",*(dos_vec + i),*(states + i));
				i++;
			}
			num_e = i;
			fclose(out);

			flags += FINISHED;
			flags += DOS;
		}
		else if (tmpc == -1) //WHY?!!
		{
			tmpc = 0;
		}
		else if (tmpc == 's' || tmpc == 'S') //broken for some reason
		{
			printf("\nchoose filename: ");

			scanf("%s",name);
			//printf("%s",name);
			out = fopen(name,"r");
			if (out != NULL)
			{
				printf("File already exists!\n");
				fclose(out);
			}
			else 
			{
				fclose(out);
				out = fopen(name,"w");
				printf("Writing to file: %s",name);
				i = 0;
				while (i < num)
				{
					fprintf(out,"Eigenvalue %d\t: %g\n",(i + 1),*(eval_vec + i));
					i++;
				}
				fclose(out);
				tmpc = -1;
			}
		}
		else
		{
			printf("unrecognised option!\n");
		}
	}
	if ((flags & DOS) != 0)
	{
		while (j < num_e)
		{
			matrix2 = gsl_matrix_complex_alloc(sizeof(gsl_complex) * num,sizeof(gsl_complex) * num);
			i = 0;
			gsl_matrix_complex_set_identity(matrix2);
			z.dat[0] = *(dos_vec + j);
			z.dat[1] = 0.0001;
			gsl_matrix_complex_scale(matrix2,z);
			while (i < num)
			{
				k = 0;
				while(k < num)
				{
					z = gsl_matrix_complex_get(matrix2,i,k);
					z.dat[0] -= *(entry + i + (k * num));
					gsl_matrix_complex_set(matrix2,i,k,z);
					k++;		
				}
				i++;
			}
			out = fopen("matrix","w");
			gsl_matrix_complex_fprintf(out,matrix2,"% 2.2lf");
			fclose(out);
			free(entry);
		}
		
	}

	//printf("\neval location = %#x",eval);
	return 0;
}
예제 #14
0
void Spectrometer::countDispersion_BS(Medium &Osrodek, QString DataName, QProgressBar *Progress, int factor) {
    //lsfgerhla

    double a=Osrodek.itsBasis.getLatticeConstant();
    double thickness=Osrodek.itsStructure.getThickness();

    int RecVec=itsRecVectors;
    int k_prec=itsK_Precision;
    double wi=itsFrequencies[0];
    double w_prec=itsFrequencies[1];
    double wf=itsFrequencies[2];

    int half=3*(2*RecVec+1)*(2*RecVec+1);
    int dimension=6*(2*RecVec+1)*(2*RecVec+1);
    int EigValStrNumber=6*(2*RecVec+1)*(2*RecVec+1);
    int EigValNumber=9*(2*RecVec+1)*(2*RecVec+1);

    std::ofstream plik;
    DataName="results/"+ DataName + ".dat";
    QByteArray   bytes  = DataName.toAscii();
    const char * CDataName = bytes.data();
    plik.open(CDataName);

    //inicjalizacje wektorów i macierzy

    gsl_matrix *gammaA=gsl_matrix_calloc(dimension, dimension);
    gsl_matrix *gammaB=gsl_matrix_calloc(dimension, dimension);

    gsl_matrix *gammaC=gsl_matrix_calloc(dimension, dimension);
    gsl_matrix *gammaD=gsl_matrix_calloc(dimension, dimension);

    gsl_eigen_genv_workspace *wspce=gsl_eigen_genv_alloc(dimension);
    gsl_eigen_genv_workspace *wspce2=gsl_eigen_genv_alloc(dimension);

    gsl_vector_complex *StrAlpha =gsl_vector_complex_alloc(dimension);
    gsl_vector *StrBeta = gsl_vector_alloc(dimension);
    gsl_matrix_complex *StrEigenVec=gsl_matrix_complex_calloc(dimension, dimension);

    gsl_vector_complex *BAlpha =gsl_vector_complex_alloc(dimension);
    gsl_vector *BBeta = gsl_vector_alloc(dimension);
    gsl_matrix_complex *BasisEigenVec=gsl_matrix_complex_calloc(dimension, dimension);

    gsl_matrix_complex *ChosenVectors = gsl_matrix_complex_calloc(half, EigValNumber);
    gsl_vector_complex *ChosenValues = gsl_vector_complex_calloc(EigValNumber);
    gsl_matrix_complex *Boundaries=gsl_matrix_complex_calloc(EigValNumber, EigValNumber);

    double kx, ky, krokx, kroky, boundary_x, boundary_y;
    double k_zred, k_zred0;

    double krok = M_PI/(k_prec*a);

    for (int droga=0; droga<3; droga++) {
    //int droga = 1;
        if (droga==0)           //droga M->Gamma
        {
            kx=-M_PI/a;
            krokx=krok;
            boundary_x=0;
            ky=-M_PI/a;
            kroky=krok;
            boundary_y=0;

            k_zred0=-1*sqrt(pow(kx/(2*M_PI/a), 2)+pow(ky/(2*M_PI/a), 2));
        }
        else if (droga==1)
        {
            kx=0;               //droga Gamma->X
            krokx=krok;
            boundary_x=M_PI/a;
            ky=0;
            kroky=0;
            boundary_y=0;

            k_zred0=sqrt(2)/2;
            //k_zred0=0;
        }
        else if (droga==2)
        {
            kx=M_PI/a;          //Droga X->M
            krokx=0;
            boundary_x=M_PI/a;
            ky=0;
            kroky=krok;
            boundary_y=M_PI/a;

            k_zred0=sqrt(2)/2;
        }

       //petla dla wektorów falowych
       for (; kx <= boundary_x && ky <= boundary_y; kx=kx+krokx, ky=ky+kroky)
       {
           if (droga==0) {
               k_zred = abs(k_zred0 + sqrt( pow(kx/(2*M_PI/a), 2)+pow(ky/(2*M_PI/a), 2)));
           } else {
               k_zred = k_zred0 + kx/(2*M_PI/a) + ky/(2*M_PI/a);
           }


           int postep=int(100*k_zred/1.7);
           Progress->setValue(postep);
           Progress->update();
           QApplication::processEvents();

            //pętla dla częstości w
           for (double w=wi; w<wf; w=w+w_prec)
            {

                gsl_matrix_complex_set_all(Boundaries, gsl_complex_rect (0,0)); //ustawienie wartosci wyznacznika na 0
                gsl_matrix_set_all(gammaA, 0);
                gsl_matrix_set_all(gammaB, 0);
                gsl_matrix_set_all(gammaC, 0);
                gsl_matrix_set_all(gammaD, 0);
                gsl_vector_complex_set_all(StrAlpha, gsl_complex_rect (0,0));
                gsl_vector_set_all(BBeta, 0);
                gsl_vector_complex_set_all(BAlpha, gsl_complex_rect (0,0));
                gsl_vector_set_all(StrBeta, 0);
                gsl_matrix_complex_set_all(BasisEigenVec, gsl_complex_rect (0,0));
                gsl_matrix_complex_set_all(StrEigenVec, gsl_complex_rect (0,0));
                gsl_matrix_complex_set_all(ChosenVectors, gsl_complex_rect (0,0));
                gsl_vector_complex_set_all(ChosenValues, gsl_complex_rect (0,0));

                //gammaA,B dla struktury
                            //gammaA,B dla struktury
                /*
                S - numeruje transformaty tensora sprężystoœci i gestosci
                i - numeruje wiersze macierzy
                j - numeruje kolumny macierzy
                half - druga polowa macierzy
                */
                for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) {
                    for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) {
                        for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) {
                            for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) {

                                double Elasticity[6][6];
                                itsRecStructureSubstance[S].getElasticity(Elasticity);
                                double Density=itsRecStructureSubstance[S].getDensity();
                                double gx=2*M_PI*Nx/a;
                                double gy=2*M_PI*Ny/a;
                                double gx_prim=2*M_PI*Nx_prim/a;
                                double gy_prim=2*M_PI*Ny_prim/a;

                                gsl_matrix_set(gammaA, i, j, Elasticity[3][3]);
                                gsl_matrix_set(gammaA, i+1, j+1, Elasticity[3][3]);
                                gsl_matrix_set(gammaA, i+2, j+2, Elasticity[0][0]);

                                gsl_matrix_set(gammaB, i+2, j, -Elasticity[0][1]*(kx+gx_prim)-Elasticity[3][3]*(kx+gx));
                                gsl_matrix_set(gammaB, i+2, j+1, -Elasticity[0][1]*(ky+gy_prim)-Elasticity[3][3]*(ky+gy));
                                gsl_matrix_set(gammaB, i, j+2, -Elasticity[0][1]*(kx+gx)-Elasticity[3][3]*(kx+gx_prim));
                                gsl_matrix_set(gammaB, i+1, j+2, -Elasticity[0][1]*(ky+gy)-Elasticity[3][3]*(ky+gy_prim));

                                gsl_matrix_set(gammaB, i, j+half, -Elasticity[0][0]*(kx+gx)*(kx+gx_prim)-Elasticity[3][3]*(ky+gy)*(ky+gy_prim)+Density*w*w);
                                gsl_matrix_set(gammaB, i+1, j+half, -Elasticity[0][1]*(kx+gx_prim)*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)*(kx+gx));
                                gsl_matrix_set(gammaB, i, j+half+1, -Elasticity[0][1]*(ky+gy_prim)*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)*(ky+gy));
                                gsl_matrix_set(gammaB, i+1, j+half+1, -Elasticity[0][0]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w);
                                gsl_matrix_set(gammaB, i+2, j+half+2, -Elasticity[3][3]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w);

                                if (i==j) {
                                    gsl_matrix_set(gammaA, i+half, j+half, 1);
                                    gsl_matrix_set(gammaA, i+half+1, j+half+1, 1);
                                    gsl_matrix_set(gammaA, i+half+2, j+half+2, 1);

                                    gsl_matrix_set(gammaB, i+half, j, 1);
                                    gsl_matrix_set(gammaB, i+half+1, j+1, 1);
                                    gsl_matrix_set(gammaB, i+half+2, j+2, 1);
                                }


                            }
                        }
                    }
                }

                //rozwiazanie zagadnienienia własnego
                gsl_eigen_genv(gammaB, gammaA, StrAlpha, StrBeta, StrEigenVec, wspce);


                //gammaC,D dla Podłoża
                for(int Nx=-RecVec, i=0, S=0; Nx<=RecVec; Nx++) {
                    for(int Ny=-RecVec; Ny<=RecVec; Ny++, i=i+3) {
                        for(int Nx_prim=-RecVec, j=0; Nx_prim<=RecVec; Nx_prim++) {
                            for(int Ny_prim=-RecVec; Ny_prim<=RecVec; Ny_prim++, j=j+3, S++) {

                                double Elasticity[6][6];
                                itsRecBasisSubstance[S].getElasticity(Elasticity);
                                double Density=itsRecBasisSubstance[S].getDensity();
                                double gx=2*M_PI*Nx/a;
                                double gy=2*M_PI*Ny/a;
                                double gx_prim=2*M_PI*Nx_prim/a;
                                double gy_prim=2*M_PI*Ny_prim/a;

                                gsl_matrix_set(gammaC, i, j, Elasticity[3][3]);
                                gsl_matrix_set(gammaC, i+1, j+1, Elasticity[3][3]);
                                gsl_matrix_set(gammaC, i+2, j+2, Elasticity[0][0]);

                                gsl_matrix_set(gammaD, i+2, j, -Elasticity[0][1]*(kx+gx_prim)-Elasticity[3][3]*(kx+gx));
                                gsl_matrix_set(gammaD, i+2, j+1, -Elasticity[0][1]*(ky+gy_prim)-Elasticity[3][3]*(ky+gy));
                                gsl_matrix_set(gammaD, i, j+2, -Elasticity[0][1]*(kx+gx)-Elasticity[3][3]*(kx+gx_prim));
                                gsl_matrix_set(gammaD, i+1, j+2, -Elasticity[0][1]*(ky+gy)-Elasticity[3][3]*(ky+gy_prim));

                                gsl_matrix_set(gammaD, i, j+half, -Elasticity[0][0]*(kx+gx)*(kx+gx_prim)-Elasticity[3][3]*(ky+gy)*(ky+gy_prim)+Density*w*w);
                                gsl_matrix_set(gammaD, i+1, j+half, -Elasticity[0][1]*(kx+gx_prim)*(ky+gy)-Elasticity[3][3]*(ky+gy_prim)*(kx+gx));
                                gsl_matrix_set(gammaD, i, j+half+1, -Elasticity[0][1]*(ky+gy_prim)*(kx+gx)-Elasticity[3][3]*(kx+gx_prim)*(ky+gy));
                                gsl_matrix_set(gammaD, i+1, j+half+1, -Elasticity[0][0]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w);
                                gsl_matrix_set(gammaD, i+2, j+half+2, -Elasticity[3][3]*(ky+gy_prim)*(ky+gy)-Elasticity[3][3]*(kx+gx_prim)*(kx+gx)+Density*w*w);

                                if (i==j) {
                                    gsl_matrix_set(gammaC, i+half, j+half, 1);
                                    gsl_matrix_set(gammaC, i+half+1, j+half+1, 1);
                                    gsl_matrix_set(gammaC, i+half+2, j+half+2, 1);

                                    gsl_matrix_set(gammaD, i+half, j, 1);
                                    gsl_matrix_set(gammaD, i+half+1, j+1, 1);
                                    gsl_matrix_set(gammaD, i+half+2, j+2, 1);
                                }


                            }
                        }
                    }
                }

                //rozwiazanie zagadnienienia własnego
                gsl_eigen_genv(gammaD, gammaC, BAlpha, BBeta, BasisEigenVec, wspce2);

                double imagL, realL; //części Re i Im wartości własnych

                int n=0;
                for (int i = 0; i<dimension; i++)
                {
                    //przepisanie wartości i wektorów własnych struktury do macierzy Chosen*
                    gsl_complex StrValue;
                    StrValue= gsl_complex_div_real(gsl_vector_complex_get(StrAlpha, i), gsl_vector_get(StrBeta,i));
                    gsl_vector_complex_set(ChosenValues, i, StrValue);
                    for (int j = half, m=0; j < dimension; j++, m++)
                    {
                        gsl_matrix_complex_set(ChosenVectors, m, i, gsl_matrix_complex_get(StrEigenVec, j, i));
                    }

                    //wybieranie odpowiednich wartości i wektorów własnych dla podłoża i przepisanie do macierzy Chosen*
                    gsl_complex BValue;
                    BValue= gsl_complex_div_real(gsl_vector_complex_get(BAlpha, i), gsl_vector_get(BBeta,i));
                    imagL=GSL_IMAG(BValue);
                    realL=GSL_REAL(BValue);

                    if (imagL > 0.00001 && n+EigValStrNumber<EigValNumber) //warunek na wartości własne && żeby nie było ich więcej niż połowa
                    {
                        gsl_vector_complex_set(ChosenValues, n+EigValStrNumber, BValue); //wybranie wartości własnej

                        for (int j = half, m=0; j < dimension; j++, m++)
                        {
                           gsl_matrix_complex_set(ChosenVectors, m, n+EigValStrNumber, gsl_complex_mul_real(gsl_matrix_complex_get(BasisEigenVec, j, i), -1));  //wybranie drugiej połowy wektora własnego
                        }

                        n++;
                    }

                }

                if (n+EigValStrNumber<EigValNumber)
                {
                    for (int i = 0; i<dimension; i++)
                    {
                        gsl_complex BValue;
                        BValue= gsl_complex_div_real(gsl_vector_complex_get(BAlpha, i), gsl_vector_get(BBeta,i));
                        imagL=GSL_IMAG(BValue);
                        realL=GSL_REAL(BValue);

                        if (imagL < 0.00001 && imagL > -0.00001 && realL < -0.00001 && n+EigValStrNumber<EigValNumber) //warunek na wartości własne && żeby nie było ich więcej niż połowa
                        {
                            gsl_vector_complex_set(ChosenValues, n+EigValStrNumber, BValue); //wybranie wartości własnej

                            for (int j = half, m=0; j < dimension; j++, m++)
                            {
                               gsl_matrix_complex_set(ChosenVectors, m, n+EigValStrNumber, gsl_complex_mul_real(gsl_matrix_complex_get(BasisEigenVec, j, i), -1));  //wybranie drugiej połowy wektora własnego
                            }

                            n++;
                        }
                    }
                }


                //wyznacznik warunków brzegowych - konstrukcja
                /*
                S, S' - numerujš transformaty tensora sprężystoœci
                i - numeruje wektory własne A w pętli dla G
                j - numeruje warunki brzegowe dla kolejnych wektorow odwrotnych G
                k - numeruje wektory własne A w pętli dla G'
                L - numeruje wartoœci własne
                */
                for (int Nx=-RecVec, S=0, S_prim=0, i=0, j=0; Nx <= RecVec; Nx++) {
                    for (int Ny=-RecVec; Ny <= RecVec; Ny++, j=j+9, i=i+3) {

                        for (int L=0; L < EigValNumber; L++) {

                            S_prim = S;
                            for (int Nx_prim=-RecVec, k=0; Nx_prim <= RecVec; Nx_prim++) {
                                for (int Ny_prim=-RecVec; Ny_prim <= RecVec; Ny_prim++, S_prim++, k=k+3) {

                                    double StrElasticity[6][6];
                                    itsRecStructureSubstance[S_prim].getElasticity(StrElasticity);
                                    double BasisElasticity[6][6];
                                    itsRecBasisSubstance[S_prim].getElasticity(BasisElasticity);

                                    double gx_prim=2*M_PI*Nx_prim/a;
                                    double gy_prim=2*M_PI*Ny_prim/a;

                                    if (L < EigValStrNumber)
                                    {

                                        //eksponens
                                        gsl_complex exponent = gsl_complex_polar(exp(GSL_IMAG(gsl_vector_complex_get(ChosenValues, L))*thickness), -1*GSL_REAL(gsl_vector_complex_get(ChosenValues, L))*thickness);

                                        //warunki zerowania się naprężenia na powierzchni
                                        gsl_complex w1 = gsl_complex_mul_real(exponent, StrElasticity[3][3]);
                                        gsl_complex w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim));
                                        gsl_complex w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L));
                                        gsl_complex BCjL = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w3), w1), gsl_matrix_complex_get(Boundaries, j, L));
                                        gsl_matrix_complex_set(Boundaries, j, L, BCjL);

                                        w1 = gsl_complex_mul_real(exponent, StrElasticity[3][3]);
                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L));
                                        BCjL = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w3), w1), gsl_matrix_complex_get(Boundaries, j+1, L));
                                        gsl_matrix_complex_set(Boundaries, j+1, L, BCjL);

                                        w1 = gsl_complex_mul_real(exponent, StrElasticity[0][0]);
                                        gsl_complex w11 = gsl_complex_mul_real(exponent, StrElasticity[0][1]);
                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim));
                                        gsl_complex w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L));
                                        gsl_complex w4 = gsl_complex_add(gsl_complex_mul(gsl_complex_add(w2, w22), w11), gsl_complex_mul(w3, w1));
                                        BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+2, L));
                                        gsl_matrix_complex_set(Boundaries, j+2, L, BCjL);

                                        //warunki równości naprężeń na granicy ośrodków - część dla struktury
                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L));
                                        BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), StrElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+3, L));
                                        gsl_matrix_complex_set(Boundaries, j+3, L, BCjL);

                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L));
                                        BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), StrElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+4, L));
                                        gsl_matrix_complex_set(Boundaries, j+4, L, BCjL);

                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim));
                                        w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L));
                                        w4 = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w22), StrElasticity[0][1]), gsl_complex_mul_real(w3, StrElasticity[0][0]));
                                        BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+5, L));
                                        gsl_matrix_complex_set(Boundaries, j+5, L, BCjL);

                                    } else {

                                        //warunki równości naprężeń na granicy ośrodków - część dla podłoża
                                        gsl_complex w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (kx+gx_prim));
                                        gsl_complex w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k, L));
                                        gsl_complex BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), BasisElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+3, L));
                                        gsl_matrix_complex_set(Boundaries, j+3, L, BCjL);

                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+2, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+1, L));
                                        BCjL = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w3), BasisElasticity[3][3]), gsl_matrix_complex_get(Boundaries, j+4, L));
                                        gsl_matrix_complex_set(Boundaries, j+4, L, BCjL);

                                        w2 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k, L), (kx+gx_prim));
                                        gsl_complex w22 = gsl_complex_mul_real(gsl_matrix_complex_get(ChosenVectors, k+1, L), (ky+gy_prim));
                                        w3 = gsl_complex_mul(gsl_vector_complex_get(ChosenValues, L), gsl_matrix_complex_get(ChosenVectors, k+2, L));
                                        gsl_complex w4 = gsl_complex_add(gsl_complex_mul_real(gsl_complex_add(w2, w22), BasisElasticity[0][1]), gsl_complex_mul_real(w3, BasisElasticity[0][0]));
                                        BCjL = gsl_complex_add(w4, gsl_matrix_complex_get(Boundaries, j+5, L));
                                        gsl_matrix_complex_set(Boundaries, j+5, L, BCjL);

                                    }
                                }
                            }

                            // warunek równości wychyleń na granicy ośrodków
                            gsl_matrix_complex_set(Boundaries, j+6, L, gsl_matrix_complex_get(ChosenVectors, i, L));
                            gsl_matrix_complex_set(Boundaries, j+7, L, gsl_matrix_complex_get(ChosenVectors, i+1, L));
                            gsl_matrix_complex_set(Boundaries, j+8, L, gsl_matrix_complex_get(ChosenVectors, i+2, L));

                        }
                        S=S_prim;
                    }
                }

                //skalowanie macierzy Boundaries
                gsl_complex scale=gsl_complex_rect(pow(10, factor), 0);
                gsl_matrix_complex_scale(Boundaries, scale);

                //obliczenie wyznacznika z Boundaries
                gsl_permutation *Bpermutation = gsl_permutation_alloc(EigValNumber);
                int Bsignum;
                gsl_linalg_complex_LU_decomp(Boundaries, Bpermutation, &Bsignum);
                double DetVal = gsl_linalg_complex_LU_lndet(Boundaries);

                //usuwanie NaN
                if(DetVal != DetVal) DetVal = 0;

                //zapisanie wartości do pliku
                plik << k_zred << "\t" << w << "\t" << DetVal << "\n";

            }
            plik << "\n";
        }

    }

    plik.close();
    gsl_matrix_free(gammaA);
    gsl_matrix_free(gammaB);
    gsl_vector_free(BBeta);
    gsl_vector_free(StrBeta);
    gsl_matrix_free(gammaC);
    gsl_matrix_free(gammaD);
    gsl_vector_complex_free(StrAlpha);
    gsl_vector_complex_free(BAlpha);
    gsl_eigen_genv_free(wspce);
        gsl_eigen_genv_free(wspce2);
    gsl_matrix_complex_free(Boundaries);
    gsl_matrix_complex_free(ChosenVectors);
    gsl_vector_complex_free(ChosenValues);

}