Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 Не выводится столбец ошибок в текстовый файл при реализации модели изинга  [new]
DaniilNakhodka
Member

Откуда:
Сообщений: 2
Здравствуйте! Помогите, пожалуйста, найти ошибку в коде. При выполнении программы создается текстовый документ(вообще 3, но интересуют только два из них, Efull.txt и M.txt) и туда записывается, например, в Efull.txt, столбец значений T, столбец Efull и третий столбец с ошибками. Первые два столбца вроде как заполняются нормально, а третий заполнен каждый раз нулями. Это лабораторная работа в универе, сравнивал с другими работами, с готовыми, там все примерно то же самое, но файлы правильно заполняются. Уже много разных изменений в код добавлял, но ничего не меняется. Ошибка вычисляется в функции double er(double *xi, double x) строка 112. Вызов функции происходит в строках 182 и 186, а печать в файл - 184 и 188.

#include <iostream>
#include <cstdlib>
#include <math.h>
#include <fstream>
#include <cmath>
#include <ctime>
using namespace std;

void array(int n, int **arr)
{
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			arr[i][j]=rand()%2;
			if(arr[i][j]==0)
			{
				arr[i][j]=-1;
			}
			cout<<arr[i][j]<<"\t";
		}
		cout<<endl;
	}
}

void sosedi(int i, int j, int n, int *s, int **arr)
{
	if(i==0)
    {
    	s[0]=arr[n-1][j];
    }
    else
    {
	    s[0]=arr[i-1][j];
    }
    if(i==n-1)
    {
    	s[1]=arr[0][j];
    }
    else
    {
	    s[1]=arr[i+1][j];
    }
    if(j==0)
    {
	    s[2]=arr[i][n-1];
    }
    else
    {
	    s[2]=arr[i][j-1];
    }
    if(j==n-1)
    {
	    s[3]=arr[i][0];
    }
    else
    {
	    s[3]=arr[i][j+1];
    }
}

double e1sp(int i, int j, int n, int **arr)
{
    double sum=0.0;
    int s[4];
    sosedi(i, j, n, s, arr);
    for(int a=0; a<4; a++)
    {
    	sum+=arr[i][j]*s[a];
    }
    return (-1)*sum;
}

double poles(int n, int **arr)
{
	double sum=0.0;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			sum+=e1sp(i, j, n, arr);
		}
	}
	return sum/(n*n);
}

double sreden(int n, int **arr)
{
	return poles(n, arr)/(n*n);
}

double namag(int n, int **arr)
{
	double sum=0.0;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			sum+=arr[i][j];
		}
	}
	return fabs(sum/(n*n));
}

double tepl(double Esum1, double Esum2, double T){
	double Esr=0, Esrkv=0;
    Esr=Esum1/10;
    Esrkv=Esum2/10;
    return (Esrkv-(Esr*Esr))/(T*T);
}

double er(double *xi, double x){
    x/=10;
    double sum=0;
    for (int i=0; i<10; i++)
	{
        sum+=(xi[i]-x)*(xi[i]-x);
    }
    return sqrt((1/9)*sum);
}

