Recent

Author Topic: Equation in Lazarus  (Read 11190 times)

ninaAU

  • New member
  • *
  • Posts: 9
Equation in Lazarus
« on: October 20, 2014, 12:13:50 pm »
Hi.
How do I get a loop in Delphi, which reads two equations that depend on each other, writes the data into a memo and make a graph of this data?
I have created variables and have defined them within the loop begins. My variables are Integers and doubles.
The code I have so far looks like this:

procedure TForm1.btnOpenClick(Sender: TObject);
var
  BioCon, SubCon Biomass, Substrat: double;
  time, dtime: integer;
begin
  BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*10^-5 * (Substrat/(10 + Substrat) * Biomass ) * dtime;
end;

What kind of loop do I have to use?

The equations looks original like this:
Xb(t+∆t) = Xb(t)+(μ * (Ss(t)/(Ks+Ss(t))  * Xb(t)- b*Xb(t)) * ∆t

Ss(t+∆t) = Ss(t) + ((-1/Y)* μ *(Ss(t)/(Ks+Ss(t))  *Xb(t)) * ∆t

Xb is the biomass concentration and Ss is substrate concentration.
The rest are constants.
« Last Edit: October 20, 2014, 12:35:59 pm by ninaAU »

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Delphi
« Reply #1 on: October 20, 2014, 12:30:20 pm »
This is a Lazarus/fpc forum, not a Delphi forum.  Before anyone answers, can you confirm if it's definitely Delphi you're interested in? 

(Suspect the Lazarus/fpc answer will involve TAChart, and I've no idea how Delphi compatible that is...)
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

ninaAU

  • New member
  • *
  • Posts: 9
Re: Equation in Delphi
« Reply #2 on: October 20, 2014, 12:38:21 pm »
This is a Lazarus/fpc forum, not a Delphi forum.  Before anyone answers, can you confirm if it's definitely Delphi you're interested in? 

(Suspect the Lazarus/fpc answer will involve TAChart, and I've no idea how Delphi compatible that is...)

Hi, i'm sorry. I'm using Lazarus. But I have learned to use Lazarus with a book called Introducing two Delphi Programming.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Lazarus
« Reply #3 on: October 20, 2014, 12:50:53 pm »
OK, so a Lazarus/fpc based solution will do you nicely :-)

I'm not the person for a clear answer - way too long since I did any graphing.  But to answer your question, looks to me like you need to loop dtime.

Assuming dtime is in seconds...

Code: [Select]
for dtime := 0 to 3600 do  // ie, one hour's worth of data
begin
  BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*10^-5 * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  // Add (dtime, BioCon) to graph as series 1
  // Add (dtime, SubCon) to graph as series 2
end;

The control to do the graphing should be TAChart.  Read up here...
http://wiki.lazarus.freepascal.org/TAChart

There's only slightly less than a LOT of examples available for you :-)  In addition to all the tutorials available on the wiki, in Lazarus you can do the following:

  Project - Close Project
  Click "View Example Projects"
  In the Projects filter type "TAChart". 
  Select the one you want (as you browse you will see a description of each project), and click "Open First Selected"

Good luck :-)
« Last Edit: October 20, 2014, 12:52:28 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

ninaAU

  • New member
  • *
  • Posts: 9
Re: Equation in Lazarus
« Reply #4 on: October 20, 2014, 12:58:40 pm »
OK, so a Lazarus/fpc based solution will do you nicely :-)

Thanks for the quick reply, I will try.

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Equation in Lazarus
« Reply #5 on: October 20, 2014, 01:24:44 pm »
This looks like two coupled differential equations - it's been a long time...

At first, I think, you need the initial conditions, i.e. Xb and Ss at time zero, t=0.  Select a reasonable value of delta t, maybe 1 second (it must be smaller than the typical time scale of that reaction). You use these values and apply them to the given formulas. From this calculation you will get Xb and SS for t=1 (second). Then apply these values for Xb(t) and Ss(t) in the equations --> you'll get a new Xb and Ss, now for t = 2 seconds. Run this loop as long as needed, maybe until t=1000. In every cycle store the results for the given t in an array.

ninaAU

  • New member
  • *
  • Posts: 9
Re: Equation in Lazarus
« Reply #6 on: October 20, 2014, 01:54:02 pm »
This looks like two coupled differential equations - it's been a long time...

At first, I think, you need the initial conditions, i.e. Xb and Ss at time zero, t=0.  Select a reasonable value of delta t, maybe 1 second (it must be smaller than the typical time scale of that reaction). You use these values and apply them to the given formulas. From this calculation you will get Xb and SS for t=1 (second). Then apply these values for Xb(t) and Ss(t) in the equations --> you'll get a new Xb and Ss, now for t = 2 seconds. Run this loop as long as needed, maybe until t=1000. In every cycle store the results for the given t in an array.

Can I use a If loop? If t < 1000 do ...   ??

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Lazarus
« Reply #7 on: October 20, 2014, 02:00:00 pm »
No such thing as an If loop.

There's a For loop (which is in the example I gave above) or you can use Repeat ..Until or While Do...

For handles incrementing for you.  With Repeat or While, you have to handle the incrementing...

For all three loops, you CAN use an IF to force an early break, but I think all you need is a For loop...

Original For Loop
Code: [Select]
for dtime := 0 to 3600 do  // ie, one hour's worth of data
begin
  BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*10^-5 * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  // Add (dtime, BioCon) to graph as series 1
  // Add (dtime, SubCon) to graph as series 2
end;

As a while loop

Code: [Select]
dtime := 0;
while (dtime <= 3600) do
begin
  BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*10^-5 * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  // Add (dtime, BioCon) to graph as series 1
  // Add (dtime, SubCon) to graph as series 2

 dtime := dtime + 1;
end;

As a Repeat loop

Code: [Select]
dtime := 0;
Repeat
  BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*10^-5 * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  // Add (dtime, BioCon) to graph as series 1
  // Add (dtime, SubCon) to graph as series 2

  dTime := dTime + 1;
Until dTime>3600; // <--- NOTE, the condition for break is different to the while loop, it's opposite

UPDATE:

Doh!  None of these three will compile - my fault for copy/pasting the original code :-)

Code: [Select]
BioCon := Biomass + (7*10^-5 * (Substrat/(10+Substrat)) * Biomass - 7*10^-6) * dtime;
^ doesn't do what you think it does...  You need, errr, power()?

Working on the For Loop only....

Code: [Select]
Uses
  Math;

...

for dtime := 0 to 3600 do  // ie, one hour's worth of data
begin
  BioCon := Biomass + (7*power(10, -5) * (Substrat/(10+Substrat)) * Biomass - 7*power(10, -6)) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*power(10, -5) * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  // Add (dtime, BioCon) to graph as series 1
  // Add (dtime, SubCon) to graph as series 2
end;
« Last Edit: October 20, 2014, 02:08:46 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

ninaAU

  • New member
  • *
  • Posts: 9
Re: Equation in Lazarus
« Reply #8 on: October 20, 2014, 02:16:04 pm »
For handles incrementing for you.  With Repeat or While, you have to handle the incrementing...

Where is the data ended? I need to put it in a memo and save the data in textfile.

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Lazarus
« Reply #9 on: October 20, 2014, 02:27:20 pm »
Where is the data ended?

The data is bounded by either the conditions in the Repeat or While loops, or by the For loop itself.

In all three examples, it cycles through dtime starting at 0, and ending at 3600.  Study each of the three examples, looking for 3600, and you'll see how the end is determined.

I need to put it in a memo and save the data in textfile.

Apologies, I thought you wanted it graphing...

Drop a TMemo on your form.  For this code, I'm assuming you leave it's .Name property as Memo1.  If you've changed the name, just adjust the code accordingly.  You may also need to resize the memo so that all this data fits.  For now, just resize using the Form Designer.

Code: [Select]
Memo1.Lines.Clear;
for dtime := 0 to 3600 do  // ie, one hour's worth of data
begin
  BioCon := Biomass + (7*power(10, -5) * (Substrat/(10+Substrat)) * Biomass - 7*power(10, -6)) * dtime;
  SubCon := Substrat + ((-1/0.60)* 7*power(10, -5) * (Substrat/(10 + Substrat) * Biomass ) * dtime;
 
  Memo1.Lines.Add(Format('(dtime, BioConn)=(%d, %.2f)', [dtime, BioCon]));
  Memo1.Lines.Add(Format('(dtime, SubCon)=(%d, %.2f)', [dtime, SubCon]));
end;

Memo1.Lines.SaveToFile('C:\MyFile.txt');

I'm going to guess you want the output in a specific format.  Just modify the two Memo1.Lines.Add until you get what you want...
« Last Edit: October 20, 2014, 02:29:57 pm by Mike.Cornflake »
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Equation in Lazarus
« Reply #10 on: October 20, 2014, 02:32:14 pm »
Mike, I think dtime should essentially be constant, it is the step width how the calculation progresses in time. The main interest is in the time itself, therefore, the loop variable must be t.

Assuming BioMass and Substrat begin with BIOMASS0 and SUBSTRAT0 at t=0, then the calculation should be like this:

Code: [Select]
const
  dtime = 1;  // 1 second
  tMax = 3600;  // 1 hour
var
  t, biomass, substrat: array of double;
  i, n: Integer;
begin
  // Number of data points expected
  n := round(tmax/dtime) + 1;

  // Dimension the result arrays
  SetLength(t, n);  // not absolutely necessary, but needed if you want to increase dtime once the reaction gets slower
  SetLength(biomass, n);
  SetLength(substrat,n);

  // Initial value of solution (t=0)
  t[0] := 0;
  biomass[0] := BIOMASS0;  // you have to know these numbers!
  substrat[0] := SUBSTRAT0;

  // Progress time steps
  i:= 1;
  while (i < n) do begin
    // Your calculations: Data at index i-1 are for the previous time step (t)
    // Data at the next time step (t + dTime) will have index i 
    t[i] := t[i-1] + dTime;
    biomass[i] := biomass[i-1] + (7*10^-5 * (Substrat[i-1]/(10+Substrat[i-1])) * Biomass[i-1] - 7*10^-6) * dtime;   
    substrat[i] := Substrat[i-1] + ((-1/0.60)* 7*10^-5 * (Substrat[i-1]/(10 + Substrat[i-1]) * Biomass[i-1] ) * dtime;
    inc(i);
  end;

To populate the memo take the results and convert them to strings which you add to the memo's Lines. Maybe like this:

Code: [Select]
var
  s: String;
...
  for i:=0 to n-1 do begin
    s := 'Time: ' + FloatToStr(t[i]) + ': Biomass = ' + FloatToStr(biomass[i]) +
      + ', Substrate = ' + FloatToStr(substrat[i]);
    Memo1.Add(s);
  end;

But I'm gonna stop now - I don't want to do all your homework... As for creation of a chart from data arrays, you'll find examples in the TAChart tutorials.
« Last Edit: October 20, 2014, 02:42:02 pm by wp »

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Lazarus
« Reply #11 on: October 20, 2014, 02:38:15 pm »
Mike, I think dtime should be constant, it is the step width how the calculation progresses in time. The main interest is in the time itself, therefore, the loop variable will be t.

Yeah, I wondered about the validity of the equation translation as well, but thought that this was mainly just a learning exercise for @ninaAU over how to handle loops.  I sincerely hope we're not doing someone's homework :-)
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

jwdietrich

  • Hero Member
  • *****
  • Posts: 1232
    • formatio reticularis
Re: Equation in Lazarus
« Reply #12 on: October 20, 2014, 02:48:40 pm »
Can I use a If loop? If t < 1000 do ...   ??
If t could be much larger than 1000 or if more complex equations are involved I would recommend to use a for, repeat or while loop within a new thread to keep the GUI responsive as long as the simulation runs.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.2.6 | FPC 3.2.2 | PPC, Intel, ARM | macOS, Windows, Linux

ninaAU

  • New member
  • *
  • Posts: 9
Re: Equation in Lazarus
« Reply #13 on: October 20, 2014, 04:47:18 pm »
Hi,
I've tried to write my code, but it seems that the loop does not quite work. I have one set of data, where the time is 3600 sek. What happened?
I still have not fully understood how these loops work.

Code: [Select]
procedure TfrmBiomass.btnOpenClick(Sender: TObject);
var
  BioCon, SubCon, Biomass, Substrat: double;
  dtime: integer;
  File1: textfile;
begin
   begin
     if frmBiomass.svdSave.Execute then
        begin
        assignfile(File1, frmBiomass.svdSave.FileName);
        rewrite(File1);
        dtime := 1;
        Substrat := 1000;
        Biomass := 1000;
        while (dtime <= 3600) do                   //timelimit
           begin
           BioCon := Biomass + (0.00007 * (Substrat/(10+Substrat)) * Biomass - 0.000007) * dtime;      //define equations
           SubCon := Substrat + ((-1/0.60)* 0.00007 * (Substrat/(10 + Substrat)) * Biomass ) * dtime;
           dtime := dtime + 1;
           end;
        end;
        memData.Lines.Add(FloatToStr(dtime) + '  ' + FloatToStr(BioCon) + '  ' + FloatToStr(SubCon));
        writeln(File1, 'Time: ' + FloatToStr(dtime) + '  Biomass: ' + FloatToStr(BioCon) + '  Substrat: ' + FloatToStr(SubCon));
        closefile(File1);
    end;
end;

Mike.Cornflake

  • Hero Member
  • *****
  • Posts: 1260
Re: Equation in Lazarus
« Reply #14 on: October 20, 2014, 05:05:07 pm »
You're only putting data in memo1 outside of your loop,  not inside.

Move the memo1.lines.add stuff up by two lines so it is inside the loop, that will help.
Lazarus Trunk/FPC Trunk on Windows [7, 10]
  Have you tried searching this forum or the wiki?:   http://wiki.lazarus.freepascal.org/Alternative_Main_Page
  BOOKS! (Free and otherwise): http://wiki.lazarus.freepascal.org/Pascal_and_Lazarus_Books_and_Magazines

 

TinyPortal © 2005-2018