Problem displaying fePower lazarus / 55-TAChart ---------------------------------------------------------------------- tambok · 2018-10-18 17:36 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 · 2018-10-18 17:48 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 · 2018-10-18 18:03 Quote from: wp on October 18, 2018, 07:48:29 pmSorry, 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 · 2018-10-18 18:21 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 · 2018-10-18 22:50 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 · 2018-10-19 06:43 my computer uses OS win 10, 64bit. the test is for 32bit IDE. I don't plan it to be used on 64 bit. Quote from: wp on October 19, 2018, 12:50:44 amI 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 · 2018-10-19 07:40 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   if FFitEquation in [feExp, fePower] then     FFitParams[0] := Exp(FFitParams[0]); - Replace this by the following lines to avoid the negative argument of the exp function:   Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     if FFitEquation in [feExp, fePower] then begin      if FFitParams[0] < 0 then        FFitParams[0] := 1.0 / Exp(-FFitParams[0])      else      FFitParams[0] := Exp(FFitParams[0]);    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 · 2018-10-19 08:41 Quote from: wp on October 19, 2018, 09:40:52 amI 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... ) this is big knowledge for me. QuoteTherefore, I am convinced now that the bug is at least within TAChart. if this bug is true as you think, should it be reported? QuoteI 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 · 2018-10-19 09:49 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // Workaround for numlib issue with too-small arguments of exp()// https://bugs.freepascal.org/view.php?id=34434function exp(x: ArbFloat): ArbFloat;begin  Result := system.exp(x);end;- Now all calls to exp() within TAFuncSeries should use the original system function.