int main()
{
	int n=0;
	srand(time(0));
	ofstream Ef, Mf, Cf;
	cout<<"Vvedite n:";
	cin>>n;
	cout<<endl;
	int **arr=new int *[n];
	for (int i=0; i<n; i++)
	{
		arr[i]=new int[n];
	}
	array(n, arr);
	cout<<endl;
	int i=rand()%n;
	int j=rand()%n;
	cout<<"Energia vibrannogo spina="<<e1sp(i, j, n, arr)<<endl;
	cout<<"Energia vsey sistemi="<<poles(n, arr)<<endl;
	cout<<"Namagnichennost vsey sistemi="<<namag(n, arr)<<endl;
	sreden(n, arr);
	double T, Efull=0.0, M=0.0, C=0.0, Esum1=0.0, Esum2=0.0;
	double Estep[10], Mstep[10], Cstep[10];
	double Msum=0.0, Csum=0.0;
	double Emist=0.0, Mmist=0.0, Cmist=0.0;
    Ef.open("Efull.txt");
	Mf.open("M.txt");
	Cf.open("C.txt");
	for(T = 0.01; T<4; T+=0.1)
	{
		for(int step=0; step<10; step++)
		{
			for(long int MK=0; MK<100000; MK++)
			{
	            double E1=0.0, E2=0.0, p=0.0, slch=0.0;
	        	int i=rand()%n;
	            int j=rand()%n;
	            E1=e1sp(i, j, n, arr);
	            arr[i][j]=(-1)*arr[i][j];
	            E2=e1sp(i, j, n, arr);
	            if(E2>=E1)
	            {
	            	p=exp(((-1)*(E2-E1))/T);
		            p*=100;
		            slch=rand()%101;
	            	if(p>=slch)
	            	{
	            		arr[i][j]=(-1)*arr[i][j];
		    		}
		    	}			 
		    }
		    Efull=poles(n, arr);
            Estep[step]=Efull;
            Esum1+=Efull;
            Esum2+=(Efull*Efull);
            Mstep[step]=namag(n, arr);
            Msum+=Mstep[step];
		}
		cout<<"T="<<T<<endl;
		Efull=poles(n, arr);
		Emist=er(Estep, Esum1);
		cout<<"E(T)="<<Efull<<endl;
		Ef<<T<<"\t"<<Efull<<"\t"<<Emist<<endl;
		M=namag(n, arr);
		Mmist=er(Mstep, Msum);
		cout<<"M(T)="<<M<<endl;
		Mf<<T<<"\t"<<M<<"\t"<<Mmist<<endl;
		C=tepl(Esum1, Esum2, T);
		cout<<"C(T)="<<C<<endl;
		Cf<<T<<"\t"<<C<<endl;
	}
    for(int i=0; i<n; i++)
	{
		delete[] arr[i];	
	} 
    delete[] arr;
    Ef.close();
    Mf.close();
    Cf.close();
}
19 мар 21, 15:59    [22297382]     Ответить | Цитировать Сообщить модератору
 Re: Не выводится столбец ошибок в текстовый файл при реализации модели изинга  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 52921

DaniilNakhodka
return sqrt((1/9)*sum);

Скобки неправильно поставлены. 1/9 всегда равно 0. Отсюда и твои нули.

Posted via ActualForum NNTP Server 1.5

19 мар 21, 16:16    [22297387]     Ответить | Цитировать Сообщить модератору
 Re: Не выводится столбец ошибок в текстовый файл при реализации модели изинга  [new]
White Owl
Member

Откуда:
Сообщений: 12682
А еще полезно писать 1.0 вместо 1, когда надо работать с float/double.
С точки зрения математики оно без разницы, и чаще всего компилятор это самостоятельно будет делать.

Но во первых, тебе самому будет проще потом понимать работаешь ты с целыми числами или (потенциально) дробными.

А во вторых, иногда компилятор может ошибиться. Например:
for(int i=0; i<10; i++) {
    double x = i/2;
    double y = i/2.0;
    cout << "x=" << x << "   y=" << y << endl;
}
20 мар 21, 04:35    [22297600]     Ответить | Цитировать Сообщить модератору
 Re: Не выводится столбец ошибок в текстовый файл при реализации модели изинга  [new]
DaniilNakhodka
Member

Откуда:
Сообщений: 2
Спасибо вам обоим, сделал вот так и получилось:

    double m=sum*0.11111111111;
    return sqrt(m);


Это вместо тех строк.
Теперь ошибка с графиками, тоже много всего с кодом перепробовал делать, на фото ниже самое лучшее, что получилось, но все равно не то. Посмотрите, пожалуйста, что может быть не так. Надо по выведенным в файлы значения построить графики в gnumplot и у меня получается так:
https://ibb.co/NNPLK7V
https://ibb.co/YZ746yn
https://ibb.co/dgT2DXH
https://ibb.co/hdJtDwP
https://ibb.co/8ryzMh6

А должно быть так:
https://ibb.co/S63mFM1
https://ibb.co/sjqyKnY
https://ibb.co/RhP3GZ1

Также, если кто знает, напишите, пожалуйста, как одновременно в gnuplot выводить 2 графика(lines и yerrorbars). На первых фото показан нужный мне вариант, а на моих все раздельно. Прописывал в gnuplot: plot "Путь к текстовому файлу" using 1:2:3 with lines/yerrorbars, но выводится только что-то одно, либо lines либо yerrorbars.

Сейчас код, с учетом всех последних изменений выглядит так:

#include <iostream>
#include <cstdlib>
#include <math.h>
#include <fstream>
#include <cmath>
#include <ctime>
using namespace std;

void array(int n, int **arr)
{
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			arr[i][j]=1;
			cout<<arr[i][j]<<"\t";
		}
		cout<<endl;
	}
}

