home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff373.lzh
/
Multiplot
/
source
/
mplot_src
/
src.zoo
/
smooth.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-02
|
21KB
|
684 lines
#include <math.h>
#include <stdio.h>
#include <exec/types.h>
#include <exec/exec.h>
#include "struct.h"
#include "plot.h"
#define RESOLUTION 40
extern SHORT UpBorderVectors[];
struct Border IntUpBorder = {
0,0, /* XY origin relative to container TopLeft */
1,0,JAM1, /* front pen, back pen and drawmode */
8, /* number of XY vectors */
UpBorderVectors, /* pointer to XY vectors */
NULL /* next border in list */
};
struct Gadget IntUp = {
NULL, /* next gadget */
183,70, /* origin XY of hit box relative to window TopLeft */
15,20, /* hit box width and height */
GADGHBOX+GADGHIMAGE, /* gadget flags */
GADGIMMEDIATE, /* activation flags */
BOOLGADGET, /* gadget type flags */
(APTR)&IntUpBorder, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
NULL, /* first IntuiText structure */
NULL, /* gadget mutual-exclude long word */
NULL, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
extern SHORT DownBorderVectors[];
struct Border IntDownBorder = {
0,0, /* XY origin relative to container TopLeft */
1,0,JAM1, /* front pen, back pen and drawmode */
8, /* number of XY vectors */
DownBorderVectors, /* pointer to XY vectors */
NULL /* next border in list */
};
struct Gadget IntDown = {
&IntUp, /* next gadget */
120,70, /* origin XY of hit box relative to window TopLeft */
15,20, /* hit box width and height */
GADGHBOX+GADGHIMAGE, /* gadget flags */
GADGIMMEDIATE, /* activation flags */
BOOLGADGET, /* gadget type flags */
(APTR)&IntDownBorder, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
NULL, /* first IntuiText structure */
NULL, /* gadget mutual-exclude long word */
NULL, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
SHORT IntGadgBorderVectors[] = {
0,0,
40,0,
40,17,
0,17,
0,1
};
struct Border IntGadgBorder = {
-1,-5, /* XY origin relative to container TopLeft */
1,0,JAM1, /* front pen, back pen and drawmode */
5, /* number of XY vectors */
IntGadgBorderVectors, /* pointer to XY vectors */
NULL /* next border in list */
};
UBYTE IntGadgSIBuff[7]="5";
struct StringInfo IntGadgSInfo = {
IntGadgSIBuff, /* buffer where text will be edited */
NULL, /* optional undo buffer */
0, /* character position in buffer */
3, /* maximum number of characters to allow */
0, /* first displayed character buffer position */
0,0,0,0,0, /* Intuition initialized and maintained variables */
0, /* Rastport of gadget */
5, /* initial value for integer gadgets */
NULL /* alternate keymap (fill in if you set the flag) */
};
struct Gadget IntGadg = {
&IntDown, /* next gadget */
140,78, /* origin XY of hit box relative to window TopLeft */
37,16, /* hit box width and height */
NULL, /* gadget flags */
RELVERIFY+LONGINT+STRINGCENTER, /* activation flags */
STRGADGET, /* gadget type flags */
(APTR)&IntGadgBorder, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
NULL, /* first IntuiText structure */
NULL, /* gadget mutual-exclude long word */
(APTR)&IntGadgSInfo, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
extern struct Image Continue;
struct Gadget IntContinue = {
&IntGadg, /* next gadget */
210,135, /* origin XY of hit box relative to window TopLeft */
99,43, /* hit box width and height */
GADGHBOX+GADGHIMAGE+GADGIMAGE, /* gadget flags */
GADGIMMEDIATE, /* activation flags */
BOOLGADGET, /* gadget type flags */
(APTR)&Continue, /* gadget border or image to be rendered */
NULL, /* alternate imagery for selection */
NULL, /* first IntuiText structure */
NULL, /* gadget mutual-exclude long word */
NULL, /* SpecialInfo structure */
NULL, /* user-definable data */
NULL /* pointer to user-definable data */
};
struct NewWindow NewGetIntWindow = {
125,84, /* window XY origin relative to TopLeft of screen */
340,200, /* window width and height */
0,1, /* detail and block pens */
GADGETDOWN|RAWKEY, /* IDCMP flags */
ACTIVATE|NOCAREREFRESH, /* flags */
&IntContinue, /* first gadget in gadget list */
NULL, /* custom CHECKMARK imagery */
NULL, /* window title */
NULL, /* custom screen pointer */
NULL, /* custom bitmap */
5,5, /* minimum width and height */
640,200, /* maximum width and height */
CUSTOMSCREEN /* destination screen type */
};
struct IntuiText GetIntText2 = {
1,0,JAM2, /* front and back text pens, drawmode and fill byte */
60,40, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
"to smooth data by.", /* pointer to text */
NULL /* next IntuiText structure */
};
struct IntuiText GetIntText1 = {
1,0,JAM2, /* front and back text pens, drawmode and fill byte */
60,30, /* XY origin relative to container TopLeft */
NULL, /* font pointer or NULL for default */
"Enter the number of values",
&GetIntText2 /* next IntuiText structure */
};
struct Window *GetIntWindow;
extern struct Screen *screen;
#define GO 1
#define STOP 0
#define ON TRUE
int QuitGetIntFlag=GO;
GetInt(min,max)
int min,max;
{
struct IntuiMessage *i_message; /* pointer to message */
void ProcGetIntMes();
struct RastPort *p;
NewGetIntWindow.Screen = screen;
if (!(GetIntWindow = (struct Window *)OpenWindow(&NewGetIntWindow)))
{
ErrorAlert(0);
CloseScreen(screen);
sexit(FALSE);
}
p = GetIntWindow->RPort;
PrintIText(p,&GetIntText1,0,0);
QuitGetIntFlag=GO; /*** RESET FLAG IN CASE NOT FIRST TIME ***/
while (QuitGetIntFlag !=STOP)
{
Wait(1l<<GetIntWindow->UserPort->mp_SigBit); /* wait for a message */
while (i_message = (struct IntuiMessage *)GetMsg(GetIntWindow->UserPort))
ProcGetIntMes(i_message,min,max);
}
CloseWindow(GetIntWindow);
return(IntGadgSInfo.LongInt);
}
void ProcGetIntMes(p_message,min,max)
int min, max;
struct IntuiMessage *p_message;
{
ULONG MesClass; /* Fields for storing */
USHORT MesCode; /* intuimessage data */
APTR Pointer; /* */
int HandleGetIntEvent();
MesClass = p_message->Class; /* Store values */
MesCode = p_message->Code;
Pointer = p_message->IAddress;
ReplyMsg(p_message); /* Reply to message */
HandleGetIntEvent(MesClass,MesCode,Pointer,min,max);
}
int HandleGetIntEvent(MesClass,MesCode,Pointer,min,max)
ULONG MesClass; /* Fields for storing */
USHORT MesCode; /* intuimessage data */
APTR Pointer; /* */
int min,max;
{
short len;
if ( MesClass == GADGETDOWN)
{
if (Pointer == (APTR)&IntDown)
{
RemoveGadget(GetIntWindow,&IntGadg);
if (IntGadgSInfo.LongInt<(min+2)) {Message("Minimum Allowable Value Reached");}
else IntGadgSInfo.LongInt--;
stci_d(IntGadgSIBuff,IntGadgSInfo.LongInt);
len =strlen(IntGadgSIBuff);
IntGadgSInfo.BufferPos=len, IntGadgSInfo.DispPos=0;
AddGadget(GetIntWindow,&IntGadg,-1L);
RefreshGadgets(&IntGadg,GetIntWindow,NULL);
}
if (Pointer == (APTR)&IntUp)
{
RemoveGadget(GetIntWindow,&IntGadg);
if (IntGadgSInfo.LongInt>(max-2)) {Message("Maximum Allowable Value Reached");}
else IntGadgSInfo.LongInt++;
stci_d(IntGadgSIBuff,IntGadgSInfo.LongInt);
len =strlen(IntGadgSIBuff);
IntGadgSInfo.BufferPos=len, IntGadgSInfo.DispPos=0;
AddGadget(GetIntWindow,&IntGadg,-1L);
RefreshGadgets(&IntGadg,GetIntWindow,NULL);
}
if (Pointer == (APTR)&IntContinue)
{
if (IntGadgSInfo.LongInt<min) {Message(" Value Entered is too Small "); return(0);}
if (IntGadgSInfo.LongInt>max-1) {Message(" Value Entered is too Large "); return(0);}
QuitGetIntFlag = STOP;
return(1);
}
}
if ( MesClass == RAWKEY)
{
if (MesCode ==196) /* RETURN key RELEASED */
{
if (IntGadgSInfo.LongInt<min) {Message(" Value Entered is too Small "); return(0);}
if (IntGadgSInfo.LongInt>max-1) {Message(" Value Entered is too Large "); return(0);}
QuitGetIntFlag = STOP;
return(1);
}
}
return(0);
}
SmoothData(Pict,SelectedPlot)
struct Plot *SelectedPlot;
struct Pict *Pict;
{
short i;
int numpoints=0, window;
FFP *y1array, *YArray, *YArrayStart, *GetArray();
struct Plot *Plot, *PlotStart, *ClonePlot();
if (!TestX(SelectedPlot)) return(FALSE);
/* Calculate and get array to store Y values */
YArray=YArrayStart=GetArray(SelectedPlot,&numpoints,3);
if (!YArray) return(FALSE);
if (!(window = GetInt(0,(int)(numpoints/2)))) return(FALSE);
/* Fill array with Y values */
Plot=SelectedPlot;
do
{
y1array=Plot->y;
for (i=0;i<Plot->NPts;i++)
{
*YArray=(FFP)y1array[i];
YArray++;
}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
/* Calculate smoothed values and place in 2nd half of array */
smooth(YArrayStart,numpoints,window);
if (!(PlotStart=ClonePlot(Pict,SelectedPlot))) return(FALSE);
/* Put new values in new structure */
YArray=YArrayStart+numpoints;
for (Plot=PlotStart;Plot;Plot=Plot->NextPlot)
{
y1array=Plot->y;
for (i=0;i<Plot->NPts;i++,YArray++) { y1array[i]=(FFP)*YArray; }
}
FreeMem(YArrayStart,sizeof(FFP)*numpoints*3);
return(TRUE);
}
FFP *GetArray(SelectedPlot,i,factor)
struct Plot *SelectedPlot;
int *i, factor;
{
FFP *Array;
struct Plot *Plot;
Plot=SelectedPlot;
do {(*i)+=Plot->NPts;} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
Array=(FFP *)AllocMem(sizeof(FFP)*(*i)*factor,MEMF_CLEAR);
if (!Array) { Message(" Not Enough Memory for Function"); return(NULL);}
else return((FFP *)Array);
}
struct Plot *ClonePlot(Pict,SelectedPlot)
struct Pict *Pict;
struct Plot *SelectedPlot;
{
short i;
int numplots=0;
FFP *xarray, *yarray, *x1array, *y1array;
struct Plot *Plot, *TempPlot, *PlotStart, *GetStructPlot();
/* Make new Plot structure to take smoothed values */
for (Plot=Pict->Plot;Plot->NextPlot;Plot=Plot->NextPlot); /* go to end */
if (!(Plot->NextPlot = GetStructPlot()))
{ Message(" Not Enough Memory for Function"); return(NULL); }
else PlotStart= Plot = Plot->NextPlot;
TempPlot=SelectedPlot;
do {
Plot->NPts=TempPlot->NPts;
Plot->Continued=TempPlot->Continued;
Plot->Color=TempPlot->Color;
Plot->Lines=TRUE;
Plot->PointSize=0;
Plot->PointType=TempPlot->PointType;
Plot->Enabled=TempPlot->Enabled;
Plot->NextPlot=NULL;
xarray=TempPlot->x; yarray=TempPlot->y;
x1array=Plot->x; y1array=Plot->y;
for (i=0;i<TempPlot->NPts;i++) x1array[i]=xarray[i];
numplots++;
if (Plot->Continued)
{
if (!(Plot->NextPlot = GetStructPlot()))
{
Message(" Not Enough Memory for Function");
Plot->Continued=FALSE;
Plot->Enabled=FALSE;
return(NULL);
}
Plot = Plot->NextPlot;
}
} while ((TempPlot->Continued)&&(TempPlot=TempPlot->NextPlot));
Pict->NPlt++;
return(PlotStart);
}
smooth(Array,n,window)
FFP *Array; /* Which is of length 2*n */
int n, window;
{
int i,j;
FFP *ResultArray, *TempArray, median(), mean();
ResultArray=Array+n; /* Place results in second half of array */
TempArray=Array+(2*n); /* Tempory data storage for sorting */
if (!(window<n/2)) return(FALSE);
for (i=0;i<window;i++)
{
for (j=0;j<i+window+1;j++) TempArray[j]=Array[j];
ResultArray[i]=mean(TempArray,i+window+1);
}
for (i=window;i<n-window;i++)
{
for (j=0;j<2*window+1;j++) TempArray[j]=Array[j+i-window];
ResultArray[i]=mean(TempArray,2*window+1);
}
for (i=n-window;i<n;i++)
{
for (j=0;j<n+window-i;j++) TempArray[j]=Array[j+i-window];
ResultArray[i]=mean(TempArray,n+window-i);
}
return(TRUE);
}
FFP median(data, n)
FFP *data;
int n;
{
int n2, n2p;
fqsort(data,n);
n2p=(n2=n/2)+1;
return((FFP)(n % 2 ? data[n2p-1] : 0.5*(data[n2-1]+data[n2p-1])));
}
FFP mean(data, n)
FFP *data;
int n;
{
int i;
FFP sum=0.0;
for(i=0;i<n;i++,data++) sum+=*data;
return((FFP)(sum/n));
}
FitData(Pict,SelectedPlot)
struct Plot *SelectedPlot;
struct Pict *Pict;
{
short i, j;
int numpoints=0;
FFP *y1array, *x1array, a, b=0.0, *YArray, *YArrayStart, *GetArray(), *XArray, *XArrayStart, *TArray;
void FitDataFunc();
struct Plot *Plot, *GetStructPlot();
char legend[80];
if (!TestX(SelectedPlot)) return(FALSE);
YArray=YArrayStart=GetArray(SelectedPlot,&numpoints,3);
if (!YArray) return(FALSE);
TArray=(XArray=XArrayStart=YArray+numpoints)+numpoints;
/* Fill arrays with X and Y values */
Plot=SelectedPlot;
do
{
y1array=Plot->y; x1array=Plot->x;
for (i=0;i<Plot->NPts;i++,YArray++,XArray++)
{*YArray=(FFP)y1array[i]; *XArray=(FFP)x1array[i];}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
FitDataFunc(XArrayStart,YArrayStart,TArray,numpoints,&a,&b);
for (Plot=Pict->Plot;Plot->NextPlot;Plot=Plot->NextPlot); /* go to end */
if (!(Plot->NextPlot = GetStructPlot()))
{ Message(" Not Enough Memory for Function"); return(NULL); }
Plot=Plot->NextPlot;
sprintf(legend,"f(x)=%2.2lf%+2.2lfx",(double)a,(double)b);
strcpy(Plot->Legend->String,legend);
i=0;
do {
Plot->NPts=MAXPOINTS;
Plot->Continued=FALSE;
Plot->Color=SelectedPlot->Color;
Plot->Lines=TRUE;
Plot->PointSize=0;
Plot->PointType=SelectedPlot->PointType;
Plot->Enabled=TRUE;
Plot->NextPlot=NULL;
x1array=Plot->x; y1array=Plot->y;
for (j=i;((i<j+Plot->NPts)&&(i<=RESOLUTION));i++)
{
x1array[i-j]= (FFP)Pict->CurrReg->XMin+ (FFP)i*((FFP)(Pict->CurrReg->XMax-Pict->CurrReg->XMin)/(FFP)RESOLUTION);
y1array[i-j]=a+b*(x1array[i-j]);
}
} while ((i<=RESOLUTION)
&&(Plot->NextPlot=(struct Plot *)GetStructPlot())
&&(Plot->Continued=TRUE)
&&(Plot=Plot->NextPlot));
Plot->NPts=i-j;
Pict->NPlt++;
FreeMem(YArrayStart,sizeof(FFP)*numpoints*3);
return(TRUE);
}
TestX(Plot)
struct Plot *Plot;
{
int i, start=TRUE;
FFP xmin, xmax, *XArray;
do {
XArray=Plot->x;
for (i=0;i<Plot->NPts;i++)
{
if (start) {xmin=xmax=XArray[i]; start=FALSE;}
else{
xmax=max(xmax,XArray[i]);
xmin=min(xmin,XArray[i]);
if (xmax!=XArray[i]) { Message(" Error: Data Set Not Sorted"); return(FALSE);}
}
}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
if (xmax==xmin) { Message(" Error: X Values Invariable"); return(FALSE);}
return(TRUE);
}
void FitDataFunc(XArray,YArray,TArray,numpoints,a,b)
FFP *XArray, *YArray,*TArray, *a,*b;
int numpoints;
{
FFP sumx=0.0, sumy=0.0, sumt2=0.0;
int i;
for(i=0;i<numpoints;i++) { sumx+=XArray[i]; sumy+=YArray[i]; }
for(i=0;i<numpoints;i++)
{
TArray[i]=XArray[i]-sumx/numpoints;
sumt2+=(TArray[i]*TArray[i]);
*b+=TArray[i]*YArray[i];
}
*b/=sumt2;
*a=(sumy-sumx**b)/numpoints;
}
FitLogData(Pict,SelectedPlot)
struct Plot *SelectedPlot;
struct Pict *Pict;
{
short i,j;
int numpoints=0;
FFP *y1array, *x1array, a, b=0.0, *YArray, *YArrayStart, *GetArray(), *XArray, *XArrayStart, *TArray;
void FitDataFunc();
struct Plot *Plot, *GetStructPlot();
char legend[80];
if (!TestX(SelectedPlot)) return(FALSE);
YArray=YArrayStart=GetArray(SelectedPlot,&numpoints,3);
if (!YArray) return(FALSE);
TArray=(XArrayStart=XArray=YArray+numpoints)+numpoints;
/* Fill arrays with X and Y values */
Plot=SelectedPlot;
do
{
y1array=Plot->y; x1array=Plot->x;
for (i=0;i<Plot->NPts;i++,YArray++,XArray++)
{
*YArray=(FFP)log(abs((double)y1array[i]));
*XArray=(FFP)x1array[i];
}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
FitDataFunc(XArrayStart,YArrayStart,TArray,numpoints,&a,&b);
for (Plot=Pict->Plot;Plot->NextPlot;Plot=Plot->NextPlot); /* go to end */
if (!(Plot->NextPlot = GetStructPlot()))
{ Message(" Not Enough Memory for Function"); return(NULL); }
Plot=Plot->NextPlot;
sprintf(legend,"f(x)=%2.2lf*exp(%2.2lfx)",exp((double)a),(double)b);
strcpy(Plot->Legend->String,legend);
i=0;
do {
Plot->NPts=MAXPOINTS;
Plot->Continued=FALSE;
Plot->Color=SelectedPlot->Color;
Plot->Lines=TRUE;
Plot->PointSize=0;
Plot->PointType=SelectedPlot->PointType;
Plot->Enabled=TRUE;
Plot->NextPlot=NULL;
x1array=Plot->x; y1array=Plot->y;
for (j=i;((i<j+Plot->NPts)&&(i<=RESOLUTION));i++)
{
x1array[i-j]= Pict->CurrReg->XMin+ i*((Pict->CurrReg->XMax-Pict->CurrReg->XMin)/RESOLUTION);
y1array[i-j]=(FFP)exp((double)a)*exp((double)b*x1array[i-j]);
}
} while ((i<=RESOLUTION)
&&(Plot->NextPlot=(struct Plot *)GetStructPlot())
&&(Plot->Continued=TRUE)
&&(Plot=Plot->NextPlot));
Plot->NPts=i-j;
Pict->NPlt++;
FreeMem(YArrayStart,sizeof(FFP)*numpoints*3);
return(TRUE);
}
SortData(Pict,SelectedPlot)
struct Plot *SelectedPlot;
struct Pict *Pict;
{
short i;
int numpoints=0;
FFP *e1array, *y1array, *x1array, *YArray, *YArrayStart, *GetArray(), *XArray, *XArrayStart, *EArray, *EArrayStart;
struct Plot *Plot, *GetStructPlot();
YArray=YArrayStart=GetArray(SelectedPlot,&numpoints,3);
if (!YArray) return(FALSE);
EArrayStart=EArray=(XArrayStart=XArray=YArray+numpoints)+numpoints;
/* Fill arrays with X and Y values */
Plot=SelectedPlot;
do
{
y1array=Plot->y; x1array=Plot->x; e1array=Plot->e;
for (i=0;i<Plot->NPts;i++,YArray++,XArray++,EArray++)
{
*YArray=(FFP)y1array[i];
*XArray=(FFP)x1array[i];
*EArray=(FFP)e1array[i];
}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
LinkSort(numpoints,XArrayStart,YArrayStart,EArrayStart);
XArray=XArrayStart; YArray=YArrayStart; EArray=EArrayStart;
Plot=SelectedPlot;
do {
x1array=Plot->x; y1array=Plot->y; e1array=Plot->e;
for (i=0;i<Plot->NPts;i++,XArray++,YArray++,EArray++)
{
x1array[i]=*XArray;
y1array[i]=*YArray;
e1array[i]=*EArray;
}
} while ((Plot->Continued)&&(Plot=Plot->NextPlot));
FreeMem(YArrayStart,sizeof(FFP)*numpoints*3);
return(TRUE);
}
LinkSort(n,ra,rb,rc)
int n;
FFP ra[], rb[], rc[];
{
int l, j, ir, i;
float rrb, rra, rrc;
ra--; rb--; rc--; /* To allow an array r[1....n] */
l=(n>>1)+1;
ir=n;
for(;;) {
if (l>1) {rra=ra[--l]; rrb=rb[l]; rrc=rc[l];}
else
{
rra=ra[ir]; rrb=rb[ir]; rrc=rc[ir];
ra[ir]=ra[1]; rb[ir]=rb[1]; rc[ir]=rc[1];
if (--ir==1) {ra[1]=rra; rb[1]=rrb; rc[1]=rrc; return(0); }
}
i=l;
j=l<<1;
while (j<=ir)
{
if ((j<ir) && (ra[j] < ra[j+1])) ++j;
if (rra< ra[j])
{
ra[i]=ra[j]; rb[i]=rb[j]; rc[i]=rc[j];
j+=(i=j);
}
else j=ir+1;
}
ra[i]=rra; rb[i]=rrb; rc[i]=rrc;
}
return(0);
}