Recent

Author Topic: Problem displaying fePower  (Read 5601 times)

tambok

  • New Member
  • *
  • Posts: 19
Problem displaying fePower
« on: October 18, 2018, 07:36:36 pm »
Halo everyone and Masters,

i have a problem with the fePower Series. my project previously used lz_TAChart.
but after upgrading to Lazarus 1.8.4 with tachartlazaruspkg, fePower cannot be displayed in some cases.

what's the difference between them? 
how can I display it again?

thanks

tbk

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Problem displaying fePower
« Reply #1 on: October 18, 2018, 07:48:29 pm »
Sorry, I don't know how PilotLogic modfied TAChart and cannot comment on any differences. What exactly is the problem? Post a little demo project which shows the issue.

"fePower" - are you talking of TFitSeries?

tambok

  • New Member
  • *
  • Posts: 19
Re: Problem displaying fePower
« Reply #2 on: October 18, 2018, 08:03:05 pm »
Sorry, I don't know how PilotLogic modfied TAChart and cannot comment on any differences. What exactly is the problem? Post a little demo project which shows the issue.

"fePower" - are you talking of TFitSeries?

Hi Wp,

thanks to quick replay.
sorry, I don't know that it's from pilotlogic.
yes, I used Pilotlogic because fePower can't appear on Lazarus.
I tried again using lazarus, and I upgraded my project, but the problem remains the same.

following the example of the Fit Series, I tried to write codes.


tambok

  • New Member
  • *
  • Posts: 19
Re: Problem displaying fePower
« Reply #3 on: October 18, 2018, 08:21:23 pm »
My codes from testFit.zip

==================================

procedure TForm1.ComboBox2Select(Sender: TObject);
begin
  case ComboBox2.ItemIndex of
   0: begin
        SpinEdit1.Enabled:=False;
        Chart1FitSeries1.Clear;
      end;
   1: begin
        SpinEdit1.Enabled:=True;
        Chart1FitSeries1.FitEquation:=fePolynomial;
        SpinEdit1Change(Sender);
        PlotFitCurve();
      end;
   2: begin
        SpinEdit1.Enabled:=False;
        Chart1FitSeries1.FitEquation:=fePower;
        PlotFitCurve();
      end;
  end;
end;

procedure TForm1.PlotFitCurve();
var
  MinVals, MaxVals, i: Integer;
  X,Y: Real;
begin
  if ComboBox1.ItemIndex>0 then
   begin
     with StringGrid1 do
       begin
         if RowCount>0 then
          begin
            Chart1FitSeries1.Clear;

            if SpinEdit2.Enabled then
             MinVals:=SpinEdit2.Value else MinVals:=SpinEdit2.MinValue;
            if SpinEdit3.Enabled then
             MaxVals:=SpinEdit3.Value else MaxVals:=SpinEdit3.MaxValue;

            for i:=1 to RowCount-1 do
             begin
               if (Cells[2,i]<>EmptyStr) and
                  (Cells[3,i]<>EmptyStr) and
                  (Cells[4,i]<>EmptyStr) and
                  (Cells[5,i]<>EmptyStr) and
                  (Cells[6,i]<>EmptyStr) then
                 begin
                   if (StrToInt(Cells[2,i])>=MinVals) and
                      (StrToInt(Cells[2,i])<=MaxVals) then
                     begin
                       case ComboBox1.ItemIndex of
                       1: begin
                             X:= StrToFloat(Cells[3,i]);  // Lpp
                             Y:= StrToFloat(Cells[4,i]);  // B
                          end;
                       2: begin
                             X:= StrToFloat(Cells[5,i]);  // D
                             Y:= StrToFloat(Cells[6,i]);  // T
                          end;
                       end;
                       Chart1FitSeries1.AddXY(X,Y,Cells[1,i]);
                     end;
                 end;
             end;
            Chart1.Refresh;
          end;
       end;
   end;
end;

==========================

thanks

tbk

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Problem displaying fePower
« Reply #4 on: October 19, 2018, 12:50:44 am »
What is your operating system? And which is the bitness of the IDE, 32 bit or 64 bit?

I normally work with the 32-bit IDE on Windows 10/64 bit, and here the fit series for fePower is displayed correctly. When I switch to the 64-bit IDE, however, the fitted curve is not drawn.

Looking a bit deeper at the fitted results of the parameters a and b of the function y = a * x^b, I see that a is returned as 0 - of course, then the entire function is zero and is not visible because it is out of the range of the data points.