void sosedi(int i, int j, int n, int *s, int **arr)
{
	if(i==0)
    {
    	s[0]=arr[n-1][j];
    }
    else
    {
	    s[0]=arr[i-1][j];
    }
    if(i==n-1)
    {
    	s[1]=arr[0][j];
    }
    else
    {
	    s[1]=arr[i+1][j];
    }
    if(j==0)
    {
	    s[2]=arr[i][n-1];
    }
    else
    {
	    s[2]=arr[i][j-1];
    }
    if(j==n-1)
    {
	    s[3]=arr[i][0];
    }
    else
    {
	    s[3]=arr[i][j+1];
    }
}

double e1sp(int i, int j, int n, int **arr)
{
    double sum=0.0;
    int s[4];
    sosedi(i, j, n, s, arr);
    for(int a=0; a<4; a++)
    {
    	sum+=arr[i][j]*s[a];
    }
    return (-1)*sum;
}

double poles(int n, int **arr)
{
	double sum=0.0;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			sum+=e1sp(i, j, n, arr);
		}
	}
	return sum/(n*n);
}

double sreden(int n, int **arr)
{
	return poles(n, arr)/(n*n);
}

double namag(int n, int **arr)
{
	double sum=0.0;
	for(int i=0; i<n; i++)
	{
		for(int j=0; j<n; j++)
		{
			sum+=arr[i][j];
		}
	}
	return fabs(sum/(n*n));
}

double tepl(double Esum1, double Esum2, double T){
	double Esr=0.0, Esrkv=0.0;
    Esr=Esum1/10;
    Esrkv=Esum2/10;
    double t=(Esrkv-(Esr*Esr))/(T*T);
    return t;
}

double er(double *xi, double x){
    x/=10.0;
    double sum=0.0;
    for (int i=0; i<10; i++)
	{
        sum+=(xi[i]-x)*(xi[i]-x);
    }
    double m=sum*0.11111111111;
    return sqrt(m);
}

int main()
{
	int n=0;
	ofstream Ef, Mf, Cf;
	cout<<"Vvedite n:";
	cin>>n;
	cout<<endl;
	int **arr=new int *[n];
	for (int i=0; i<n; i++)
	{
		arr[i]=new int[n];
	}
	array(n, arr);
	cout<<endl;
	int i=rand()%n;
	int j=rand()%n;
	cout<<"Energia vibrannogo spina="<<e1sp(i, j, n, arr)<<endl;
	cout<<"Energia vsey sistemi="<<poles(n, arr)<<endl;
	cout<<"Namagnichennost vsey sistemi="<<namag(n, arr)<<endl;
	sreden(n, arr);
	double T, C=0.0, Esum1=0.0, Esum2=0.0;
	double Est[10], Mst[10];
	double Msum=0.0, Csum=0.0;
    Ef.open("Efull.txt");
	Mf.open("M.txt");
	Cf.open("C.txt");
	for(T = 0.01; T<4; T+=0.1)
	{
		for(int i=0; i<10; i++)
		{
			for(long int MK=0; MK<100000; MK++)
			{
				double E1=0.0, E2=0.0, p=0.0, slch=0.0;
	        	int i=rand()%n;
	            int j=rand()%n;
	            E1=e1sp(i, j, n, arr);
	            arr[i][j]=(-1)*arr[i][j];
	            E2=e1sp(i, j, n, arr);
	            if(E2>=E1)
	            {
	            	p=exp(((-1)*(E2-E1))/T);
		            slch=(double)rand()/(double)RAND_MAX;
	            	if(slch>p)
	            	{
	            		arr[i][j]=(-1)*arr[i][j];
		    		}
		    	}			 
		    }
            Est[i]=poles(n, arr);
            Esum1+=Est[i];
            Esum2+=(Est[i]*Est[i]);
            Mst[i]=namag(n, arr);
            Msum+=Mst[i];
		}
		cout<<"T="<<T<<endl;
		cout<<"E(T)="<<poles(n, arr)<<endl;
		Ef<<T<<"\t"<<poles(n, arr)<<"\t"<<er(Est, Esum1)<<endl;
		cout<<"M(T)="<<namag(n, arr)<<endl;
		Mf<<T<<"\t"<<namag(n, arr)<<"\t"<<er(Mst, Msum)<<endl;
		C=tepl(Esum1, Esum2, T);
		cout<<"C(T)="<<C<<endl;
		Cf<<T<<"\t"<<C<<endl;
	}
    for(int i=0; i<n; i++)
	{
		delete[] arr[i];	
	} 
    delete[] arr;
    Ef.close();
    Mf.close();
    Cf.close();
}


Массив специально генерируется только из единиц со знаком +, без -1, так советовал препод. Однако что с -1, что без -1, разницы особой нет, проверял.

Сообщение было отредактировано: 20 мар 21, 09:27
20 мар 21, 09:26    [22297618]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить