Dear Rene,
I'm sorry for long delay.
Rene Brun wrote:
> Hi Maxim,
>
> In the CVS version, I have improved the array reallocation mechanism
> for TGraph, TGraphErrors, TGraphAsymmErrors and TGraphBentErrors.
> I hope that you see an improvement. Let me know.
Your solution works, performance of TGraph::SetPoint() was improved. but
I am not satisfied yet. I'm surprised that
new Double_t[0];
doesn't lead to segmentation fault. Consider
gr = new TGraph(); // fMaxSize = 0;
gr->SetPoint(Int_t i = 0, 1, 2); // (i >= fMaxSize) is true, 2*i == 0
A have several additional remarks. Probable methods
TGraph::InsertPoint(), TGraph::RemovePoint() should also use buffers.
I'm suggesting add test (2 == sscanf(...)) in the TGraph::TGraph(const
char *filename, const char *format) constructor. It allows to skip empty
lines and comments like '# comment '. Similar TGraphErrors constructor
uses inaccurate field counting algorithm. It doesn't allow skipping
numbers using "*" modifier.
I'm sending my attempt to implement issues mentioned above (only for
TGraph and TGraphErros). The patch is in the attachment. Use
patch -p1 < TGraph_TGraphErrors.patch
from root/graph source directory. I'm trying to localize new/delete
operations.
--
Yours faithfully,
Maxim Nikulin
> Maxim Nikulin wrote:
>
>>Hi,
>>
>>I'm writing a kind of slow control system. I use several histograms, two
>>dimensional plots and TGTextView widgets. They should be "ready to
>>display". If program receives entries one by one it works fine, but
>>reading a file recorded early takes significant time.
>>
>>Using the callgrind program I found several poor places. The first one
>>was TGTextView::AddLine() (Posted in
>>http://root.cern.ch/cgi-bin/print_hit_bold.pl/root/roottalk/roottalk04/2536.html
>>and fixed). Than my manipulations with TAxis::SetTimeDisplay() became
>>most important (old post, for curiosity only
>>http://root.cern.ch/phpBB2/viewtopic.php?t=992 ) and I found more cheap
>>workaround.
>>
>>For two dimensional plots I use the TGraph class. When the program
>>receives an entry it calls TGraph::SetPoint(). This leads to allocation,
>>copying and deallocation of x and y arrays. I don't use TGraph::Set() to
>>allocate large buffer due to (0, 0) points appear on my plots.
>>
>>I propose to introduce additional member and split point number and
>>array size for the TGraph suite. Are there any arguments against the
>>solution? I checked it with restricted descendant of TGraph, but in
>>general case it is more complicated than the TGTextView::AddLine()
>>issue, that's why I decide to discuss it firstly.
>>
>>--
>>Max
Index: graf/inc/TGraph.h
===================================================================
RCS file: /user/cvs/root/graf/inc/TGraph.h,v
retrieving revision 1.37
diff -a -u -r1.37 TGraph.h
--- graf/inc/TGraph.h 6 Sep 2004 06:54:55 -0000 1.37
+++ graf/inc/TGraph.h 9 Sep 2004 11:01:46 -0000
@@ -49,6 +49,16 @@
static void SwapValues(Double_t* arr, Int_t pos1, Int_t pos2);
virtual void SwapPoints(Int_t pos1, Int_t pos2);
+ virtual Double_t **Allocate(Double_t **newarrays, Int_t newsize);
+ virtual Bool_t CopyPoints(Double_t **newarrays, Int_t ibegin, Int_t iend,
+ Int_t obegin);
+ virtual void CopyAndRelease(Double_t **newarrays,
+ Int_t ibegin, Int_t iend, Int_t obegin);
+ virtual Double_t **ExpandAndCopy(Double_t **newarrays,
+ Int_t size, Int_t iend);
+ virtual Double_t **ShrinkAndCopy(Double_t **newarrays,
+ Int_t size, Int_t iend);
+
public:
// TGraph status bits
enum {
@@ -85,6 +95,8 @@
virtual void DrawPanel(); // *MENU*
virtual Double_t Eval(Double_t x, TSpline *spline=0, Option_t *option="") const;
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
+ virtual void Expand(Int_t newsize);
+ virtual void Expand(Int_t newsize, Int_t step);
virtual TObject *FindObject(const char *name) const;
virtual TObject *FindObject(const TObject *obj) const;
virtual Int_t Fit(const char *formula ,Option_t *option="" ,Option_t *goption="", Axis_t xmin=0, Axis_t xmax=0); // *MENU*
Index: graf/inc/TGraphErrors.h
===================================================================
RCS file: /user/cvs/root/graf/inc/TGraphErrors.h,v
retrieving revision 1.15
diff -a -u -r1.15 TGraphErrors.h
--- graf/inc/TGraphErrors.h 6 May 2004 09:40:30 -0000 1.15
+++ graf/inc/TGraphErrors.h 9 Sep 2004 11:01:47 -0000
@@ -1,4 +1,4 @@
-// @(#)root/graf:$Name: $:$Id: TGraphErrors.h,v 1.15 2004/05/06 09:40:30 brun Exp $
+// @(#)root/graf:$Name: v4-00-08-patches $:$Id: TGraphErrors.h,v 1.15 2004/05/06 09:40:30 brun Exp $
// Author: Rene Brun 15/09/96
/*************************************************************************
@@ -32,6 +32,11 @@
Double_t *fEY; //[fNpoints] array of Y errors
virtual void SwapPoints(Int_t pos1, Int_t pos2);
+ virtual Double_t** Allocate(Double_t **newarrays, Int_t size);
+ virtual void CopyAndRelease(Double_t **newarrays,
+ Int_t ibegin, Int_t iend, Int_t obegin);
+ virtual Bool_t CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend,
+ Int_t obegin);
public:
TGraphErrors();
@@ -43,6 +48,7 @@
TGraphErrors(const char *filename, const char *format="%lg %lg %lg %lg", Option_t *option="");
virtual ~TGraphErrors();
virtual void Apply(TF1 *f);
+ static Int_t CalculateScanfFields(const char *fmt);
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const;
Double_t GetErrorX(Int_t bin) const;
Double_t GetErrorY(Int_t bin) const;
@@ -51,8 +57,6 @@
virtual Int_t InsertPoint(); // *MENU*
virtual void Paint(Option_t *chopt="");
virtual void Print(Option_t *chopt="") const;
- virtual Int_t RemovePoint(); // *MENU*
- virtual Int_t RemovePoint(Int_t ipoint);
virtual void SavePrimitive(ofstream &out, Option_t *option);
virtual void Set(Int_t n);
virtual void SetPoint(Int_t i, Double_t x, Double_t y);
Index: graf/src/TGraph.cxx
===================================================================
RCS file: /user/cvs/root/graf/src/TGraph.cxx,v
retrieving revision 1.137
diff -a -u -r1.137 TGraph.cxx
--- graf/src/TGraph.cxx 6 Sep 2004 06:54:55 -0000 1.137
+++ graf/src/TGraph.cxx 9 Sep 2004 11:01:48 -0000
@@ -466,8 +466,10 @@
char line[80];
Int_t np = 0;
while (fgets(line,80,fp)) {
- sscanf(&line[0],format,&x, &y);
- if (np >= fNpoints) Set(2*fNpoints);
+ if( 2 != sscanf(&line[0],format,&x, &y)) {
+ // skip empty and ill-formed lines
+ continue;
+ }
SetPoint(np,x,y);
np++;
}
@@ -503,6 +505,27 @@
}
//______________________________________________________________________________
+Double_t** TGraph::Allocate(Double_t **newarrays, Int_t size)
+{
+// allocate new arays of size n.
+// For zero newarrays allocate newarrays[2],
+// assign pointers to newarrays[0] for x and newarrays[1] for y.
+// Return newarrays (argument or allocated one)
+ if (size < 0) { size = 0; }
+ if (!newarrays) {
+ newarrays = new Double_t*[2];
+ }
+ if (!size) {
+ newarrays[0] = newarrays[1] = 0;
+ } else {
+ newarrays[0] = new Double_t[size];
+ newarrays[1] = new Double_t[size];
+ }
+ fMaxSize = size;
+ return newarrays;
+}
+
+//______________________________________________________________________________
void TGraph::Apply(TF1 *f)
{
// apply function f to all the data points
@@ -554,6 +577,48 @@
}
//______________________________________________________________________________
+void TGraph::CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend,
+ Int_t obegin)
+{
+// Copy points from fX and fY to arrays[0] and arrays[1]
+// or to fX and fY if arrays == 0 and ibegin != iend.
+// If newarrays is non null, replace fX, fY with pointers from newarrays[0,1].
+// Delete newarrays, old fX and fY
+ CopyPoints(newarrays, ibegin, iend, obegin);
+ if (newarrays) {
+ delete[] fX;
+ fX = newarrays[0];
+ delete[] fY;
+ fY = newarrays[1];
+ delete[] newarrays;
+ }
+}
+
+//______________________________________________________________________________
+Bool_t TGraph::CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend,
+ Int_t obegin)
+{
+// Copy points from fX and fY to arrays[0] and arrays[1]
+// or to fX and fY if arrays == 0 and ibegin != iend.
+ if (ibegin < 0 || iend <= ibegin || obegin < 0) { // Error;
+ return kFALSE;
+ }
+ if (!arrays && ibegin == obegin) { // No copying is needed
+ return kFALSE;
+ }
+ if (arrays) {
+ memmove(&arrays[0][obegin], &fX[ibegin],
+ (iend - ibegin)*sizeof(Double_t));
+ memmove(&arrays[1][obegin], &fY[ibegin],
+ (iend - ibegin)*sizeof(Double_t));
+ } else {
+ memmove(&fX[obegin], &fX[ibegin], (iend - ibegin)*sizeof(Double_t));
+ memmove(&fY[obegin], &fY[ibegin], (iend - ibegin)*sizeof(Double_t));
+ }
+ return kTRUE;
+}
+
+//______________________________________________________________________________
void TGraph::Draw(Option_t *option)
{
//*-*-*-*-*-*-*-*-*-*-*Draw this graph with its current attributes*-*-*-*-*-*-*
@@ -952,6 +1017,39 @@
}
//______________________________________________________________________________
+void TGraph::Expand(Int_t newsize)
+{
+// if array sizes <= newsize, expand storage to 2*newsize.
+ Double_t **ps = ExpandAndCopy(0, newsize, fNpoints);
+ CopyAndRelease(ps, 0, 0, 0);
+}
+
+//______________________________________________________________________________
+void TGraph::Expand(Int_t newsize, Int_t step)
+{
+// If graph capacity is less than newsize points then make array sizes
+// equal to least multiple of step to contain newsize points.
+// Returns kTRUE if size was altered
+ if (newsize <= fMaxSize) {
+ return;
+ }
+ Double_t **ps = Allocate(0, (newsize/step + (newsize%step?1:0))*step);
+ CopyAndRelease(ps, 0, fNpoints, 0);
+}
+
+//______________________________________________________________________________
+Double_t **TGraph::ExpandAndCopy(Double_t **newarrays, Int_t size, Int_t iend)
+{
+// if size > fMaxSize allocate new arrays of 2*size points
+// and copy oend first points.
+// Return pointer to new arrays.
+ if (size <= fMaxSize) { return newarrays; }
+ newarrays = Allocate(newarrays, 2*size);
+ CopyPoints(newarrays, 0, iend, 0);
+ return newarrays;
+}
+
+//______________________________________________________________________________
TObject *TGraph::FindObject(const char *name) const
{
// search object named name in the list of functions
@@ -1673,24 +1771,10 @@
if (dpx*dpx+dpy*dpy < 25) ipoint = 0;
else ipoint = fNpoints;
}
- fNpoints++;
- fMaxSize = fNpoints;
- Double_t *newX = new Double_t[fNpoints];
- Double_t *newY = new Double_t[fNpoints];
- for (i=0;i<ipoint;i++) {
- newX[i] = fX[i];
- newY[i] = fY[i];
- }
- newX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(px));
- newY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(py));
- for (i=ipoint+1;i<fNpoints;i++) {
- newX[i] = fX[i-1];
- newY[i] = fY[i-1];
- }
- delete [] fX;
- delete [] fY;
- fX = newX;
- fY = newY;
+ Double_t **ps = ExpandAndCopy(0, fNpoints + 1, ipoint);
+ CopyAndRelease(ps, ipoint, fNpoints++, ipoint + 1);
+ fX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(px));
+ fY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(py));
gPad->Modified();
return ipoint;
}
@@ -3291,24 +3375,7 @@
Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
if (dpx*dpx+dpy*dpy < 25) {ipoint = i; break;}
}
- if (ipoint == -2) return -1;
- fNpoints--;
- fMaxSize = fNpoints;
- Double_t *newX = new Double_t[fNpoints];
- Double_t *newY = new Double_t[fNpoints];
- Int_t j = -1;
- for (i=0;i<fNpoints+1;i++) {
- if (i == ipoint) continue;
- j++;
- newX[j] = fX[i];
- newY[j] = fY[i];
- }
- delete [] fX;
- delete [] fY;
- fX = newX;
- fY = newY;
- gPad->Modified();
- return ipoint;
+ return RemovePoint(ipoint);
}
//______________________________________________________________________________
@@ -3319,21 +3386,8 @@
if (ipoint < 0) return -1;
if (ipoint >= fNpoints) return -1;
- fNpoints--;
- fMaxSize = fNpoints;
- Double_t *newX = new Double_t[fNpoints];
- Double_t *newY = new Double_t[fNpoints];
- Int_t j = -1;
- for (Int_t i=0;i<fNpoints+1;i++) {
- if (i == ipoint) continue;
- j++;
- newX[j] = fX[i];
- newY[j] = fY[i];
- }
- delete [] fX;
- delete [] fY;
- fX = newX;
- fY = newY;
+ Double_t **ps = ShrinkAndCopy(0, fNpoints - 1, ipoint);
+ CopyAndRelease(ps, ipoint+1, fNpoints--, ipoint);
if (gPad) gPad->Modified();
return ipoint;
}
@@ -3402,26 +3456,13 @@
if (n < 0) n = 0;
if (n == fNpoints) return;
- Double_t *xx=0, *yy=0;
- if (n > 0) {
- xx = new Double_t[n];
- yy = new Double_t[n];
- }
- Int_t i;
- for (i=0; i<fNpoints && i<n;i++) {
- if (fX) xx[i] = fX[i];
- if (fY) yy[i] = fY[i];
- }
- for (i=fNpoints; i<n;i++) {
- xx[i] = 0;
- yy[i] = 0;
+ Double_t **ps = Allocate(0, n);
+ CopyAndRelease(ps, 0, TMath::Min(fNpoints,n), 0);
+ if (n > fNpoints) {
+ memset(&fX[fNpoints], 0, (n - fNpoints)*sizeof(Double_t));
+ memset(&fY[fNpoints], 0, (n - fNpoints)*sizeof(Double_t));
}
- delete [] fX;
- delete [] fY;
fNpoints = n;
- fMaxSize = n;
- fX = xx;
- fY = yy;
}
//______________________________________________________________________________
@@ -3464,22 +3505,15 @@
if (i < 0) return;
if (i >= fMaxSize) {
- // re-allocate the object
- fMaxSize = 2*i;
- Double_t *savex = new Double_t[fMaxSize];
- Double_t *savey = new Double_t[fMaxSize];
- if (fNpoints > 0) {
- memcpy(savex,fX,fNpoints*sizeof(Double_t));
- memcpy(savey,fY,fNpoints*sizeof(Double_t));
- }
- memset(&savex[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- memset(&savey[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- if (fX) delete [] fX;
- if (fY) delete [] fY;
- fX = savex;
- fY = savey;
+ Double_t **ps = ExpandAndCopy(0, i+1, fNpoints);
+ CopyAndRelease(ps, 0,0,0);
+ }
+ if (i >= fNpoints) {
+ // points above i can be not initialized
+ memset(&fX[fNpoints],0,(i-fNpoints)*sizeof(Double_t));
+ memset(&fY[fNpoints],0,(i-fNpoints)*sizeof(Double_t));
+ fNpoints = i+1;
}
- if (i >= fNpoints) fNpoints = i+1;
fX[i] = x;
fY[i] = y;
if (fHistogram) {
@@ -3496,6 +3530,22 @@
}
//______________________________________________________________________________
+Double_t **TGraph::ShrinkAndCopy(Double_t **newarrays, Int_t size,
+ Int_t oend)
+{
+// if size*2 <= fMaxSize allocate new arrays of size points,
+// copy points [0,oend).
+// Return newarray (passed or new instance if it was zero
+// and allocations are needed)
+ if (size*2 > fMaxSize || !fMaxSize) {
+ return 0;
+ }
+ newarrays = Allocate(newarrays, size);
+ CopyPoints(newarrays, 0, oend, 0);
+ return newarrays;
+}
+
+//______________________________________________________________________________
void TGraph::Smooth(Int_t npoints, Double_t *x, Double_t *y, Int_t drawtype)
{
//*-*-*-*-*-*-*-*-*-*-*-*Smooth a curve given by N points*-*-*-*-*-*-*-*-*-*
Index: graf/src/TGraphErrors.cxx
===================================================================
RCS file: /user/cvs/root/graf/src/TGraphErrors.cxx,v
retrieving revision 1.39
diff -a -u -r1.39 TGraphErrors.cxx
--- graf/src/TGraphErrors.cxx 2 Sep 2004 14:22:20 -0000 1.39
+++ graf/src/TGraphErrors.cxx 9 Sep 2004 11:01:48 -0000
@@ -198,21 +198,23 @@
return;
}
// count number of columns in format
- Int_t ncol = 0;
- char *s = (char*)format;
- while((s=(char*)strstr(s,"%"))) {ncol++; s++;}
+ Int_t ncol = CalculateScanfFields(format);
char line[80];
Int_t np = 0;
while (fgets(line,80,fp)) {
+ ex=ey=0;
+ Int_t res;
if (ncol < 3) {
- ex=ey=0;
- sscanf(&line[0],format,&x, &y);
+ res = sscanf(&line[0],format,&x, &y);
} else if(ncol <4) {
- ex=0;
- sscanf(&line[0],format,&x, &y, &ey);
+ res = sscanf(&line[0],format,&x, &y, &ey);
} else {
- sscanf(&line[0],format,&x, &y, &ex, &ey);
+ res = sscanf(&line[0],format,&x, &y, &ex, &ey);
+ }
+ if (res < 2) {
+ // not a data line
+ continue;
}
if (np >= fNpoints) Set(2*fNpoints);
SetPoint(np,x,y);
@@ -235,6 +237,28 @@
}
//______________________________________________________________________________
+Double_t** TGraphErrors::Allocate(Double_t **newarrays, Int_t size)
+{
+// allocate new arays of size n.
+// For zero newarrays allocate newarrays[4],
+// assign pointers to newarrays[0] for ex and newarrays[1] for ey,
+// newarrays[2] for x and newarrays[3] for y
+// Return newarrays (argument or allocated one)
+ if (size < 0) { size = 0; }
+ if (!newarrays) {
+ newarrays = new Double_t*[4];
+ }
+ if (!size) {
+ newarrays[0] = newarrays[1] = 0;
+ } else {
+ newarrays[0] = new Double_t[size];
+ newarrays[1] = new Double_t[size];
+ }
+ TGraph::Allocate(newarrays + 2, size);
+ return newarrays;
+}
+
+//______________________________________________________________________________
void TGraphErrors::Apply(TF1 *f)
{
// apply function to all the data points
@@ -262,6 +286,34 @@
}
//______________________________________________________________________________
+Int_t TGraphErrors::CalculateScanfFields(const char *fmt)
+{
+ Int_t fields = 0;
+ while ((fmt = strchr(fmt, '%'))) {
+ Bool_t skip = kFALSE;
+ while (*(++fmt)) {
+ if ('[' == *fmt) {
+ if (*++fmt && '^' == *fmt) ++fmt; // "%[^]a]"
+ if (*++fmt && ']' == *fmt) ++fmt; // "%[]a]" or "%[^]a]"
+ while (*fmt && *fmt != ']')
+ ++fmt;
+ if (!skip) ++fields;
+ break;
+ }
+ if ('%' == *fmt) break; // %% literal %
+ if ('*' == *fmt) {
+ skip = kTRUE; // %*d -- skip a number
+ } else if (strchr("dDiouxXxfegEscpn", *fmt)) {
+ if (!skip) ++fields;
+ break;
+ }
+ // skip modifiers & field width
+ }
+ }
+ return fields;
+}
+
+//______________________________________________________________________________
void TGraphErrors::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
{
for (Int_t i=0;i<fNpoints;i++) {
@@ -287,6 +339,52 @@
}
//______________________________________________________________________________
+void TGraphErrors::CopyAndRelease(Double_t **newarrays,
+ Int_t ibegin, Int_t iend, Int_t obegin)
+{
+// Copy points from fX and fY to arrays[3] and arrays[1],
+// errors from arrays[0] and arrays[1];
+// or to fX and fY if arrays == 0 and ibegin != iend.
+// If newarrays is non null, replace fX, fY with pointers from newarrays[0,1].
+// Delete newarrays, old fX and fY
+ CopyPoints(newarrays, ibegin, iend, obegin);
+ if (newarrays) {
+ delete[] fX;
+ fX = newarrays[2];
+ delete[] fY;
+ fY = newarrays[3];
+ delete[] fEX;
+ fEX = newarrays[0];
+ delete[] fEY;
+ fEY = newarrays[1];
+ delete[] newarrays;
+ }
+}
+
+//______________________________________________________________________________
+Bool_t TGraphErrors::CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend,
+ Int_t obegin)
+{
+// Copy errors from fEX and fEY to arrays[0] and arrays[1]
+// or to fX and fY. Copy points.
+ if (TGraph::CopyPoints(arrays ? arrays+2 : 0, ibegin, iend, obegin)) {
+ if (arrays) {
+ memmove(&arrays[0][obegin], &fEX[ibegin],
+ (iend - ibegin)*sizeof(Double_t));
+ memmove(&arrays[1][obegin], &fEY[ibegin],
+ (iend - ibegin)*sizeof(Double_t));
+ } else {
+ memmove(&fEX[obegin], &fEX[ibegin], (iend - ibegin)*sizeof(Double_t));
+ memmove(&fEY[obegin], &fEY[ibegin], (iend - ibegin)*sizeof(Double_t));
+ }
+ return kTRUE;
+ } else {
+ return kFALSE;
+ }
+}
+
+
+//______________________________________________________________________________
Double_t TGraphErrors::GetErrorX(Int_t i) const
{
// This function is called by GraphFitChisquare.
@@ -314,24 +412,10 @@
// Insert a new point at the mouse position
Int_t ipoint = TGraph::InsertPoint();
-
- Double_t *newEX = new Double_t[fNpoints];
- Double_t *newEY = new Double_t[fNpoints];
- Int_t i;
- for (i=0;i<ipoint;i++) {
- newEX[i] = fEX[i];
- newEY[i] = fEY[i];
- }
- newEX[ipoint] = 0;
- newEY[ipoint] = 0;
- for (i=ipoint+1;i<fNpoints;i++) {
- newEX[i] = fEX[i-1];
- newEY[i] = fEY[i-1];
+ if (ipoint >= 0) {
+ fEX[ipoint] = 0;
+ fEY[ipoint] = 0;
}
- delete [] fEX;
- delete [] fEY;
- fEX = newEX;
- fEY = newEY;
return ipoint;
}
@@ -546,54 +630,6 @@
}
//______________________________________________________________________________
-Int_t TGraphErrors::RemovePoint()
-{
-// Delete point close to the mouse position
-
- Int_t ipoint = TGraph::RemovePoint();
- if (ipoint < 0) return ipoint;
-
- Double_t *newEX = new Double_t[fNpoints];
- Double_t *newEY = new Double_t[fNpoints];
- Int_t i, j = -1;
- for (i=0;i<fNpoints+1;i++) {
- if (i == ipoint) continue;
- j++;
- newEX[j] = fEX[i];
- newEY[j] = fEY[i];
- }
- delete [] fEX;
- delete [] fEY;
- fEX = newEX;
- fEY = newEY;
- return ipoint;
-}
-
-//______________________________________________________________________________
-Int_t TGraphErrors::RemovePoint(Int_t ipnt)
-{
-// Delete point number ipnt
-
- Int_t ipoint = TGraph::RemovePoint(ipnt);
- if (ipoint < 0) return ipoint;
-
- Double_t *newEX = new Double_t[fNpoints];
- Double_t *newEY = new Double_t[fNpoints];
- Int_t i, j = -1;
- for (i=0;i<fNpoints+1;i++) {
- if (i == ipoint) continue;
- j++;
- newEX[j] = fEX[i];
- newEY[j] = fEY[i];
- }
- delete [] fEX;
- delete [] fEY;
- fEX = newEX;
- fEY = newEY;
- return ipoint;
-}
-
-//______________________________________________________________________________
void TGraphErrors::SavePrimitive(ofstream &out, Option_t *option)
{
// Save primitive as a C++ statement(s) on output stream out
@@ -655,39 +691,12 @@
// Existing coordinates are preserved
// New coordinates and errors above fNpoints are preset to 0.
- if (n < 0) n = 0;
- if (n == fNpoints) return;
- Double_t *x=0, *y=0, *ex=0, *ey=0;
- if (n > 0) {
- x = new Double_t[n];
- y = new Double_t[n];
- ex = new Double_t[n];
- ey = new Double_t[n];
- }
- Int_t i;
- for (i=0; i<fNpoints && i<n;i++) {
- if (fX) x[i] = fX[i];
- if (fY) y[i] = fY[i];
- if (fEX) ex[i] = fEX[i];
- if (fEY) ey[i] = fEY[i];
- }
- for (i=fNpoints; i<n;i++) {
- x[i] = 0;
- y[i] = 0;
- ex[i] = 0;
- ey[i] = 0;
+ Int_t saveNpoints = fNpoints;
+ TGraph::Set(n);
+ if (fNpoints > saveNpoints) {
+ memset(&fEX[saveNpoints], 0, (fNpoints - saveNpoints)*sizeof(Double_t));
+ memset(&fEY[saveNpoints], 0, (fNpoints - saveNpoints)*sizeof(Double_t));
}
- delete [] fX;
- delete [] fY;
- delete [] fEX;
- delete [] fEY;
- fNpoints = n;
- fMaxSize = n;
-
- fX = x;
- fY = y;
- fEX = ex;
- fEY = ey;
}
//______________________________________________________________________________
@@ -695,40 +704,11 @@
{
//*-*-*-*-*-*-*-*-*-*-*Set x and y values for point number i*-*-*-*-*-*-*-*-*
//*-* =====================================
-
- if (i < 0) return;
- if (i >= fMaxSize) {
- // re-allocate the object
- fMaxSize = 2*i;
- Double_t *savex = new Double_t[fMaxSize];
- Double_t *savey = new Double_t[fMaxSize];
- Double_t *saveex = new Double_t[fMaxSize];
- Double_t *saveey = new Double_t[fMaxSize];
- if (fNpoints > 0) {
- memcpy(savex, fX, fNpoints*sizeof(Double_t));
- memcpy(savey, fY, fNpoints*sizeof(Double_t));
- memcpy(saveex,fEX,fNpoints*sizeof(Double_t));
- memcpy(saveey,fEY,fNpoints*sizeof(Double_t));
- }
- memset(&savex[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- memset(&savey[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- memset(&saveex[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- memset(&saveey[fNpoints],0,(fMaxSize-fNpoints)*sizeof(Double_t));
- if (fX) delete [] fX;
- if (fY) delete [] fY;
- if (fEX) delete [] fEX;
- if (fEY) delete [] fEY;
- fX = savex;
- fY = savey;
- fEX = saveex;
- fEY = saveey;
- }
- if (i >= fNpoints) fNpoints = i+1;
- fX[i] = x;
- fY[i] = y;
- if (fHistogram) {
- delete fHistogram;
- fHistogram = 0;
+ Int_t saveNpoints = fNpoints;
+ TGraph::SetPoint(i, x, y);
+ if (fNpoints > saveNpoints) {
+ memset(fEX + fNpoints, 0, (fNpoints - saveNpoints + 1)*sizeof(Double_t));
+ memset(fEY + fNpoints, 0, (fNpoints - saveNpoints + 1)*sizeof(Double_t));
}
}
This archive was generated by hypermail 2b29 : Sun Jan 02 2005 - 05:50:09 MET