Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.11.2012, 15:43
Басота Басота вне форума
Прохожий
 
Регистрация: 28.11.2012
Адрес: Киев
Сообщения: 6
Версия Delphi: Delphi 2010
Репутация: 10
Печаль Результат вычислений равен NaN

Всем доброго дня. Подскажите мне, пожалуйста, в чем может быть проблема. Решаю задачу Пуассона для двумерного пространства. Программа н-ое количество раз делает вычисления правильно, на на (н+1) разе получаю ошибку (error = Nan). Ошибка возникает в этом месте кода:
for i := 2 to n1 - 1 do
begin
for j := 1 to m1 do ui[j] := Unew[i, j];
Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1);
for j := 1 to m1 do unew1[i, j] := ui[j];
end;
Когда использовал assignfile(output, 'гoutput.txt'); rewrite(output); write(output, ui [j]); closefile(output), то в массиве ui были значения NaN. Сама функция Prog мне недоступна, поскольку ее дал мне преподаватель и она, по его словам, работает отлично. Он сказал, что, возможно, проблема связана с использованием глобальных переменных i, j, что они принимают значения, для которых массив не создавался.
ProgInit(ui, n); - создания одномерного массива n-ого размера
getmem1(y, sizeoffloat, m); - создания одномерного массива m -ого размера
getmem1(x, sizeoffloat, n); - создания одномерного массива n-ого размера
getmem2(u, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(Unew, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(unew1, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера
getmem2(Func, sizeoffloat, n, m); - создания двумерного массива n х m -ого размера

Ну а это соответственно очистка массивов
Freemem1(y, sizeoffloat, m);
Freemem1(x, sizeoffloat, n);
Freemem2(u, sizeoffloat, n, m);
Freemem2(Unew, sizeoffloat, n, m);
Freemem2(Unew1, sizeoffloat, n, m);
Freemem2(Func, sizeoffloat, n, m);
ProgFree(ui, n);

Ехе файл во вложениях

Код:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;

type
  TForm3 = class(TForm)
    Image1: TImage;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    Label2: TLabel;
    Edit2: TEdit;
    Label3: TLabel;
    Edit3: TEdit;
    Label4: TLabel;
    Edit4: TEdit;
    Label5: TLabel;
    Edit5: TEdit;
    Label6: TLabel;
    Edit6: TEdit;
    Label7: TLabel;
    Edit7: TEdit;
    Label8: TLabel;
    Label9: TLabel;
    Edit8: TEdit;
    Label10: TLabel;
    Edit9: TEdit;
    Label11: TLabel;
    Edit10: TEdit;
    Label12: TLabel;
    Edit11: TEdit;
    Label13: TLabel;
    Edit12: TEdit;
    Label14: TLabel;
    Edit13: TEdit;
    Label15: TLabel;
    Edit14: TEdit;
    Label16: TLabel;
    Edit15: TEdit;
    Label17: TLabel;
    Edit16: TEdit;
    Label18: TLabel;
    Edit17: TEdit;
    Label19: TLabel;
    Edit18: TEdit;
    CheckBox1: TCheckBox;
    Memo1: TMemo;
    Label20: TLabel;
    CheckBox2: TCheckBox;
    CheckBox3: TCheckBox;
    CheckBox4: TCheckBox;
    CheckBox5: TCheckBox;
    ProgressBar1: TProgressBar;
    Button1: TButton;
    Label21: TLabel;
    Edit19: TEdit;
    Label22: TLabel;
    Edit20: TEdit;
    Label23: TLabel;
    Edit21: TEdit;
    Label24: TLabel;
    Edit22: TEdit;
    Label25: TLabel;
    Edit23: TEdit;
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  var
  Form3: TForm3;
implementation
uses typedef, arrdef, progon;
{$R *.dfm}
var
  pixelMaxx, pixelMaxy: word;
  i,j: word;
  x0gr, y0gr, xgr, ygr, dx, dy: float;
  TimeStr, Date1: TdateTime;
  num: byte;
  gizoline: float;
  error: float;

var
  u, Unew, unew1, Func: arr2ptr;
  x, y: arr1ptr;
  A, B, C, D: float;
  dt, k: float;
  ui: arr1ptr;
  {$I izoline}

// -------------------------------------------------------------------------------
procedure coef1(j: word; var a, b, c, d: float; w, w1: float);
begin
  A := k * dt / sqr(dx);
  C := A;
  B := -(2 * A + 2 * k * dt / sqr(dy) + 1);
  D := -u[i, j] - dt * k * (Unew[i + 1, j] + Unew[i - 1, j]) / sqr(dy) - dt * Func[i, j];
end;


procedure Progonka2D(leftx1, lefty1, rightx1, righty1, n1, m1, k21, k31, k41, k51: integer);
var
  error1:float;
begin

for i := 2 to n1 - 1 do
  begin
    for j := 1 to m1 do  ui[j] := Unew[i, j];
    Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1);
    for j := 1 to m1 do unew1[i, j] := ui[j];
  end;

  error := 0;
  for i := leftx1 to rightx1 do  for j := lefty1 to righty1 do
    begin
      error1 := abs(unew1[i, j] - Unew[i, j]);
      if error <= error1 then  error := error1;
    end;

  for i := 2 to n1 - 1 do for j := 2 to m1-1 do
      Unew[i, j] := unew1[i, j];

  if (k21 = 1) then    for j := 1 to m1 do
      Unew[1, j] := Unew[2, j];

  if (k31 = 1) then    for j := 1 to m1 do
      Unew[n1, j] := Unew[n1 - 1, j];

  if (k41 = 1) then    for i := 1 to n1 do
      Unew[i, 1] := Unew[i, 2];

  if (k51 = 1) then    for i := 1 to n1 do
      Unew[i, m1] := Unew[i, m1 - 1];

  for i := 1 to n1 do for j := 1 to m1 do  u[i, j] := Unew[i, j];

end;
//----------------------------------------------------------------------------------------

procedure TForm3.Button3Click(Sender: TObject);
var
  k2, k3, k4, k5: integer;
  iii, jjj, kk: integer;
  Koef: float;
  Stat: integer;
  nitr: integer;
m,n:integer;

  liva, prava, nyznja, verxnja, seredyna: float;
  leftx, lefty, rightx, righty: integer;

begin
  TimeStr := time;
  pixelMaxx := 300;
  pixelMaxy := 300;
  KodGr := 1;
  MaxColor := 1000;
  ColorMode := 1;
  x0gr := 0.02;
  y0gr := 0.02;
  xgr := 0.98;
  ygr := 0.98;
  num := 10;
  gizoline := 1;
  Edit13.Clear;
  Edit14.Clear;
  Edit19.Clear;
  Edit20.Clear;
  Edit21.Clear;
  Edit22.Clear;
  Edit23.Clear;
  Image1.Picture := nil;
  n := StrToInt(Edit1.Text);
  leftx := StrToInt(Edit15.Text);
  lefty := StrToInt(Edit16.Text);
  rightx := StrToInt(Edit17.Text);
  righty := StrToInt(Edit18.Text);
  m := StrToInt(Edit2.Text);
  k := StrToFloat(Edit3.Text);
  Koef := StrToFloat(Edit4.Text);
  liva := StrToFloat(Edit8.Text);
  prava := StrToFloat(Edit9.Text);
  nyznja := StrToFloat(Edit10.Text);
  verxnja := StrToFloat(Edit11.Text);
  seredyna := StrToFloat(Edit12.Text);
  dt := 0.001 * StrToFloat(Edit6.Text);
  // --------------------------------
  dx := 1 / (n - 1);
  dy := 1 / (m - 1);
  ProgInit(ui, n);
  getmem1(y, sizeoffloat, m);
  getmem1(x, sizeoffloat, n);
  getmem2(u, sizeoffloat, n, m);
  getmem2(Unew, sizeoffloat, n, m);
  getmem2(unew1, sizeoffloat, n, m);
  getmem2(Func, sizeoffloat, n, m);

  x[1] := 0;
  for iii := 1 to n - 1 do x[iii + 1] := x[iii] + dx;

  y[1] := 0;
  for jjj := 1 to m - 1 do  y[jjj + 1] := y[jjj] + dy;

  for iii := 1 to n do    for jjj := 1 to m do
      Func[iii, jjj] := Koef * (sqr(x[iii]) + sqr(y[jjj]));

  for iii := 2 to n - 1 do   for jjj := 2 to m - 1 do
      u[iii, jjj] := seredyna;

  for jjj := 1 to m do   u[1, jjj] := liva;
  for jjj := 1 to m do   u[n, jjj] := prava;
  for iii := 1 to n do   u[iii, 1] := nyznja;
  for iii := 1 to n do   u[iii, m] := verxnja;

  for iii := 1 to n do   for jjj := 1 to m do
      Unew[iii, jjj] := u[iii, jjj];
  for iii := 1 to n do   for jjj := 1 to m do
      unew1[iii, jjj] := u[iii, jjj];

  if ((CheckBox2.Checked = False) and (CheckBox3.Checked = False) and
      (CheckBox4.Checked = False) and (CheckBox5.Checked = False)) then
    kk := 0
  else
    kk := 1;

  { условия Дирихле}
  if (CheckBox2.Checked = True) then     k2 := 1;
  if (CheckBox3.Checked = True) then     k3 := 1;
  if (CheckBox4.Checked = True) then     k4 := 1;
  if (CheckBox5.Checked = True) then     k5 := 1;

  nitr := 0;
  Stat:= 0;

  repeat
    Stat:=Stat+1;
    nitr := nitr + 1;
    Progonka2D(leftx, lefty, rightx, righty, n, m, k2, k3, k4, k5);

    

    Edit13.Text := IntToStr(nitr);
    Edit19.Text := FloatToStr(error);
    Application.ProcessMessages;

        if (Stat>100) then Stat:=0;
        ProgressBar1.Position:=Stat;

  until (error < 0.00001);
    // очищаем память
 Freemem1(y, sizeoffloat, m);
 Freemem1(x, sizeoffloat, n);
 Freemem2(u, sizeoffloat, n, m);
 Freemem2(Unew, sizeoffloat, n, m);
 Freemem2(Unew1, sizeoffloat, n, m);
 Freemem2(Func, sizeoffloat, n, m);
 ProgFree(ui, n);

  Edit13.Text := IntToStr(nitr);
  Edit14.Text := IntToStr(kk);
  Edit20.Text := IntToStr(k2);
  Edit21.Text := IntToStr(k3);
  Edit22.Text := IntToStr(k4);
  Edit23.Text := IntToStr(k5);
  Date1 := time - TimeStr;
  Edit7.Text := TimeToStr(Date1);
end;
end.






Вложения
Тип файла: zip Project2.zip (403.4 Кбайт, 1 просмотров)
Ответить с цитированием
  #2  
Старый 28.11.2012, 15:54
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Басота
Он сказал, что, возможно, проблема связана с использованием глобальных переменных i, j, что они принимают значения, для которых массив не создавался.
Во-первых, да, переменные для циклов for делай всегда локальными (в той же процедуре где и сами циклы).
Во-вторых не нужно пытаться экономить на переменных цикла, объявляй их не как word, а как Integer.
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Басота (28.11.2012)
  #3  
Старый 28.11.2012, 16:08
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

И в третьих - а массивы должны индексироваться с нуля или с единицы?
Как объявлены arr1ptr и arr2ptr?
Ответить с цитированием
  #4  
Старый 28.11.2012, 16:29
Басота Басота вне форума
Прохожий
 
Регистрация: 28.11.2012
Адрес: Киев
Сообщения: 6
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Во-первых, да, переменные для циклов for делай всегда локальными (в той же процедуре где и сами циклы).
Во-вторых не нужно пытаться экономить на переменных цикла, объявляй их не как word, а как Integer.

Спасибо, но проблема с глобальными/локальными переменными связана с
procedure coef1(j: word; var a, b, c, d: float; w, w1: float);
поскольку в этой процедуре я вычисляю коэффициенты А,В,С, Д.
Как мне, не используя глобальные переменные i,j найти эти коэффициенты? Массивы u, Unew, unew1, Func, ui у меня глобальные. Неужели мне нужно будет не использовать функцию Prog, процедуру coef1, а самостоятельно запрограммировать метод прогонки?
Ответить с цитированием
  #5  
Старый 28.11.2012, 16:31
Басота Басота вне форума
Прохожий
 
Регистрация: 28.11.2012
Адрес: Киев
Сообщения: 6
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от icWasya
И в третьих - а массивы должны индексироваться с нуля или с единицы?
Как объявлены arr1ptr и arr2ptr?

С единицы. Массивы типу arr1ptr, arr2ptr начинаются с единицы (не с нуля). Этот тип массива дал нам преподаватель.
Ответить с цитированием
  #6  
Старый 28.11.2012, 16:42
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Басота
Спасибо, но проблема с глобальными/локальными переменными связана с
procedure coef1(j: word; var a, b, c, d: float; w, w1: float);
поскольку в этой процедуре я вычисляю коэффициенты А,В,С, Д.
Как мне, не используя глобальные переменные i,j найти эти коэффициенты?
А здесь у тебя вообще что-то чудное.
Код:
procedure coef1(j: word; var a, b, c, d: float; w, w1: float);
.....
for i := 2 to n1 - 1 do
  begin
    for j := 1 to m1 do  ui[j] := Unew[i, j];
    Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1); // Где у тебя здесь присваивается значение переменной j для процедуры coef1?
    for j := 1 to m1 do unew1[i, j] := ui[j];
  end;
.....
Ответить с цитированием
  #7  
Старый 28.11.2012, 17:00
Басота Басота вне форума
Прохожий
 
Регистрация: 28.11.2012
Адрес: Киев
Сообщения: 6
Версия Delphi: Delphi 2010
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
А здесь у тебя вообще что-то чудное.
Код:
procedure 
    Prog(1, m1, ui, 1, ui[1], 0, 1, ui[m1], 0, 1, 0, coef1); // Где у тебя здесь присваивается значение переменной j для процедуры coef1?
  .....

Код:
1, m1
Первое число - минимальное значение j, второе - максимальное.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 05:12.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025