But the 32-bit program yields the correct value of a, 0.3402.

The fit to the power function primarily returns the log of a. The fitting routine does get the correct log(a) = -1.078 on both 32 and 64 bits. In order to return a directly the FitSeries calculates the exponential of this value, i.e. exp(-1.078). The 32-bit program does it correctly, but the 64-bit program returns 0. How can this be? A standalone 64-bit program does the calculation correctly.

I fear that something in the user program is badly wrong. Looks like a long debugging session...

tambok

  • New Member
  • *
  • Posts: 19
Re: Problem displaying fePower
« Reply #5 on: October 19, 2018, 08:43:27 am »
my computer uses OS win 10, 64bit.
the test is for 32bit IDE. I don't plan it to be used on 64 bit.


I fear that something in the user program is badly wrong. Looks like a long debugging session...

Did you mean the 'user' here is designer or programmer that uses Lazarus?

if yes, I only use the code as in the test file. but has different results. hmm..


thanks

tbk

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Problem displaying fePower
« Reply #6 on: October 19, 2018, 09:40:52 am »
With "user" I meant your code. I simplified your test project, removed all the file-reading and grid stuff, but the issue remains (see attached project). Therefore, I am convinced now that the bug is at least within TAChart.

Here is a workaround which makes the fitted curve visible, but since it does not fix the root cause the bug may show up at another place:
- Open file TAFuncSeries.pas (in components/tachart of your Lazarus installation).
- Find procedure TFitSeries.ExecFit and the nested procedure TryFit therein.
- Towards its end you'll find the two-liner
 
Code: Pascal  [Select][+][-]
  1.   if FFitEquation in [feExp, fePower] then
  2.     FFitParams[0] := Exp(FFitParams[0]);

- Replace this by the following lines to avoid the negative argument of the exp function:
 
Code: Pascal  [Select][+][-]
  1.     if FFitEquation in [feExp, fePower] then begin
  2.       if FFitParams[0] < 0 then
  3.         FFitParams[0] := 1.0 / Exp(-FFitParams[0])
  4.       else
  5.         FFitParams[0] := Exp(FFitParams[0]);
  6.     end;

I wonder why you see the bug in the 32-bit program and I see it in 64-bit only. I hope we are talking of the same thing.

tambok

  • New Member
  • *
  • Posts: 19
Re: Problem displaying fePower
« Reply #7 on: October 19, 2018, 10:41:09 am »
I simplified your test project, removed all the file-reading and grid stuff, but the issue remains (see attached project).

i see your codes wp. Thank you very much. 
may I ask permission to use your code? (actually, i dont know how to use Record and Array... :D)
this is big knowledge for me.


Quote
Therefore, I am convinced now that the bug is at least within TAChart.

if this bug is true as you think, should it be reported?

Quote
I wonder why you see the bug in the 32-bit program and I see it in 64-bit only. I hope we are talking of the same thing.

i'm sure we are talking of the same thing. :)


anyway thanks to you, WP for the help.
atleast i can continue the project.


tbk

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Problem displaying fePower
« Reply #8 on: October 19, 2018, 11:49:06 am »
Found it.

The exp() function is normally calculated by the system unit. But because of the fitting calculations TAFuncSeries.pas also has some numlib units in its uses clause. The culprit is unit "typ" which implements its own exp function and overrides the system function. It sets the function result to zero when the function argument is very small (i.e. very negative). The problem is that the switch-over point is way too large on 64-bit systems (near zero)! I reported this to the fpc people to fix (https://bugs.freepascal.org/view.php?id=34434).

Since the fpc fix will not be readily available soon I also added a fix to the TAFuncSeries which by-passes numlib in the calculation of exp(). This patch is immediately available in Lazarus trunk and will be included in the upcoming Lazarus v2.0.

You can patch your currently used v1.8.4 easily:
- Open unit TAFuncSeries again and remove the changes that I proposed previously.
- Find the comment  { TColorMapLegendItem }.
- Insert the following code before this comment (or at another location near the top of the implementation section):
Code: Pascal  [Select][+][-]
  1. // Workaround for numlib issue with too-small arguments of exp()
  2. // https://bugs.freepascal.org/view.php?id=34434
  3. function exp(x: ArbFloat): ArbFloat;
  4. begin
  5.   Result := system.exp(x);
  6. end;
- Now all calls to exp() within TAFuncSeries should use the original system function.

 

TinyPortal © 2005-2018