diff --git a/Makefile b/Makefile index 552d6446..78255448 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sanswave.o faverage.o bruker.o rmtrail.o fowrite.o ltc11.o \ simchop.o choco.o chadapter.o docho.o trim.o eurodriv.o scaldate.o \ hklscan.o xytable.o amor2t.o nxamor.o amorscan.o amorstat.o \ - circular.o el755driv.o maximize.o sicscron.o tecsdriv.o + circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o COUNTEROBJ = countdriv.o simcter.o counter.o @@ -53,8 +53,9 @@ CC=cc EXTRA= CFLAGS = -I$(HDFROOT)/include -Ihardsup -I. -std1 -g -warnprotos -c #CFLAGS = -I$(HDFROOT)/include -DFORTIFY -Ihardsup -g -std1 -warnprotos -c -LIBS = -L$(HDFROOT)/lib -Lhardsup -lhlib -Ltecs -ltecsl -ltcl8.0 -lfor -lmfhdf -ldf \ - $(HDFROOT)/lib/libjpeg.a -lz -lm -ll -lc +LIBS = -L$(HDFROOT)/lib -Lhardsup -lhlib -Lmatrix -lmatrix -Ltecs \ + -ltecsl -ltcl8.0 -lfor -lmfhdf -ldf $(HDFROOT)/lib/libjpeg.a \ + -lz -lm -ll -lc #------- for cygnus #HDFROOT=../HDF411 diff --git a/SCinter.c b/SCinter.c index e6d0738f..0fb57c4c 100644 --- a/SCinter.c +++ b/SCinter.c @@ -302,10 +302,13 @@ extern char *SkipSpace(char *pPtr); pCurrent = self->pCList; while(pCurrent) { - if(strcmp(pCurrent->pName, pBueffel) == 0 ) + if(pCurrent->pName != NULL) { - return pCurrent; - } + if(strcmp(pCurrent->pName, pBueffel) == 0 ) + { + return pCurrent; + } + } pCurrent = pCurrent->pNext; } return NULL; diff --git a/chadapter.c b/chadapter.c index 33f806f3..3e5753d6 100644 --- a/chadapter.c +++ b/chadapter.c @@ -14,10 +14,15 @@ #include #include "fortify.h" #include "sics.h" +#define CHOCOINTERNAL #include "choco.h" +#include "evcontroller.h" +#include "evdriver.i" #define CHADAINTERNAL #include "chadapter.h" +#define NOTIMPLEMENTED -11555 + /*-------------------------------------------------------------------------*/ static void *AdapterGetInterface(void *pData, int iID) { @@ -313,6 +318,190 @@ return 1; } +/*========================================================================= + An environment driver based on top of a controller object. + -------------------------------------------------------------------------*/ + static int AVEVSetValue(pEVDriver self, float fNew) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + myData->iLastError = 0; + + return myData->pDriv->SetPar(myData->pDriv,myData->pParName,fNew); + } +/*-----------------------------------------------------------------------*/ + static int AVEVGetValue(pEVDriver self, float *fNew) + { + pCHev myData; + int iRet; + char pBueffel[80]; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + + iRet = myData->pDriv->GetPar(myData->pDriv,myData->pParName, + pBueffel,79); + sscanf(pBueffel,"%f",fNew); + return iRet; + } +/*-----------------------------------------------------------------------*/ + static int AVEVSend(pEVDriver self, char *pCommand, + char *pReply, int iLen) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + myData->iLastError = NOTIMPLEMENTED; + + return 0; + } +/*-----------------------------------------------------------------------*/ + static int AVEVGetError(pEVDriver self, int *iCode, + char *pReply, int iLen) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + + if(myData->iLastError == NOTIMPLEMENTED) + { + strncpy(pReply,"ERROR: Not Implemented here!", iLen); + *iCode = NOTIMPLEMENTED; + myData->iLastError = 0; + return 1; + } + else + { + return myData->pDriv->GetError(myData->pDriv, iCode, + pReply, iLen); + } + } +/*------------------------------------------------------------------------*/ + static int AVEVTryFixIt(pEVDriver self, int iCode) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + + if(iCode == NOTIMPLEMENTED) + { + return DEVFAULT; + } + else + { + return myData->pDriv->TryFixIt(myData->pDriv, iCode); + } + } +/*---------------------------------------------------------------------*/ + static int AVEVInit(pEVDriver self) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + + return myData->pDriv->Init(myData->pDriv); + } +/*---------------------------------------------------------------------*/ + static int AVEVClose(pEVDriver self) + { + pCHev myData; + + assert(self); + myData = (pCHev)self->pPrivate; + assert(myData); + + return myData->pDriv->Close(myData->pDriv); + } +/*----------------------------------------------------------------------*/ + static void AVEVKillPrivate(void *pData) + { + pCHev myData; + + if(pData != NULL) + { + myData = (pCHev)pData; + if(myData != NULL) + { + if(myData->pParName) + free(myData->pParName); + free(myData); + } + } + } +/*---------------------------------------------------------------------*/ + pEVDriver MakeControllerEnvironmentDriver(int argc, char *argv[]) + { + pEVDriver pNew = NULL; + pCHev myData = NULL; + CommandList *pCom = NULL; + pDummy pDum = NULL; + pChoco pChop; + + /* + Two arguments are needed: the name of the controller and the + name of the parameter + */ + if(argc < 2) + { + return NULL; + } + pCom = FindCommand(pServ->pSics,argv[0]); + if(!pCom) + { + return NULL; + } + pDum = pCom->pData; + if(!pDum) + { + return NULL; + } + if(strcmp(pDum->pDescriptor->name,"Chopper") != 0) + { + return NULL; + } + + /* alright: I think we got a controller now, let us create our + act + */ + pNew = CreateEVDriver(argc,argv); + if(!pNew) + { + return NULL; + } + myData = (pCHev)malloc(sizeof(CHev)); + if(!myData) + { + return NULL; + } + + pChop = (pChoco)pCom->pData; + myData->iLastError = 0; + myData->pDriv = pChop->pDriv; + myData->pParName = strdup(argv[1]); + pNew->pPrivate = myData; + pNew->SetValue =AVEVSetValue; + pNew->GetValue =AVEVGetValue; + pNew->Send = AVEVSend; + pNew->GetError =AVEVGetError; + pNew->TryFixIt =AVEVTryFixIt; + pNew->Init =AVEVInit; + pNew->Close =AVEVClose; + pNew->KillPrivate =AVEVKillPrivate; + + return pNew; + } diff --git a/chadapter.h b/chadapter.h index abaaa445..ec3319f8 100644 --- a/chadapter.h +++ b/chadapter.h @@ -40,6 +40,7 @@ typedef struct __CHEV { char *pParName; pCodri pDriv; + int iLastError; }CHev, *pCHev; #endif diff --git a/choco.c b/choco.c index e2064edb..fdf02d52 100644 --- a/choco.c +++ b/choco.c @@ -175,6 +175,7 @@ extern pCodri MakeSimChopper(void); extern pCodri MakeDoChoDriver(char *pHost, int iPort, int iChannel); +extern pCodri MakeCookerDriver(char *pHost, int iPort, int iChannel); /*-----------------------------------------------------------------------*/ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -230,6 +231,33 @@ extern pCodri MakeDoChoDriver(char *pHost, int iPort, int iChannel); } pDriv = MakeDoChoDriver(argv[3],iPort,iChannel); } + else if(strcmp(argv[2],"sanscook") == 0) + { + if(argc < 6) + { + SCWrite(pCon, + "ERROR: Insufficient number of arguments to install SANS Cooker driver", + eError); + return 0; + } + iRet = Tcl_GetInt(pSics->pTcl,argv[4],&iPort); + if(iRet != TCL_OK) + { + sprintf(pBueffel,"ERROR: expected integer as port number, got %s", + argv[4]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + iRet = Tcl_GetInt(pSics->pTcl,argv[5],&iChannel); + if(iRet != TCL_OK) + { + sprintf(pBueffel,"ERROR: expected integer as channel number, got %s", + argv[4]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + pDriv = MakeCookerDriver(argv[3],iPort,iChannel); + } else { sprintf(pBueffel,"ERROR: Driver %s NOT supported for MakeController", diff --git a/choco.tex b/choco.tex index 9b543f6e..af1f8bbe 100644 --- a/choco.tex +++ b/choco.tex @@ -270,6 +270,7 @@ $\langle$evada {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ typedef struct __CHEV {@\\ \mbox{}\verb@ char *pParName;@\\ \mbox{}\verb@ pCodri pDriv;@\\ +\mbox{}\verb@ int iLastError;@\\ \mbox{}\verb@ }CHev, *pCHev;@\\ \mbox{}\verb@@$\diamond$ \end{list} diff --git a/choco.w b/choco.w index d61ffaea..10b6be55 100644 --- a/choco.w +++ b/choco.w @@ -92,7 +92,7 @@ the error can be ignored or was fully resolved. \item[pParList] is text string containing a comma separated list of all parameters understood by this driver. \item[pPrivate] Is a pointer to a driver specific specific data -structure. This data structure will not be messed with by upper level code. +structure. This data structure shall not be messed with by upper level code. \end{description} \subsubsection{The Controller Object} @@ -200,6 +200,7 @@ controller driver: typedef struct __CHEV { char *pParName; pCodri pDriv; + int iLastError; }CHev, *pCHev; @} diff --git a/countdriv.c b/countdriv.c index a42a0778..f19527d6 100644 --- a/countdriv.c +++ b/countdriv.c @@ -455,13 +455,24 @@ case EL737__BAD_ILLG: case EL737__BAD_ADR: case EL737__BAD_PAR: - case EL737__BAD_BSY: case EL737__BAD_TMO: case EL737__BAD_REPLY: case EL737__BAD_SNTX: case EL737__BAD_OVFL: return COREDO; break; + case EL737__BAD_BSY: + strcpy(pCommand,"S \r"); + iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49); + if(iRet < 0) + { + return COTERM; + } + else + { + return COREDO; + } + break; case EL737__BAD_LOC: strcpy(pCommand,"rmt 1\r"); iRet = EL737_SendCmnd(&pEL737->pData,pCommand,pReply,49); diff --git a/counter.c b/counter.c index 25e3486b..283dbe29 100644 --- a/counter.c +++ b/counter.c @@ -233,7 +233,15 @@ sMon.fCurrent = fControl; sMon.fPreset = self->pDriv->fPreset; sMon.pName = self->name; - InvokeCallBack(self->pCall,MONITOR,&sMon); + if(self->iCallbackCounter > 20) + { + InvokeCallBack(self->pCall,MONITOR,&sMon); + self->iCallbackCounter = 0; + } + else + { + self->iCallbackCounter++; + } self->pDriv->fLastCurrent = fControl; return eCt; } @@ -357,6 +365,7 @@ pRes->pCountInt->Halt = Halt; pRes->pCountInt->Pause = PauseCount; pRes->pCountInt->Continue = ContinueCount; + pRes->iCallbackCounter = 20; pRes->pCall = CreateCallBackInterface(); diff --git a/counter.h b/counter.h index 06f56923..bdefc49c 100644 --- a/counter.h +++ b/counter.h @@ -22,6 +22,7 @@ pCounterDriver pDriv; pICallBack pCall; unsigned long tStart; + int iCallbackCounter; } Counter, *pCounter; /*----------------------------- birth & death -----------------------------*/ diff --git a/danu.dat b/danu.dat index b399ab11..d338d9b0 100644 --- a/danu.dat +++ b/danu.dat @@ -1,3 +1,3 @@ - 5798 + 5829 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!|n \ No newline at end of file diff --git a/drive.c b/drive.c index 7a336df6..c11d8083 100644 --- a/drive.c +++ b/drive.c @@ -358,7 +358,7 @@ /* check the completion status */ if(iRet == DEVERROR) { - sprintf(pBueffel,"Driving finished with problem",argv[0]); + sprintf(pBueffel,"Driving finished with problem"); SCWrite(pCon,pBueffel,eError); ClearExecutor(GetExecutor()); SetStatus(eOld); diff --git a/evcontroller.c b/evcontroller.c index a509bc7e..340253dd 100644 --- a/evcontroller.c +++ b/evcontroller.c @@ -61,6 +61,7 @@ #include "eurodriv.h" #include "el755driv.h" #include "tecsdriv.h" +#include "chadapter.h" /*--------------------- Functions needed to implement interfaces -----------*/ static long EVIDrive(void *pData, SConnection *pCon, float fVal) { @@ -1239,7 +1240,8 @@ SCSendOK(pCon); return 1; } - else if(strcmp(argv[3],"ltc11") == 0) /* Neocera LTC-11 temperature controller*/ + else if(strcmp(argv[3],"ltc11") == 0) + /* Neocera LTC-11 temperature controller*/ { /* Create a driver */ pDriv = CreateLTC11Driver(argc-4,&argv[4]); @@ -1340,6 +1342,18 @@ return 0; } } + else if(strcmp(argv[3],"gencon") == 0) /* general controller */ + { + /* Create a driver */ + pDriv = MakeControllerEnvironmentDriver(argc-4,&argv[4]); + if(!pDriv) + { + SCWrite(pCon, + "ERROR: failed to create Controller Environment driver", + eError); + return 0; + } + } else if(strcmp(argv[3],"euro") == 0) /* dillution driver */ { /* Create a driver */ diff --git a/hkl.c b/hkl.c index 2e8dec89..bc525eeb 100644 --- a/hkl.c +++ b/hkl.c @@ -18,6 +18,7 @@ #include "motor.h" #include "selector.h" #include "selvar.h" +#include "matrix/matrix.h" #include "hkl.h" #include "hkl.i" /*-------------------------------------------------------------------------*/ @@ -79,6 +80,7 @@ pNew->fUB[0] = 1.; pNew->fUB[4] = 1.; pNew->fUB[8] = 1.; + pNew->UBinv = NULL; return pNew; } @@ -306,6 +308,7 @@ int SetUB(pHKL self, float fUB[9]) { int i; + MATRIX m; assert(self); @@ -313,6 +316,21 @@ { self->fUB[i] = fUB[i]; } + /* invert UB matrix for use in backwards calculation */ + if(self->UBinv != NULL) + { + mat_free(self->UBinv); + } + m = mat_creat(3,3,ZERO_MATRIX); + for(i = 0; i < 3; i++) + { + m[0][i] = self->fUB[i]; + m[1][i] = self->fUB[3+i]; + m[2][i] = self->fUB[6+i]; + } + self->UBinv = mat_inv(m); + mat_free(m); + return 1; } /*-------------------------------------------------------------------------*/ @@ -1183,6 +1201,42 @@ ente: return iResult; } +/*------------------------------------------------------------------------- + For the conversion from angles to HKL. + -------------------------------------------------------------------------*/ + static int angle2HKL(pHKL self ,double tth, double om, + double chi, double phi, float fHKL[3]) + { + double dTh, dOm, dChi, dPhi, dHM; + MATRIX res, rez; + int i; + + /* conversion to radians */ + dTh = tth/(2*RD); + dOm = (om - tth/2.)/RD; + dChi = chi/RD; + dPhi = phi/RD; + dHM = 2* sin(dTh)/self->fLambda; + + /* angles to XYZ, stolen from DIFRAC code in PRPXYZ */ + res = mat_creat(3,1,ZERO_MATRIX); + res[0][0] = dHM*(cos(dChi)*cos(dPhi)*cos(dOm) - + sin(dPhi)*sin(dOm)); + res[1][0] = dHM*(cos(dChi)*sin(dPhi)*cos(dOm) + + cos(dPhi)*sin(dOm)); + res[2][0] = dHM*sin(dChi)*cos(dOm); + + /* multiply with UBinv in order to yield HKL */ + rez = mat_mul(self->UBinv,res); + for(i = 0; i < 3; i++) + { + fHKL[i] = rez[i][0]; + } + mat_free(res); + mat_free(rez); + + return 1; + } /*--------------------------------------------------------------------------*/ int isNumeric(char *pText) { @@ -1312,10 +1366,28 @@ ente: /*----------- current */ else if(strcmp(argv[1],"current") == 0) { - sprintf(pBueffel,"Last HKL: %8.4f %8.4f %8.4f ", - self->fLastHKL[0], self->fLastHKL[1],self->fLastHKL[2]); - SCWrite(pCon,pBueffel,eValue); - return 1; + if(self->iNOR) + { + sprintf(pBueffel,"Last HKL: %8.4f %8.4f %8.4f ", + self->fLastHKL[0], self->fLastHKL[1],self->fLastHKL[2]); + SCWrite(pCon,pBueffel,eValue); + return 1; + } + else + { + /* do a serious calculation based on angles */ + iRet = GetCurrentPosition(self,pCon,fSet); + if(iRet == 0) + { + return; + } + angle2HKL(self,(double)fSet[0],(double)fSet[1], + (double)fSet[2],(double)fSet[3],fHKL); + sprintf(pBueffel,"Current HKL: %8.4f %8.4f %8.4f ", + fHKL[0], fHKL[1],fHKL[2]); + SCWrite(pCon,pBueffel,eValue); + return 1; + } } /*------------- lambda */ else if(strcmp(argv[1],"lambda") == 0) diff --git a/hkl.i b/hkl.i index 80666e91..56ef03da 100644 --- a/hkl.i +++ b/hkl.i @@ -10,6 +10,7 @@ typedef struct __HKL { pObjectDescriptor pDes; double fUB[9]; + MATRIX UBinv; double fLambda; int iManual; double fLastHKL[5]; diff --git a/hkl.tex b/hkl.tex index 764637d1..f34f82d9 100644 --- a/hkl.tex +++ b/hkl.tex @@ -18,6 +18,7 @@ $\langle$hkldat {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ typedef struct __HKL {@\\ \mbox{}\verb@ pObjectDescriptor pDes;@\\ \mbox{}\verb@ double fUB[9];@\\ +\mbox{}\verb@ MATRIX UBinv;@\\ \mbox{}\verb@ double fLambda;@\\ \mbox{}\verb@ int iManual;@\\ \mbox{}\verb@ double fLastHKL[5];@\\ diff --git a/hkl.w b/hkl.w index 3384c8f2..e26baff2 100644 --- a/hkl.w +++ b/hkl.w @@ -13,6 +13,7 @@ The object uses the following object data structure: typedef struct __HKL { pObjectDescriptor pDes; double fUB[9]; + MATRIX UBinv; double fLambda; int iManual; double fLastHKL[5]; diff --git a/hklscan.c b/hklscan.c index 00bd4cb4..34d81c28 100644 --- a/hklscan.c +++ b/hklscan.c @@ -17,6 +17,7 @@ #include "scan.h" #include "hkl.h" #include "scan.i" +#include "matrix/matrix.h" #include "hkl.i" #include "hklscan.i" #include "hklscan.h" diff --git a/matrix/DEMO.DAT b/matrix/DEMO.DAT new file mode 100644 index 00000000..b566d75c --- /dev/null +++ b/matrix/DEMO.DAT @@ -0,0 +1,20 @@ +1.1 2 3 4 5 6 7 8 9 9 +2 3.1 4 5 6 7 8 9 9 8 +3 4 5.1 6 7 8 9 9 8 7 +3 4 5 6.1 7 8 9 9 8 7 +1 2 3 4 5 7.2 7 8 9 9 +1 2 3 4 1 6 7 8.3 9 9 +6 2 3 4 5 6 7 8 9.8 9 +1 2 3 3 5 6 7 8 9 9.8 +1 2 3 4 6 6 7 8 9 9 +6 2 3 4 5 4 7 8 9 9 +3 +1 +4 +1 +2 +3 +1 +1 +2 +6 diff --git a/matrix/DEMO.EXE b/matrix/DEMO.EXE new file mode 100644 index 00000000..1dc7e4ca Binary files /dev/null and b/matrix/DEMO.EXE differ diff --git a/matrix/MAKEFILE.MSC b/matrix/MAKEFILE.MSC new file mode 100644 index 00000000..107df78b --- /dev/null +++ b/matrix/MAKEFILE.MSC @@ -0,0 +1,62 @@ +#------------------------------------------------------------------------------ +# file: makefile.msc +# desc: makefile for matrix library package under Microsoft C/C++ v7.0 +# by: patrick ko +# date: 16 Apr 94 +# +# note: a slim matrix library matrix.lib will be generated +#------------------------------------------------------------------------------ + +OBJS = matcreat.obj matdump.obj materr.obj matadd.obj matsub.obj \ +matmul.obj matinv.obj matsolve.obj matdet.obj mattran.obj matdurbn.obj \ +mattoepz.obj matsubx.obj + +CC = cl -c +C = cl + +demo.exe: demo.c matrix.lib + $(C) demo.c matrix.lib + +matrix.lib: $(OBJS) + lib matrix +matcreat +matdump +materr +matadd.obj ,, + lib matrix +matsub +matmul +matinv +matsolve +matdet.obj ,, + lib matrix +mattran +matdurbn +mattoepz +matsubx ,, + +matcreat.obj: matcreat.c matrix.h + $(CC) matcreat.c + +matdump.obj: matdump.c matrix.h + $(CC) matdump.c + +materr.obj: materr.c matrix.h + $(CC) materr.c + +matadd.obj: matadd.c matrix.h + $(CC) matadd.c + +matsub.obj: matsub.c matrix.h + $(CC) matsub.c + +matmul.obj: matmul.c matrix.h + $(CC) matmul.c + +matinv.obj: matinv.c matrix.h + $(CC) matinv.c + +matsolve.obj: matsolve.c matrix.h + $(CC) matsolve.c + +mattran.obj: mattran.c matrix.h + $(CC) mattran.c + +matdet.obj: matdet.c matrix.h + $(CC) matdet.c + +matdurbn.obj: matdurbn.c matrix.h + $(CC) matdurbn.c + +mattoepz.obj: mattoepz.c matrix.h + $(CC) mattoepz.c + +matsubx.obj: matsubx.c matrix.h + $(CC) matsubx.c diff --git a/matrix/MAKEFILE.TC b/matrix/MAKEFILE.TC new file mode 100644 index 00000000..0823ac6b --- /dev/null +++ b/matrix/MAKEFILE.TC @@ -0,0 +1,74 @@ +#------------------------------------------------------------------------------ +# file: makefile.tc +# desc: makefile for matrix library package under Turbo C v2.0 +# by: patrick ko +# date: 16 Apr 94 +# +# note: a slim matrix library matrix.lib will be generated +#------------------------------------------------------------------------------ +DRIVE = C: + +OBJS = matcreat.obj matdump.obj materr.obj matadd.obj matsub.obj \ +matmul.obj matinv.obj matsolve.obj matdet.obj mattran.obj matdurbn.obj \ +mattoepz.obj matsubx.obj + +LIB = -L$(DRIVE)\TC\LIB +INC = -I$(DRIVE)\TC\INCLUDE +CC = tcc -c -mh $(INC) +C = tcc -mh $(LIB) $(INC) +LL = tlib matrix.lib + +demo.exe: demo.c $(OBJS) + $(C) demo.c matrix.lib + +matcreat.obj: matcreat.c matrix.h + $(CC) matcreat.c + $(LL) -+matcreat.obj + +matdump.obj: matdump.c matrix.h + $(CC) matdump.c + $(LL) -+matdump.obj + +materr.obj: materr.c matrix.h + $(CC) materr.c + $(LL) -+materr.obj + +matadd.obj: matadd.c matrix.h + $(CC) matadd.c + $(LL) -+matadd.obj + +matsub.obj: matsub.c matrix.h + $(CC) matsub.c + $(LL) -+matsub.obj + +matmul.obj: matmul.c matrix.h + $(CC) matmul.c + $(LL) -+matmul.obj + +matinv.obj: matinv.c matrix.h + $(CC) matinv.c + $(LL) -+matinv.obj + +matsolve.obj: matsolve.c matrix.h + $(CC) matsolve.c + $(LL) -+matsolve.obj + +mattran.obj: mattran.c matrix.h + $(CC) mattran.c + $(LL) -+mattran.obj + +matdet.obj: matdet.c matrix.h + $(CC) matdet.c + $(LL) -+matdet.obj + +matdurbn.obj: matdurbn.c matrix.h + $(CC) matdurbn.c + $(LL) -+matdurbn.obj + +mattoepz.obj: mattoepz.c matrix.h + $(CC) mattoepz.c + $(LL) -+mattoepz.obj + +matsubx.obj: matsubx.c matrix.h + $(CC) matsubx.c + $(LL) -+matsubx.obj diff --git a/matrix/MAKEFILE.UX b/matrix/MAKEFILE.UX new file mode 100644 index 00000000..a5f58ce5 --- /dev/null +++ b/matrix/MAKEFILE.UX @@ -0,0 +1,54 @@ +#------------------------------------------------------------------------------ +# file: makefile.ux +# desc: makefile for matrix library package under Unix +# by: patrick ko +# date: 16 Apr 94 +#------------------------------------------------------------------------------ +OBJS = matcreat.o matdump.o materr.o matadd.o matsub.o \ +matmul.o matinv.o matsolve.o mattran.o matdet.o mattoepz.o matdurbn.o + +CC = cc -c +C = cc +CO = -lm -g + +demo: demo.c $(OBJS) + $(C) demo.c -o demo $(OBJS) $(CO) + +matcreat.o: matcreat.c matrix.h + $(CC) matcreat.c + +matdump.o: matdump.c matrix.h + $(CC) matdump.c + +materr.o: materr.c matrix.h + $(CC) materr.c + +matadd.o: matadd.c matrix.h + $(CC) matadd.c + +matsub.o: matsub.c matrix.h + $(CC) matsub.c + +matmul.o: matmul.c matrix.h + $(CC) matmul.c + +matinv.o: matinv.c matrix.h + $(CC) matinv.c + +matsolve.o: matsolve.c matrix.h + $(CC) matsolve.c + +mattran.o: mattran.c matrix.h + $(CC) mattran.c + +matdet.o: matdet.c matrix.h + $(CC) matdet.c + +mattoepz.o: mattoepz.c matrix.h + $(CC) mattoepz.c + +matdurbn.o: matdurbn.c matrix.h + $(CC) matdurbn.c + +matsubx.o: matsubx.c matrix.h + $(CC) matsubx.c diff --git a/matrix/MATRIX.DOC b/matrix/MATRIX.DOC new file mode 100644 index 00000000..edaf9f48 --- /dev/null +++ b/matrix/MATRIX.DOC @@ -0,0 +1,482 @@ +/* +*----------------------------------------------------------------------------- +* file: matrix.doc +* desc: document for matrix toolbox function calls +* by: KO shu pui, patrick +* date: 24 may 92 v0.4 +* 23 sep 93 v0.41 +* 16 apr 94 v0.42 +*----------------------------------------------------------------------------- +*/ + +=============================================================================== +0. INTRODUCTION +=============================================================================== +This document only provides you the following information: + + 0.1 How to create and free a matrix + 0.2 Description of each matrix function call + 0.3 Some hints to use this toolbox + +Remember that this document will NOT describe the data structure and +any technical details of the toolbox - just because this document is +aimed at to be a sort-of "User's Guide" for programmers. + + + + +=============================================================================== +1. OUR MATRIX OF REFERENCE +=============================================================================== +In order to avoid terms confusion, here is our matrix of reference +(matrix A) which is of size m x n. + + Column + Row 0 1 2 n-1 + 0 [ a0,0 a0,1 a0,2 ... a0,n-1 ] + A = 1 [ a1,0 a1,1 a1,2 ... a1,n-1 ] + 2 [ a2,0 a2,1 a2,2 ... a2,n-1 ] + [ ... ... ... ... ... ] + m-1 [ am-1,0 am-1,1 am-1,2 ... am-1,n-1 ] + + + +=============================================================================== +2. BASIC MATRIX OBJECT OPERATION +=============================================================================== +------------------------------------------------------------------------------- +Function : MATRIX mat_creat (int m, int n, int type) +Synopsis : creation of a matrix which can be used by the matrix toolbox + functions; memory is allocated for this object; and some + initialization is performed. +Parameter: m: number of rows + n: number of columns + type: matrix initialization type where + + type= + + UNDEFINED do not initialize the matrix + ZERO_MATRIX fill zero to all matrix elements + UNIT_MATRIX fill a one to all matrix element ai,j + where i=j + +Return Value: the matrix object +Example: + + MATRIX A; + + /* + * create a 15 x 15 matrix; + * do not initialize the elements + */ + A = mat_creat( 15, 15, UNDEFINED); + + /* + * put a 4 in element A(0,14) of matrix A, + * put a 2 in element A(3,5) of matrix A + */ + A[0][14] = 4.0; + A[3][5] = 2.0; + +See Also: mat_free(), for Accessing a matrix, see this example. +------------------------------------------------------------------------------- +Function: MATRIX mat_fill ( MATRIX A, int type ) +Synopsis: initialize a matrix will a simple type +Parameter: A: the matrix object for which mat_creat() has been called + type: matrix initialization type where + + type= + + UNDEFINED do not initialize the matrix + ZERO_MATRIX fill zero to all matrix elements + UNIT_MATRIX fill a one to all matrix element ai,j + where i=j +Return Value: MATRIX A +Example: + + MATRIX A; + + ... + /* + * fill the matrix A will zeroes + */ + mat_fill( A, ZERO_MATRIX ); + +See Also: mat_creat() +------------------------------------------------------------------------------- +Function : int mat_free ( MATRIX A ) +Synopsis : free all memory occupied by the matrix object A +Parameter: A: the matrix object for which mat_creat() was called +Return Value: None +Example: + + MATRIX A; + + A = mat_creat(...); + ... + mat_free(A); + +Note: since memory may be a very scarce resource in a computer, + as a C programmer you are advised to free up the matrix as + soon as that matrix will not be used any more in future. + +See Also: mat_creat() +------------------------------------------------------------------------------- +Function: MatCol ( A ) +Synopsis: find out the number of columns of a matrix object A +Parameter: A: the matrix object for which mat_creat() was called +Return Value: number of columns +Example: + int i; + + ... + i = MatCol(A); + +Note: this is a macro +See Also: MatRow() +------------------------------------------------------------------------------- +Function: MatRow ( A ) +Synopsis: find out the number of rows of a matrix object A +Parameter: A: the matrix object for which mat_creat() was called +Return Value: number of rows +Example: + int i; + + ... + i = MatRow(A); + +Note: this is a macro +See Also: MatCol() + +------------------------------------------------------------------------------- +Function: MATRIX mat_colcopy1 ( MATRIX A, MATRIX B, int j1, int j2 ) +Synopsis: copy a column from a matrix A to a column at matrix B +Parameter: A, B: the matrix objects for which mat_creat() was called + column j1 of A is copied to column j2 of B; +Return Value: MATRIX A +Example: + MATRIX A, B; + + A = mat_creat( 5, 4, ZERO_MATRIX ); + B = mat_creat( 5, 4, UNDEFINED ); + + /* + * copy column 2 of A to column 0 of B + */ + mat_colcopy1( A, 2, B, 0 ); + +Note: the sizes of rows of A, B must be the same +See Also: mat_copy() +------------------------------------------------------------------------------- +Function: MATRIX mat_copy ( MATRIX A ) +Synopsis: duplicate a matrix +Parameter: A: the matrix object for which mat_creat() was called +Return Value: Another allocated matrix object whose contents are same + as A +Example: + MATRIX A, B; + + A = mat_creat( 5, 4, ZERO_MATRIX ); + + /* + * B is also a 5 x 4 zero matrix now + */ + B = mat_copy( A ); + ... + mat_free( B ); + +See Also: mat_colcopy1() +------------------------------------------------------------------------------- + + + + +=============================================================================== +3. BASIC MATRIX OBJECT INPUT/OUTPUT OPERATION +=============================================================================== +------------------------------------------------------------------------------- +Function: int fgetmat (MATRIX A, FILE * fp) +Synopsis: read a matrix from stream +Parameter: A: allocated matrix + fp: a stream pointer obtained from fopen() or predefined + pointer in standard library such as stdin +Return Value: number of matrix elements read +Example: + MATRIX A; + FILE *fp; + + A = mat_creat(3, 3, UNDEFINED); + fp = fopen("mymatrix.dat", "r"); + fgetmat( A, fp ); + +See Also: mat_dumpf(), mat_dump(), mat_fdump(), mat_fdumpf() +------------------------------------------------------------------------------- +Function: MATRIX mat_dump (MATRIX A) + MATRIX mat_dumpf (MATRIX A, char * format) + MATRIX mat_fdump (MATRIX A, FILE * fp) + MATRIX mat_fdumpf (MATRIX A, char * format, FILE * fp) + +Synopsis: mat_dump: dump a matrix to std output with default format + mat_dumpf: dump a matrix to std output with specified format + mat_fdump: dump a matrix to a file with default format + mat_fdumpf:dump a matrix to a file with specified format + +Parameter: A: allocated matrix + format: same as printf() 's format parameter, but can only + be floating point type, such as "%.2f ", etc. + fp: file pointer obtained via fopen() + +Return Value: matrix A + +Example: + MATRIX A; + + A = mat_creat( ... ); + ... + /* + * dump the matrix to standard output and each element + * is restricted to 2 precision format + */ + mat_dumpf( A, "%.2f "); + +See Also: fgetmat() +------------------------------------------------------------------------------- + + + + +=============================================================================== +4. BASIC MATRIX OBJECT MATHEMATICAL OPERATION +=============================================================================== +------------------------------------------------------------------------------- +Function: MATRIX mat_add (MATRIX A, MATRIX B); + MATRIX mat_sub (MATRIX A, MATRIX B); +Synopsis: mat_add: addition of 2 matrices + mat_sub: substraction of 2 matrices +Parameter: A, B: allocated matrices +Return Value: a newly allocated matrix which is the result of the operation +Example: + + MATRIX A, B, C; + + A = mat_creat( 5, 5, UNIT_MATRIX ); + B = mat_creat( 5, 5, UNIT_MATRIX ); + + C = mat_add( A, B ); + + mat_dump( C ); + + mat_free( A ); + mat_free( B ); + mat_free( C ); + +Note: A, B must be of the same dimensions +See Also: mat_mul, mat_inv +------------------------------------------------------------------------------- +Function: MATRIX mat_mul (MATRIX A, MATRIX B); +Synopsis: multiplication of 2 matrices +Parameter: A, B: allocated matrix +Return Value: a newly allocated matrix which is the result of the operation +Example: + MATRIX A, B, C; + + A = mat_creat( 5, 3, UNIT_MATRIX ); + B = mat_creat( 3, 6, UNIT_MATRIX ); + + /* + * C is now a 5 x 6 matrix + */ + C = mat_add( A, B ); + + mat_dump( C ); + ... + +Note: the column dimension of A must equal row dimension of B +See Also: mat_add, mat_sub +------------------------------------------------------------------------------- +Function: MATRIX mat_inv (MATRIX A) +Synopsis: find the inverse of a matrix +Parameter: A: allocated square matrix +Return Value: a newly allocated square matrix which is the inverse of A +Example: + MATRIX A, AI; + + /* + * A must be a square matrix + */ + A = mat_creat( 7, 7, UNIT_MATRIX ); + ... + /* + * find the inverse of A + */ + AI = mat_inv( A ); + ... + +See Also: mat_tran, mat_add, mat_sub +------------------------------------------------------------------------------- +Function: MATRIX mat_tran( MATRIX A ) +Synopsis: find the transpose of a matrix +Parameter: A: allocated matrix +Return Value: a newly allocated matrix which is the transpose of A +Example: + MATRIX A, T; + + A = mat_creat( 3, 5, UNDEFINED ); + ... + T = mat_tran( A ); + ... + +See Also: mat_inv +------------------------------------------------------------------------------- + + + + +=============================================================================== +5. DETERMINANT OPERATIONS +=============================================================================== +------------------------------------------------------------------------------- +Function: MATRIX mat_submat (MATRIX A, int i, int j) +Synopsis: form a new matrix by deleting a row and a column of A +Parameter: A: allocated matrix + i, j: row and column of A which will not appear in the + resulting matrix +Return Value: a new matrix whose dimensions are 1 less than A +Example: + MATRIX A, B + + A = mat_creat( 3, 4, UNDEFINED ); + ... + B = mat_submat( A, 2, 2 ); + /* + * suppose A = [ 1 2 3 4 ] + * [ 3 3 4 5 ] + * [ 6 7 9 9 ] + * + * then B = [ 1 2 4 ] + * [ 3 3 5 ] + */ + +Note: Do not be misled -- the contents in A will NOT be changed +See Also: mat_det, mat_cofact, mat_minor +------------------------------------------------------------------------------- +Function: double mat_cofact (MATRIX A, int i, int j) +Synopsis: find out the cofactor of A(i,j) +Parameter: A: allocated square matrix + i,j: row, column position of A for the cofactor +Return Value: the value of cofactor of A(i,j) +Example: + MATRIX A; + + A = mat_creat( 5, 5, UNIT_MATRIX ); + ... + printf( "cofactor of A(0,2) = %f\n", mat_cofact( A, 0, 2 )); + +See Also: mat_det, mat_minor +------------------------------------------------------------------------------- +Function: double mat_minor (MATRIX A, int i, int j) +Synopsis: find out the minor of A(i,j) +Parameter: A: allocated square matrix + i,j: row, column position of A for the minor +Return Value: the value of minor of A(i,j) +Example: + MATRIX A; + + A = mat_creat( 5, 5, UNIT_MATRIX ); + ... + printf( "minor of A(0,2) = %f\n", mat_minor( A, 0, 2 )); + +See Also: mat_det, mat_cofact +------------------------------------------------------------------------------- +Function: double mat_det (MATRIX A) +Synopsis: find the determinant of a matrix +Parameter: A: allocated square matrix +Return Value: the determinant value of |A| +Example: + MATRIX A; + double det; + + A = mat_creat( 5, 5, UNIT_MATRIX ); + det = mat_det( A ); + +See Also: mat_cofact, mat_minor, mat_submat +------------------------------------------------------------------------------- + + + + +=============================================================================== +6. ADVANCED MATRIX OBJECT MATHEMATICAL OPERATION +=============================================================================== +------------------------------------------------------------------------------- +Function: MATRIX mat_lsolve (MATRIX A, MATRIX B) +Synopsis: solve simultaneous linear equation AX = B given A, B +Parameter: A, B: allocated matrix +Return Value: newly allocated matrix X in AX = B +Example: + MATRIX A, B, X; + + A = mat_creat( 5, 5, UNDEFINED ); + fgetmat( A, stdin ); + ... + B = mat_creat( 5, 1, UNDEFINED ); + fgetmat( B, stdin ); + ... + X = mat_lsolve( A, B ); + mat_dump( X ); + +Note: number of rows in A and B must be equal +See Also: mat_lsolve_durbin +------------------------------------------------------------------------------- +Function: MATRIX mat_lsolve_durbin (MATRIX A, MATRIX B) +Synopsis: simultaneous linear equations wtih Levinson-Durbin method +Parameter: A, B: allocated matrix where A is an autocorrelated matrix and + B is derived from A + + A, B must be the following forms: + + | a0 a1 a2 .. an-1 | | x1 | | a1 | + | a1 a0 a1 .. an-2 | | x2 | | a2 | + | a2 a1 a0 .. an-3 | | x3 | = | .. | + | ... | | .. | | .. | + | an-1 an-2 .. .. a0 | | xn | | an | + + where A is a symmetric Toeplitz matrix and B + in the above format (related to A) + +Return Value: a newly allocated matrix X which is the solution of AX = B + +Example: this method only applies to certain A, B only. + e.g. + + A = [1 3 9] B = [3] + [3 1 3] [9] + [9 3 1] [12] <- the last one is unrelated to A + +See Also: mat_SymToeplz +------------------------------------------------------------------------------- +Function: MATRIX mat_SymToeplz (MATRIX R); +Synopsis: create a symmetric Toeplitz matrix from a + Autocorrelation vector +Parameter: R: allocated matrix of dimension n x 1 +Return Value: a newly allocated symmetrical Toeplitz matrix +Example: + e.g. + + MATRIX A, R; + + R = mat_creat( 3, 1, UNDEFINED ); + ... + A = mat_SymToeplz( R ); + + /* + * if + * + * R = [1 3 9] A = [1 3 9] + * [3 1 3] + * [9 3 1] + * + */ + +See Also: mat_lsolve_durbin +------------------------------------------------------------------------------- diff --git a/matrix/READ.ME b/matrix/READ.ME new file mode 100644 index 00000000..89521113 --- /dev/null +++ b/matrix/READ.ME @@ -0,0 +1,112 @@ +------------------------------------------------------------------------------- + Small Matrix Toolbox for C programmers + version 0.42 + (Support Unix and DOS) + + by Patrick KO Shu-pui + + Copyright (c) 1992, 1993, 1994 All Rights Reserved. +------------------------------------------------------------------------------- +ADDRESS TO CONTACT: + + fidonet: 6:700/132 BiG Programming Club + [852] 663-0223 19.2 kbps + [852] 663-0236 16.8 kbps + + internet: pko@hk.super.net + + mailing: Patrick Ko + G.P.O. Box 7468 + Hong Kong +------------------------------------------------------------------------------- +MATRX042.ZIP contains + +READ .ME - this file +DEMO .C - demo how to use this package +DEMO .DAT - demo data +DEMO .EXE - demo executable for DOS +MAKEFILE.MSC - makefile for Microsoft C/C++ 7.0 on DOS +MAKEFILE.TC - makefile for Turbo C 2.0 on DOS +MAKEFILE.UX - makefile for Unix +MATRIX .DOC - matrix toolbox interface document +MATRIX .H - matrix header file (must include it) +MATADD .C - matrix addition +MATCREAT.C - matrix creation +MATDET .C - find minor, cofactor, determinant +MATDUMP .C - matrix dump +MATERR .C - matrix error handling routine +MATINV .C - matrix inversion +MATMUL .C - matrix multiplication +MATSOLVE.C - linear equations solver +MATSUB .C - matrix substraction +MATSUBX .C - submatrix operation +MATTOEPZ.C - create symmetric Toeplitz matrix +MATDURBN.C - Symmetrix Toeplitz matrix fast solving algorithm +MATTRAN .C - matrix transpose + +------------------------------------------------------------------------------- +WHATS NEW in v0.1: + - +, -, *, inverse matrix operations + +WHATS NEW in v0.2: + - Linear equation solver + - C-programmer-friendly C sources + +WHATS NEW in v0.3: + - better data structure (more Object-Oriented) + - finding minors, cofactors, determinants + - Levinson-Durbin algorithm for symmetric Toeplitz matrix + +WHATS NEW in v0.4: + - Revised method for minors, cofactors and determinants + whose time complexity is T(n^3) instead of nearly T(n!). + This is important when you want to find the determinant + of a matrix whose size is over 10 x 10. + - submatrix operator + - matrix formmated dump function + - brief matrix toolbox interface document included + +WHATS NEW in v0.41: + - bug fix for unit matrix creation + +WHATS NEW in v0.42: + - support Microsoft C/C++ 7.0 + +HOW TO COMPILE: + + 1. All Unix environment - make -f makefile.ux + 2. DOS (Turbo C v2.0) - make -fmakefile.tc + 3. DOS (Microsoft C/C++ v7.0) - nmake -fmakefile.msc + +REFERENCES + + [1] Mary L.Boas, "Mathematical Methods in the Physical Sciene," + John Wiley & Sons, 2nd Ed., 1983. Chap 3. + + [2] Kendall E.Atkinson, "An Introduction to Numberical Analysis," + John Wiley & Sons, 1978. + + [3] Shuzo Saito, Kazuo Nakata, "Fundamentals of Speech Signal + Processing," Academic Press, 1985. + + [4] Alfred V.Aho, John E.Hopcroft, Jeffrey D.Ullman, "The Design + and Analysis of Computer Algorithms," 1974. + +AUTHOR +All the sources are written by Patrick KO Shu Pui +BiG Programming Club (6:700/132, fidonet) + +=============================================================================== +AUTHORIZATION NOTICE + +This C source package MATRX042.ZIP is FREE for ACADEMIC purpose only. + +For COMMERCIAL use, authorization is required from the author. +Please send US$25 for registration. +=============================================================================== +DISCLAIMER (I hate this but I have to do that) + +You are on your own risk - the author is not responsible for any lost due +to the use of this toolbox. +=============================================================================== + diff --git a/matrix/demo.c b/matrix/demo.c new file mode 100644 index 00000000..8658ce01 --- /dev/null +++ b/matrix/demo.c @@ -0,0 +1,92 @@ +/* +*----------------------------------------------------------------------------- +* file: demo.c +* desc: demostrate how to use Patrick's matrix toolbox +* by: ko shu pui, patrick +* date: 24 nov 91 v0.1 +* revi: 14 may 92 v0.2 +* 24 may 92 v0.4 +* ref: +* [1] Mary L.Boas, "Mathematical Methods in the Physical Sciene," +* John Wiley & Sons, 2nd Ed., 1983. Chap 3. +* +* [2] Kendall E.Atkinson, "An Introduction to Numberical Analysis," +* John Wiley & Sons, 1978. +* +* [3] Alfred V.Aho, John E.Hopcroft, Jeffrey D.Ullman, "The Design +* and Analysis of Computer Algorithms," 1974. +* +*----------------------------------------------------------------------------- +*/ +#include +#include +#include "matrix.h" + +int main() +{ + MATRIX A, B, X, M; + FILE *fp; + double result; + time_t t1, t2; + int tinv, tdet, tmul; + + A = mat_creat( 10, 10, UNDEFINED ); + B = mat_creat( 10, 1, UNDEFINED ); + + if ((fp = fopen( "demo.dat", "r" )) == NULL) + { + fprintf( stderr, "file cannot be opened\n" ); + exit (0); + } + + fgetmat( A, fp ); + printf( "|- Matrix A -|\n"); + mat_dumpf( A, "%+06.1f " ); + + t1 = time(&t1); + result = mat_det(A); + t2 = time(&t2); + tdet = t2 - t1; + printf( "\n\nDet(A) = %f\n", result ); + + printf( "|- Inv A -|\n"); + t1 = time(&t1); + X = mat_inv( A ); + t2 = time(&t2); + tinv = t2 - t1; + + if (X == NULL) + printf( "A is a singular matrix\n" ); + else + { + mat_dumpf(X, "%+06.1f "); + + printf( "|- A x Inv A -|\n"); + t1 = time(&t1); + M = mat_mul( X, A ); + t2 = time(&t2); + tmul = t2 - t1; + mat_dumpf( M, "%+06.1f " ); + + mat_free(M); + mat_free(X); + } + + fgetmat( B, fp ); + printf( "|- Matrix B -|\n"); + mat_dumpf( B, "%+06.1f " ); + + printf( "|- A x B -|\n"); + mat_free(mat_dumpf(mat_mul(A, B), "%+06.1f ")); + + printf( "time for finding 10 x 10 matrix inversion is less than %d secs\n", tinv ); + printf( "time for finding 10 x 10 matrix determinant is less than %d secs\n", tdet ); + printf( "time for finding 10 x 10 matrix multiplication is less than %d secs\n", tmul ); + + mat_free( A ); + mat_free( B ); + + fclose(fp); + +} + \ No newline at end of file diff --git a/matrix/matadd.c b/matrix/matadd.c new file mode 100644 index 00000000..ff1e9bf9 --- /dev/null +++ b/matrix/matadd.c @@ -0,0 +1,43 @@ +/* +*----------------------------------------------------------------------------- +* file: matadd.c +* desc: matrix addition +* by: ko shu pui, patrick +* date: 24 nov 91 v0.1 +* revi: +* ref: +* [1] Mary L.Boas, "Mathematical Methods in the Physical Sciene," +* John Wiley & Sons, 2nd Ed., 1983. Chap 3. +* +*----------------------------------------------------------------------------- +*/ +#include +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_add +* desct: addition of two matrice +* given: A, B = Compatible matrice to be added +* retrn: NULL if malloc() fails +* else allocated matrix of A + B +* comen: +*----------------------------------------------------------------------------- +*/ +MATRIX mat_add( A, B ) +MATRIX A, B; +{ + int i, j; + MATRIX C; + + if ((C = mat_creat( MatRow(A), MatCol(A), UNDEFINED )) == NULL) + return (NULL); + + for (i=0; i + +#ifdef __TURBOC__ +#include +#else +#include +#endif + +#include "matrix.h" + +MATRIX _mat_creat( row, col ) +int row, col; +{ + MATBODY *mat; + int i, j; + + if ((mat = (MATBODY *)malloc( sizeof(MATHEAD) + sizeof(double *) * row)) == NULL) + return (mat_error( MAT_MALLOC )); + + for (i=0; imatrix) + i) = (double *)malloc(sizeof(double) * col)) == NULL) + return (mat_error( MAT_MALLOC )); + } + + mat->head.row = row; + mat->head.col = col; + + return (&(mat->matrix)); +} + +/* +*----------------------------------------------------------------------------- +* funct: mat_creat +* desct: create a matrix +* given: row, col = dimension, type = which kind of matrix +* retrn: allocated matrix (use mat_free() to free memory) +*----------------------------------------------------------------------------- +*/ +MATRIX mat_creat( row, col, type ) +int row, col, type; +{ + MATRIX A; + + if ((A =_mat_creat( row, col )) != NULL) + { + return (mat_fill(A, type)); + } + else + return (NULL); +} + +/* +*----------------------------------------------------------------------------- +* funct: mat_fill +* desct: form a special matrix +* given: A = matrix, type = which kind of matrix +* retrn: A +*----------------------------------------------------------------------------- +*/ +MATRIX mat_fill( A, type ) +MATRIX A; +int type; +{ + int i, j; + + switch (type) + { + case UNDEFINED: + break; + case ZERO_MATRIX: + case UNIT_MATRIX: + for (i=0; i +*----------------------------------------------------------------------------- +*/ +int mat_free( A ) +MATRIX A; +{ + int i; + + if (A == NULL) + return (0); + for (i=0; i +#include "matrix.h" + +static double signa[2] = {1.0, -1.0}; + +/* +*----------------------------------------------------------------------------- +* funct: mat_minor +* desct: find minor +* given: A = a square matrix, +* i=row, j=col +* retrn: the minor of Aij +*----------------------------------------------------------------------------- +*/ +double mat_minor( A, i, j ) +MATRIX A; +int i, j; +{ + MATRIX S; + double result; + + S = mat_submat(A, i, j); + result = mat_det( S ); + mat_free(S); + + return (result); + +} + +/* +*----------------------------------------------------------------------------- +* funct: mat_cofact +* desct: find cofactor +* given: A = a square matrix, +* i=row, j=col +* retrn: the cofactor of Aij +*----------------------------------------------------------------------------- +*/ +double mat_cofact( A, i, j ) +MATRIX A; +int i, j; +{ + double result; + + result = signa[(i+j)%2] * A[i][j] * mat_minor(A, i, j); + + return (result); +} + +/* +*----------------------------------------------------------------------------- +* funct: mat_det +* desct: find determinant +* given: A = matrix +* retrn: the determinant of A +* comen: +*----------------------------------------------------------------------------- +*/ +double mat_det( a ) +MATRIX a; +{ + MATRIX A, P; + int i, j, n; + double result; + + n = MatRow(a); + A = mat_copy(a); + P = mat_creat(n, 1, UNDEFINED); + + /* + * take a LUP-decomposition + */ + i = mat_lu(A, P); + switch (i) + { + /* + * case for singular matrix + */ + case -1: + result = 0.0; + break; + + /* + * normal case: |A| = |L||U||P| + * |L| = 1, + * |U| = multiplication of the diagonal + * |P| = +-1 + */ + default: + result = 1.0; + for (j=0; j +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_dump +* desct: dump a matrix +* given: A = matrice to dumped +* retrn: nothing +* comen: matrix a dumped to standard output +*----------------------------------------------------------------------------- +*/ +MATRIX mat_dump( A ) +MATRIX A; +{ + return(mat_fdumpf(A, "%f ", stdout)); +} + +/* +*----------------------------------------------------------------------------- +* funct: mat_dumpf +* desct: dump a matrix with format string to standard output +* given: A = matrice to dumped +* retrn: nothing +* comen: matrix a dumped to standard output +*----------------------------------------------------------------------------- +*/ +MATRIX mat_dumpf( A, s ) +MATRIX A; +char *s; +{ + return (mat_fdumpf(A, s, stdout)); +} + +MATRIX mat_fdump( A, fp ) +MATRIX A; +FILE *fp; +{ + return (mat_fdumpf(A, "%f ", fp)); +} + +MATRIX mat_fdumpf( A, s, fp ) +MATRIX A; +char *s; +FILE *fp; +{ + int i, j; + + for (i=0; i + +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_durbin +* desct: Levinson-Durbin algorithm +* +* This function solve the linear eqns Ax = B: +* +* | v0 v1 v2 .. vn-1 | | a1 | | v1 | +* | v1 v0 v1 .. vn-2 | | a2 | | v2 | +* | v2 v1 v0 .. vn-3 | | a3 | = | .. | +* | ... | | .. | | .. | +* | vn-1 vn-2 .. .. v0 | | an | | vn | +* +* where A is a symmetric Toeplitz matrix and B +* in the above format (related to A) +* +* given: R = autocorrelated matrix (v0, v1, ... vn) (dim (n+1) x 1) +* retrn: x (of Ax = B) +*----------------------------------------------------------------------------- +*/ +MATRIX mat_durbin( R ) +MATRIX R; +{ + int i, i1, j, ji, p, n; + MATRIX W, E, K, A, X; + + p = MatRow(R) - 1; + W = mat_creat( p+2, 1, UNDEFINED ); + E = mat_creat( p+2, 1, UNDEFINED ); + K = mat_creat( p+2, 1, UNDEFINED ); + A = mat_creat( p+2, p+2, UNDEFINED ); + + W[0][0] = R[1][0]; + E[0][0] = R[0][0]; + + for (i=1; i<=p; i++) + { + K[i][0] = W[i-1][0] / E[i-1][0]; + E[i][0] = E[i-1][0] * (1.0 - K[i][0] * K[i][0]); + + A[i][i] = -K[i][0]; + + i1 = i-1; + if (i1 >= 1) + { + for (j=1; j<=i1; j++) + { + ji = i - j; + A[j][i] = A[j][i1] - K[i][0] * A[ji][i1]; + } + } + + if (i != p) + { + W[i][0] = R[i+1][0]; + for (j=1; j<=i; j++) + W[i][0] += A[j][i] * R[i-j+1][0]; + } + } + + X = mat_creat( p, 1, UNDEFINED ); + for (i=0; i + +#ifdef __TURBOC__ +#include +#else +#include +#endif + +#include "matrix.h" + +MATRIX mat_error( errno ) +int errno; +{ + switch( errno ) + { + case MAT_MALLOC: + fprintf(stderr, "mat: malloc error\n" ); + break; + case MAT_FNOTOPEN: + fprintf(stderr, "mat: fileopen error\n" ); + break; + case MAT_FNOTGETMAT: + fprintf(stderr, "fgetmat: matrix read error\n"); + break; + } + + return (NULL); +} + + \ No newline at end of file diff --git a/matrix/matinv.c b/matrix/matinv.c new file mode 100644 index 00000000..1c134e01 --- /dev/null +++ b/matrix/matinv.c @@ -0,0 +1,77 @@ +/* +*----------------------------------------------------------------------------- +* file: matinv.c +* desc: matrix inversion +* by: ko shu pui, patrick +* date: 24 nov 91 v0.1 +* revi: 14 may 92 v0.2 +* ref: +* [1] Mary L.Boas, "Mathematical Methods in the Physical Sciene," +* John Wiley & Sons, 2nd Ed., 1983. Chap 3. +* +* [2] Kendall E.Atkinson, "An Introduction to Numberical Analysis," +* John Wiley & Sons, 1978. +* +*----------------------------------------------------------------------------- +*/ +#include +#include + +#ifdef __TURBOC__ +#include +#else +#include +#endif + +#include "matrix.h" + + +/* +*----------------------------------------------------------------------------- +* funct: mat_inv +* desct: find inverse of a matrix +* given: a = square matrix a +* retrn: square matrix Inverse(A) +* NULL = fails, singular matrix, or malloc() fails +*----------------------------------------------------------------------------- +*/ +MATRIX mat_inv( a ) +MATRIX a; +{ + MATRIX A, B, C, P; + int i, j, n; + double temp; + + n = MatCol(a); + A = mat_copy(a); + B = mat_creat( n, 1, UNDEFINED ); + C = mat_creat( n, n, UNDEFINED ); + P = mat_creat( n, 1, UNDEFINED ); + + /* + * - LU-decomposition - + * also check for singular matrix + */ + if (mat_lu(A, P) == -1) + { + mat_free(A); + mat_free(B); + mat_free(C); + mat_free(P); + + return (NULL); + } + + for (i=0; i +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_mul +* desct: multiplication of two matrice +* given: A, B = compatible matrice to be multiplied +* retrn: NULL if malloc() fails +* else allocated matrix of A * B +* comen: +*----------------------------------------------------------------------------- +*/ +MATRIX mat_mul( A, B ) +MATRIX A, B; +{ + int i, j, k; + MATRIX C; + + if ((C = mat_creat( MatRow(A), MatCol(B), UNDEFINED )) == NULL) + return (NULL); + + for (i=0; irow) +#define MatCol(a) (Mathead(a)->col) + +/* +*---------------------------------------------------------------------------- +* mat_errors definitions +*---------------------------------------------------------------------------- +*/ +#define MAT_MALLOC 1 +#define MAT_FNOTOPEN 2 +#define MAT_FNOTGETMAT 3 + +/* +*---------------------------------------------------------------------------- +* matrice types +*---------------------------------------------------------------------------- +*/ +#define UNDEFINED -1 +#define ZERO_MATRIX 0 +#define UNIT_MATRIX 1 + + +/* prototypes of matrix package */ +#ifndef NOPROTO + +MATRIX mat_error (int); +MATRIX _mat_creat (int, int); +MATRIX mat_creat (int, int, int); +MATRIX mat_fill (MATRIX, int); +int mat_free (MATRIX); +MATRIX mat_copy (MATRIX); +MATRIX mat_colcopy1 (MATRIX, MATRIX, int, int); +int fgetmat (MATRIX, FILE *); +MATRIX mat_dump (MATRIX); +MATRIX mat_dumpf (MATRIX, char *); +MATRIX mat_fdump (MATRIX, FILE *); +MATRIX mat_fdumpf (MATRIX, char *, FILE *); + +MATRIX mat_add (MATRIX, MATRIX); +MATRIX mat_sub (MATRIX, MATRIX); +MATRIX mat_mul (MATRIX, MATRIX); +double mat_diagmul (MATRIX); +MATRIX mat_tran (MATRIX); +MATRIX mat_inv (MATRIX); +MATRIX mat_SymToeplz (MATRIX); + +int mat_lu (MATRIX, MATRIX); +MATRIX mat_backsubs1 (MATRIX, MATRIX, MATRIX, MATRIX, int); +MATRIX mat_lsolve (MATRIX, MATRIX); + +MATRIX mat_submat (MATRIX, int, int); +double mat_cofact (MATRIX, int, int); +double mat_det (MATRIX); +double mat_minor (MATRIX, int, int); + +MATRIX mat_durbin (MATRIX); +MATRIX mat_lsolve_durbin(MATRIX, MATRIX); +#else + +MATRIX mat_error (); +MATRIX _mat_creat (); +MATRIX mat_creat (); +MATRIX mat_fill (); +int mat_free (); +MATRIX mat_copy (); +MATRIX mat_colcopy1 (); +int fgetmat (); +MATRIX mat_dumpf (); +MATRIX mat_dump (); +MATRIX mat_fdump (); +MATRIX mat_fdumpf (); + +MATRIX mat_add (); +MATRIX mat_sub (); +MATRIX mat_mul (); +double mat_diagmul (); +MATRIX mat_tran (); +MATRIX mat_inv (); +MATRIX mat_SymToeplz (); + +int mat_lu (); +MATRIX mat_backsubs1 (); +MATRIX mat_lsolve (); + +MATRIX mat_submat (); +double mat_cofact (); +double mat_det (); +double mat_minor (); + +MATRIX mat_durbin (); +MATRIX mat_lsolve_durbin(); +#endif + +#endif + + + + diff --git a/matrix/matsolve.c b/matrix/matsolve.c new file mode 100644 index 00000000..9a2f61e8 --- /dev/null +++ b/matrix/matsolve.c @@ -0,0 +1,182 @@ +/* +*----------------------------------------------------------------------------- +* file: matsolve.c +* desc: solve linear equations +* by: ko shu pui, patrick +* date: 24 nov 91 v0.1 +* revi: 14 may 92 v0.2 +* ref: +* [1] Mary L.Boas, "Mathematical Methods in the Physical Sciene," +* John Wiley & Sons, 2nd Ed., 1983. Chap 3. +* +* [2] Kendall E.Atkinson, "An Introduction to Numberical Analysis," +* John Wiley & Sons, 1978. +* +*----------------------------------------------------------------------------- +*/ +#include +#include + +#ifdef __TURBOC__ +#include +#else +#include +#endif + +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_lu +* desct: in-place LU decomposition with partial pivoting +* given: !! A = square matrix (n x n) !ATTENTION! see commen +* P = permutation vector (n x 1) +* retrn: number of permutation performed +* -1 means suspected singular matrix +* comen: A will be overwritten to be a LU-composite matrix +* +* note: the LU decomposed may NOT be equal to the LU of +* the orignal matrix a. But equal to the LU of the +* rows interchanged matrix. +*----------------------------------------------------------------------------- +*/ +int mat_lu( A, P ) +MATRIX A; +MATRIX P; +{ + int i, j, k, n; + int maxi, tmp; + double c, c1; + int p; + + n = MatCol(A); + + for (p=0,i=0; i c) + { + c = c1; + maxi = i; + } + } + + /* + * row exchange, update permutation vector + */ + if (k != maxi) + { + p++; + tmp = P[k][0]; + P[k][0] = P[maxi][0]; + P[maxi][0] = tmp; + } + + /* + * suspected singular matrix + */ + if ( A[(int)P[k][0]][k] == 0.0 ) + return (-1); + + for (i=k+1; i=0; k--) + { + sum = 0.0; + for (j=k+1; j +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_sub +* desct: subtraction of two matrice +* given: A, B = compatible matrice to be added +* retrn: NULL if malloc() fails +* else allocated matrix of A - B +* comen: +*----------------------------------------------------------------------------- +*/ +MATRIX mat_sub( A, B ) +MATRIX A, B; +{ + int i, j; + MATRIX C; + + if ((C = mat_creat( MatRow(A), MatCol(A), UNDEFINED )) == NULL) + return (NULL); + + for (i=0; i +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_submat +* desct: return a submatrix S of A +* given: A = main matrix, +* i,j = row and column of A to be deleted to obtained S +* retrn: S +*----------------------------------------------------------------------------- +*/ +MATRIX mat_submat( A, i, j ) +MATRIX A; +int i,j; +{ + int m, m1, p, p1; + MATRIX S; + + S = mat_creat(MatRow(A)-1, MatCol(A)-1, UNDEFINED); + + for (m=m1=0; m + +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_SymToeplz +* desct: create a n x n symmetric Toeplitz matrix from +* a n x 1 correlation matrix +* given: R = correlation matrix (n x 1) +* retrn: the symmetric Toeplitz matrix +*----------------------------------------------------------------------------- +*/ +MATRIX mat_SymToeplz( R ) +MATRIX R; +{ + int i, j, n; + MATRIX T; + + n = MatRow(R); + T = mat_creat(n, n, UNDEFINED); + + for (i=0; i +#include "matrix.h" + +/* +*----------------------------------------------------------------------------- +* funct: mat_tran +* desct: transpose of a matrix +* given: A = matrix A to be transposed +* retrn: allocated matrix for A^t +* comen: +*----------------------------------------------------------------------------- +*/ +MATRIX mat_tran( A ) +MATRIX A; +{ + int i, j; + MATRIX At; + + if ((At = mat_creat( MatCol(A), MatRow(A), UNDEFINED )) == NULL) + return (NULL); + + /* + * Transposing ... + */ + for (i=0; i +#include +#include +#include "fortify.h" +#include "sics.h" +#include "stringdict.h" +#include "hardsup/serialsinq.h" +#include "hardsup/el734_errcodes.h" +#include "hardsup/el734fix.h" +#include "codri.h" + +/*----------------------------------------------------------------------- + A private data structure for the SANS cooker +-------------------------------------------------------------------------*/ + typedef struct { + char *pHost; + int iPort; + int iChannel; + void *pData; + int iStop; + int iError; + } SANSCook, *pSANSCook; +/* + pHost, iPort and iChannel combined are the adress of the cooker + controller at the Macintosh terminal server. pData is the serial + port connection data structure needed and managed by the SerialIO + functions. + + iError is the last error reported on this device. If no error: 0 + +-----------------------------------------------------------------------*/ + +/* + ERROR CODES: +*/ + +#define NOTINIT -9001 +#define POWEROFF -9002 +#define LOWRANGE -9003 +#define HIGHRANGE -9004 +#define CONTIMEOUT -9005 +#define BADCOMMAND -9006 +#define NOANSWER -9007 +#define BADINPUT -9008 +#define MOTERROR -9009 +#define CONBUSY -9010 +#define BADREPLY -9011 + +/*-------------------------------------------------------------------------*/ + static int CookerInit(pCodri self) + { + pSANSCook pPriv = NULL; + int iRet; + char pReply[131]; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + pPriv->iError = 0; + + /* first open the connection to the serial port server and channel */ + iRet = SerialOpen(&(pPriv->pData),pPriv->pHost,pPriv->iPort, + pPriv->iChannel); + if(iRet <= 0) + { + pPriv->iError = iRet; + return 0; + } + /* configure the connection */ + SerialATerm(&(pPriv->pData),"1\r\n"); + SerialSendTerm(&(pPriv->pData),"\r"); + + pPriv->iStop = 0; + + /* switch everything on, but do not deal with errors here */ + /* + SerialWriteRead(&(pPriv->pData),"mpon",pReply,131); + SerialWriteRead(&(pPriv->pData),"mzon",pReply,131); + SerialWriteRead(&(pPriv->pData),"ton",pReply,131); + */ + + return 1; + } +/*------------------------------------------------------------------------*/ + static int CookerClose(pCodri self) + { + pSANSCook pPriv = NULL; + int iRet; + long lVal; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + + if(pPriv->pData) + { + SerialClose(&(pPriv->pData)); + pPriv->pData = NULL; + } + return 1; + } +/*-----------------------------------------------------------------------*/ + static int CookerDelete(pCodri self) + { + pSANSCook pPriv = NULL; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + + if(pPriv->pData) + { + SerialClose(&(pPriv->pData)); + pPriv->pData = NULL; + } + + if(pPriv->pHost) + free(pPriv->pHost); + + free(pPriv); + + return 1; + } +/*-----------------------------------------------------------------------*/ + static int CookerSetPar(pCodri self, char *parname, float fValue) + { + pSANSCook pPriv = NULL; + char pCommand[80], pReply[132]; + int iRet, iValue; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + pPriv->iError = 0; + + /* handle the numeric parameters */ + iValue = (int)fValue; + + if(strcmp(parname,"mp") == 0) + { + sprintf(pCommand,"mps%3.3d",iValue); + } + else if(strcmp(parname,"mz") == 0) + { + sprintf(pCommand,"mzs%3.3d",iValue); + } + else if(strcmp(parname,"ts") == 0) + { + sprintf(pCommand,"ts%3.3d",iValue); + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + /* send command and check for errors right here */ + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,131); + if(iRet != 1) + { + pPriv->iError = iRet; + return 0; + } + else + { + if(strstr(pReply,"Error") != NULL) + { + pPriv->iError = MOTERROR; + return 0; + } + if(strstr(pReply,"Power OFF") != NULL) + { + pPriv->iError = POWEROFF; + return 0; + } + if(strstr(pReply,"not init.") != NULL) + { + pPriv->iError = NOTINIT ; + return 0; + } + if(strstr(pReply,"Timeout") != NULL) + { + pPriv->iError = CONTIMEOUT ; + return 0; + } + if(strstr(pReply,"Busy") != NULL) + { + pPriv->iError = CONBUSY ; + return 0; + } + if( (strstr(pReply,"Max") != NULL) || (strstr(pReply,"high") != NULL) ) + { + pPriv->iError = HIGHRANGE; + return 0; + } + if( (strstr(pReply,"Min") != NULL) || (strstr(pReply,"down") != NULL) ) + { + pPriv->iError = LOWRANGE; + return 0; + } + return 1; + } + + + } +/*------------------------------------------------------------------------*/ + static int CookerSetPar2(pCodri self, char *parname, char *pValue) + { + pSANSCook pPriv = NULL; + char pCommand[80], pReply[132]; + int iRet, iAct = 0; + float fValue; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + pPriv->iError = 0; + + /* handle our parameters. The first set is the power settings */ + if(strcmp(parname,"mp.power") == 0) + { + if(strstr(pValue,"on") != NULL) + { + strcpy(pCommand,"mpon"); + iAct = 1; + } + else if(strstr(pValue,"off") != NULL) + { + strcpy(pCommand,"mpoff"); + iAct = 1; + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + } + else if(strcmp(parname,"mz.power") == 0) + { + if(strstr(pValue,"on") != NULL) + { + strcpy(pCommand,"mzon"); + iAct = 1; + } + else if(strstr(pValue,"off") != NULL) + { + strcpy(pCommand,"mzoff"); + iAct = 1; + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + } + else if(strcmp(parname,"ts.power") == 0) + { + if(strstr(pValue,"on") != NULL) + { + iAct = 1; + strcpy(pCommand,"ton"); + } + else if(strstr(pValue,"off") != NULL) + { + iAct = 1; + strcpy(pCommand,"toff"); + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + } + if(iAct == 1) + { + /* send command and check for errors right here */ + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,131); + if(iRet != 1) + { + pPriv->iError = iRet; + return 0; + } + else + { + if(strstr(pReply,"Error") != NULL) + { + pPriv->iError = MOTERROR; + return 0; + } + return 1; + } + } + + + /* second set: init */ + if(strcmp(parname,"mp.init") == 0) + { + strcpy(pCommand,"mpi"); + iAct = 1; + } + else if(strcmp(parname,"mz.init") == 0) + { + strcpy(pCommand,"mzi"); + iAct = 1; + } + if(iAct) + { + /* send command and check for errors right here */ + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,131); + if(iRet != 1) + { + pPriv->iError = iRet; + return 0; + } + else + { + if(strstr(pReply,"Error") != NULL) + { + pPriv->iError = MOTERROR; + return 0; + } + return 1; + } + } + + /* + what is left here is either the para's themselves which will be + handled in the second function after convertion to float or an + error + */ + iRet = sscanf(pValue,"%f",&fValue); + if(iRet != 1) + { + pPriv->iError = BADINPUT; + return; + } + + return CookerSetPar(self,parname,fValue); + } +/*-----------------------------------------------------------------------*/ + static int CookerHalt(pCodri self) + { + pSANSCook pPriv = NULL; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + pPriv->iError = 0; + + /* no commands are defined to halt a thing! */ + return 1; + } +/*----------------------------------------------------------------------*/ +extern char *stptok(const char *s, char *tok, size_t toklen, char *brk); + + static int CookerGetPar(pCodri self, char *parname, + char *pBuffer, int iLen) + { + pSANSCook pPriv = NULL; + char pBueffel[256], pCommand[80], pReply[80]; + float fVal; + char *pPtr; + int iAct = 0, iRet; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + pPriv->iError = 0; + + /* first the power stuff */ + if(strcmp(parname,"mp.power") == 0 || strcmp(parname,"mp.init") == 0) + { + strcpy(pBueffel,parname); + strcpy(pCommand,"mps"); + iAct = 1; + } + else if(strcmp(parname,"mz.power") == 0 || strcmp(parname,"mz.init") ==0 ) + { + strcpy(pBueffel,parname); + strcpy(pCommand,"mzs"); + iAct = 1; + } + else if(strcmp(parname,"ts.power") == 0) + { + strcpy(pBueffel,parname); + strcpy(pCommand,"ts"); + iAct = 1; + } + if(iAct) + { + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,80); + if(iRet != 1) + { + pPriv->iError = iRet; + return 0; + } + else + { + if( strstr(pReply,"OFF") != NULL || strstr(pReply,"Off") != NULL) + { + strcat(pBueffel," off"); + } + else if(strstr(pReply,"not init") != NULL) + { + strcat(pBueffel," not"); + } + else + { + strcat(pBueffel," on"); + } + + } + strncpy(pBuffer,pBueffel,iLen); + return 1; + } + + /* now request values for the parameter */ + if(strcmp(parname,"mp") == 0) + { + strcpy(pCommand,"mps"); + } + else if(strcmp(parname,"mz") == 0) + { + strcpy(pCommand,"mzs"); + } + else if(strcmp(parname,"ts") == 0) + { + strcpy(pCommand,"ts"); + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,80); + if(iRet != 1) + { + pPriv->iError = iRet; + return 0; + } + /* decode value */ + pPtr = pReply; + pPtr = stptok(pPtr,pBueffel,255,"/\0"); + pPtr = stptok(pPtr,pBueffel,255,"/\0"); + iRet = sscanf(pBueffel,"%f",&fVal); + if(iRet != 1) + { + pPriv->iError = BADREPLY; + return 0; + } + sprintf(pBueffel,"%f",fVal); + strncpy(pBuffer,pBueffel,iLen); + return 1; + } +/*-----------------------------------------------------------------------*/ + static int CookerCheckPar(pCodri self, char *parname) + { + pSANSCook pPriv = NULL; + char pCommand[80], pReply[80]; + int iRet; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + + if(strcmp(parname,"mp") == 0) + { + strcpy(pCommand,"mps"); + } + else if(strcmp(parname,"mz")) + { + strcpy(pCommand,"mzs"); + } + else + { + pPriv->iError = BADINPUT; + return 0; + } + + /* get a status reply */ + iRet = SerialWriteRead(&(pPriv->pData),pCommand,pReply,80); + if(iRet != 1) + { + pPriv->iError = iRet; + return HWFault; + } + + if( strstr(pReply,"Start") != NULL || strstr(pReply,"Move") != NULL ) + { + return HWBusy; + } + else + { + return HWIdle; + } + return HWIdle; + } +/*---------------------------------------------------------------------*/ + static int CookerError(pCodri self, int *iCode, char *pError, int iLen) + { + pSANSCook pPriv = NULL; + char pCommand[80], pReply[80]; + int iRet; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + + *iCode = pPriv->iError; + switch(pPriv->iError) + { + case NOTINIT: + strncpy(pError,"ERROR: NOT Initialized!",iLen); + break; + case POWEROFF: + strncpy(pError,"ERROR: Power is OFF",iLen); + break; + case LOWRANGE: + strncpy(pError,"ERROR: Lower limit violated",iLen); + break; + case HIGHRANGE: + strncpy(pError,"ERROR: Upper limit violated",iLen); + break; + case CONTIMEOUT: + strncpy(pError,"ERROR: Internal controller timeout ",iLen); + break; + case BADCOMMAND: + strncpy(pError,"ERROR: Controller did not understand command",iLen); + break; + case BADINPUT: + strncpy(pError,"A bad parameter was entered",iLen); + break; + case MOTERROR: + strncpy(pError,"ERROR: Iternal motor error in controller",iLen); + break; + case CONBUSY: + strncpy(pError,"ERROR: Controller is busy",iLen); + break; + default: + SerialError(pPriv->iError,pError,iLen); + break; + } + pPriv->iError = 0; + return 1; + } +/*----------------------------------------------------------------------*/ + static int CookerFix(pCodri self, int iCode) + { + pSANSCook pPriv = NULL; + int iRet; + + assert(self); + pPriv = (pSANSCook)self->pPrivate; + assert(pPriv); + + switch(iCode) + { + case NOTINIT: + case POWEROFF: + case LOWRANGE: + case HIGHRANGE: + case BADCOMMAND: + case BADINPUT: + case MOTERROR: + return CHFAIL; + case CONTIMEOUT: + case CONBUSY: + return CHREDO; + /* network errors */ + case EL734__BAD_FLUSH: + case EL734__BAD_RECV: + case EL734__BAD_RECV_NET: + case EL734__BAD_RECV_UNKN: + case EL734__BAD_RECVLEN: + case EL734__BAD_RECV1: + case EL734__BAD_RECV1_PIPE: + case EL734__BAD_RNG: + case EL734__BAD_SEND: + case EL734__BAD_SEND_PIPE: + case EL734__BAD_SEND_NET: + case EL734__BAD_SEND_UNKN: + case EL734__BAD_SENDLEN: + case NOCONNECTION: + SerialForceClose(&(pPriv->pData)); + pPriv->pData = NULL; + iRet = SerialOpen(&(pPriv->pData),pPriv->pHost, + pPriv->iPort,pPriv->iChannel); + if(iRet == 1 ) + { + return CHREDO; + } + else + { + return CHFAIL; + } + break; + case EL734__FORCED_CLOSED: + iRet = CookerInit(self); + if(iRet) + { + return CHREDO; + } + else + { + return CHFAIL; + } + break; + default: + return CHFAIL; + break; + + } + } +/*------------------------------------------------------------------------*/ + pCodri MakeCookerDriver(char *pHost, int iPort, int iChannel) + { + pCodri pNew = NULL; + pSANSCook pPriv = NULL; + char *pText; + + /* allocate memory */ + pText = (char *)malloc(1024*sizeof(char)); + pNew = (pCodri)malloc(sizeof(Codri)); + pPriv = (pSANSCook)malloc(sizeof(SANSCook)); + if( !pText || !pNew || !pPriv) + { + return NULL; + } + memset(pText,0,1024); + memset(pNew,0,sizeof(Codri)); + memset(pPriv,0,sizeof(SANSCook)); + + /* initialize private data structure */ + pPriv->pHost = strdup(pHost); + pPriv->iPort = iPort; + pPriv->iChannel = iChannel; + pPriv->pData = NULL; + + /* set known parameter names */ + strcpy(pText,"mp"); + strcat(pText,",mp.power"); + strcat(pText,",mp.init"); + strcat(pText,",mz"); + strcat(pText,",mz.power"); + strcat(pText,",mz.init"); + strcat(pText,",ts"); + strcat(pText,",ts.power"); + + + /* install codri */ + pNew->Init = CookerInit; + pNew->Close = CookerClose; + pNew->Delete = CookerDelete; + pNew->SetPar = CookerSetPar; + pNew->SetPar2 = CookerSetPar2; + pNew->GetPar = CookerGetPar; + pNew->CheckPar = CookerCheckPar; + pNew->GetError = CookerError; + pNew->TryFixIt = CookerFix; + pNew->Halt = CookerHalt; + pNew->pParList = pText; + pNew->pPrivate = pPriv; + + return pNew; + } + + + + + diff --git a/sicsstatus.tcl b/sicsstatus.tcl index 2a13e85b..4267fa8f 100644 --- a/sicsstatus.tcl +++ b/sicsstatus.tcl @@ -22,8 +22,8 @@ th sign 1.000000 th InterruptMode 0.000000 th AccessCode 2.000000 #Crystallographic Settings -hkl lambda 0.703790 -hkl setub -0.124702 0.001618 -0.041357 -0.104448 -0.001326 0.049388 0.000751 0.084094 0.001574 +hkl lambda 1.179000 +hkl setub -0.019370 0.077484 -0.004944 0.077493 0.019386 0.002155 0.001034 -0.001344 -0.254040 det1dist 300. det1dist setAccess 1 det1zeroy 128. @@ -401,5 +401,5 @@ sample shit at 10.000000 sample setAccess 2 title TopsiTupsiTapsi title setAccess 2 -starttime 2000-06-29 15:01:07 +starttime 2000-06-29 15:01:07 starttime setAccess 2 diff --git a/stptok.c b/stptok.c index 508016be..7000e83b 100644 --- a/stptok.c +++ b/stptok.c @@ -28,7 +28,7 @@ char *stptok(const char *s, char *tok, size_t toklen, char *brk) if ( *s == *b ) { *tok = 0; - return (char *)s; + return (char *)(s+1); } } *tok++ = *s++; @@ -52,4 +52,13 @@ char *stptok(const char *s, char *tok, size_t toklen, char *brk) } return NULL; } - \ No newline at end of file + + + + + + + + + + diff --git a/test.tcl b/test.tcl index d6f49304..9e347bb1 100644 --- a/test.tcl +++ b/test.tcl @@ -355,15 +355,21 @@ MakeFocusAverager average hm FocusInstall hm focus.dic $shome/sics/focusmerge.dat #MakeChopper choco docho lnsp20 4000 8 -#MakeChopper choco sim +MakeChopper choco sim #ChopperAdapter fermispeed choco chopper1.nspee 0 20000 #ChopperAdapter diskspeed choco chopper2.nspee 0 20000 #ChopperAdapter phase choco chopper2.nphas 0 90. #ChopperAdapter ratio choco chopper2.ratio 0 6. -#ChopperAdapter diskspeed choco speed 0 20000 -#ChopperAdapter phase choco phase 0 90. -#ChopperAdapter ratio choco ratio 0 6. +ChopperAdapter diskspeed choco speed 0 20000 +ChopperAdapter phase choco phase 0 90. +ChopperAdapter ratio choco ratio 0 6. +#-------- SANS Cooker +MakeChopper cooker sanscook lnsa10 4000 11 +ChopperAdapter cookp cooker mp 0 400 +ChopperAdapter cookz cooker mz 0 400 + + source chosta.tcl Publish chosta Spy