"Fossies" - the Fresh Open Source Software Archive

Member "laspack/matrix.c" (8 Aug 1995, 10686 Bytes) of package /linux/privat/old/laspack.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /****************************************************************************/
    2 /*                                 matrix.c                                 */
    3 /****************************************************************************/
    4 /*                                                                          */
    5 /* type MATRIX                                                              */
    6 /*                                                                          */
    7 /* Copyright (C) 1992-1995 Tomas Skalicky. All rights reserved.             */
    8 /*                                                                          */
    9 /****************************************************************************/
   10 /*                                                                          */
   11 /*        ANY USE OF THIS CODE CONSTITUTES ACCEPTANCE OF THE TERMS          */
   12 /*              OF THE COPYRIGHT NOTICE (SEE FILE COPYRGHT.H)               */
   13 /*                                                                          */
   14 /****************************************************************************/
   15 
   16 #include <stddef.h>
   17 #include <stdlib.h>
   18 #include <math.h>
   19 #include <string.h>
   20 
   21 #include "laspack/matrix.h"
   22 #include "laspack/errhandl.h"
   23 #include "laspack/copyrght.h"
   24 
   25 static ElType ZeroEl = { 0, 0.0 };
   26 
   27 static int ElCompar(const void *El1, const void *El2);
   28 
   29 void M_Constr(Matrix *M, char *Name, size_t RowDim, size_t ClmDim,
   30               ElOrderType ElOrder, InstanceType Instance, Boolean OwnData)
   31 /* constructor of the type Matrix */
   32 {
   33     size_t Dim, RoC;
   34 
   35     M->Name = (char *)malloc((strlen(Name) + 1) * sizeof(char));
   36     if (M->Name != NULL)
   37         strcpy(M->Name, Name);
   38     else
   39         LASError(LASMemAllocErr, "M_Constr", Name, NULL, NULL);
   40     M->RowDim = RowDim;
   41     M->ClmDim = ClmDim;
   42     M->ElOrder = ElOrder;
   43     M->Instance = Instance;
   44     M->LockLevel = 0;
   45     M->Multipl = 1.0;
   46     M->OwnData = OwnData;
   47     if (OwnData) {
   48         if (LASResult() == LASOK) {
   49             if (ElOrder == Rowws)
   50                 Dim = RowDim;
   51             else
   52                 Dim = ClmDim;
   53         M->Len = (size_t *)malloc((Dim + 1) * sizeof(size_t));
   54         M->El = (ElType **)malloc((Dim + 1) * sizeof(ElType *));
   55         M->ElSorted = (Boolean *)malloc(sizeof(Boolean));
   56         if (M->Len != NULL && M->El != NULL) {
   57                 for (RoC = 1; RoC <= Dim; RoC++) {
   58                     M->Len[RoC] = 0;
   59                     M->El[RoC] = NULL;
   60                 }
   61                 *M->ElSorted = False;
   62             } else {
   63             LASError(LASMemAllocErr, "M_Constr", Name, NULL, NULL);
   64             }
   65         } else {
   66         M->Len = NULL;
   67         M->El = NULL;
   68         M->ElSorted = NULL;
   69         }
   70     }
   71 }
   72 
   73 void M_Destr(Matrix *M)
   74 /* destructor of the type Matrix */
   75 {
   76     size_t Dim, RoC;
   77 
   78     if (M->Name != NULL)
   79         free(M->Name);
   80     if (M->ElOrder == Rowws)
   81         Dim = M->RowDim;
   82     else
   83         Dim = M->ClmDim;
   84     if (M->OwnData) {
   85     if (M->Len != NULL && M->El != NULL) {
   86             for (RoC = 1; RoC <= Dim; RoC++) {
   87                 if (M->Len[RoC] > 0) {
   88                     if (M->El[RoC] != NULL)
   89                         free(M->El[RoC]);
   90                 }
   91             }
   92         }
   93         if (M->Len != NULL) {
   94             free(M->Len);
   95             M->Len = NULL;
   96         }
   97         if (M->El != NULL) {
   98             free(M->El);
   99             M->El = NULL;
  100         }
  101         if (M->ElSorted != NULL) {
  102             free(M->ElSorted);
  103             M->ElSorted = NULL;
  104         }
  105     }
  106 }
  107 
  108 void M_SetName(Matrix *M, char *Name)
  109 /* (re)set name of the matrix M */
  110 {
  111     if (LASResult() == LASOK) {
  112         free(M->Name);
  113         M->Name = (char *)malloc((strlen(Name) + 1) * sizeof(char));
  114         if (M->Name != NULL)
  115             strcpy(M->Name, Name);
  116         else
  117             LASError(LASMemAllocErr, "M_SetName", Name, NULL, NULL);
  118     }
  119 }
  120 
  121 char *M_GetName(Matrix *M)
  122 /* returns the name of the matrix M */
  123 {
  124     if (LASResult() == LASOK)
  125         return(M->Name);
  126     else
  127         return("");
  128 }
  129 
  130 size_t M_GetRowDim(Matrix *M)
  131 /* returns the row dimension of the matrix M */
  132 {
  133     size_t Dim;
  134 
  135     if (LASResult() == LASOK)
  136         Dim = M->RowDim;
  137     else
  138         Dim = 0;
  139     return(Dim);
  140 }
  141 
  142 size_t M_GetClmDim(Matrix *M)
  143 /* returns the column dimension of the matrix M */
  144 {
  145     size_t Dim;
  146 
  147     if (LASResult() == LASOK)
  148         Dim = M->ClmDim;
  149     else
  150         Dim = 0;
  151     return(Dim);
  152 }
  153 
  154 ElOrderType M_GetElOrder(Matrix *M)
  155 /* returns the element order */
  156 {
  157     ElOrderType ElOrder;
  158 
  159     if (LASResult() == LASOK) {
  160         ElOrder = M->ElOrder;
  161     } else {
  162         ElOrder = (ElOrderType)0;
  163     }
  164     return(ElOrder);
  165 }
  166 
  167 void M_SetLen(Matrix *M, size_t RoC, size_t Len)
  168 /* set the length of a row or column of the matrix M */
  169 {
  170     size_t ElCount;
  171     ElType *PtrEl;
  172 
  173     if (LASResult() == LASOK) {
  174         if (M->Instance == Normal
  175             && ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim)
  176             || (M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim))) {
  177             M->Len[RoC] = Len;
  178 
  179             PtrEl = M->El[RoC];
  180 
  181             if (PtrEl != NULL) {
  182                 free(PtrEl);
  183         PtrEl = NULL;
  184             }
  185 
  186             if (Len > 0) {
  187                 PtrEl = (ElType *)malloc(Len * sizeof(ElType));
  188                 M->El[RoC] = PtrEl;
  189 
  190                 if (PtrEl != NULL) {
  191                     for (ElCount = Len; ElCount > 0; ElCount--) {
  192                         *PtrEl = ZeroEl;
  193                         PtrEl++;
  194                     }
  195                 } else {
  196                     LASError(LASMemAllocErr, "M_SetLen", M->Name, NULL, NULL);
  197                 }
  198             } else {
  199                 M->El[RoC] = NULL;
  200             }
  201         } else {
  202             if (M->Instance == Normal)
  203                 LASError(LASLValErr, "M_SetLen", M->Name, NULL, NULL);
  204             else
  205                 LASError(LASRangeErr, "M_SetLen", M->Name, NULL, NULL);
  206         }
  207     }
  208 }
  209 
  210 size_t M_GetLen(Matrix *M, size_t RoC)
  211 /* returns the length of a row or column of the matrix M */
  212 {
  213     size_t Len;
  214 
  215     if (LASResult() == LASOK) {
  216         if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim) ||
  217             (M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim)) {
  218             Len = M->Len[RoC];
  219         } else {
  220             LASError(LASRangeErr, "M_GetLen", M->Name, NULL, NULL);
  221             Len = 0;
  222         }
  223     } else {
  224         Len = 0;
  225     }
  226     return(Len);
  227 }
  228 
  229 void M_SetEntry(Matrix *M, size_t RoC, size_t Entry, size_t Pos, Real Val)
  230 /* set a new matrix entry */
  231 {
  232     if (LASResult() == LASOK) {
  233         if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim && Pos > 0 && Pos <= M->ClmDim) ||
  234             ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim && Pos > 0 && Pos <= M->RowDim) &&
  235             (Entry < M->Len[RoC]))) {
  236             M->El[RoC][Entry].Val = Val;
  237             M->El[RoC][Entry].Pos = Pos;
  238         } else {
  239             LASError(LASRangeErr, "M_SetEntry", M->Name, NULL, NULL);
  240         }
  241     }
  242 }
  243 
  244 size_t M_GetPos(Matrix *M, size_t RoC, size_t Entry)
  245 /* returns the position of a matrix entry */
  246 {
  247     size_t Pos;
  248 
  249     if (LASResult() == LASOK)
  250         if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim) ||
  251             ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim) &&
  252             (Entry < M->Len[RoC]))) {
  253             Pos = M->El[RoC][Entry].Pos;
  254         } else {
  255             LASError(LASRangeErr, "M_GetPos", M->Name, NULL, NULL);
  256         Pos = 0;
  257         }
  258     else
  259         Pos = 0;
  260     return(Pos);
  261 }
  262 
  263 Real M_GetVal(Matrix *M, size_t RoC, size_t Entry)
  264 /* returns the value of a matrix entry */
  265 {
  266     Real Val;
  267 
  268     if (LASResult() == LASOK)
  269         if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim) ||
  270             ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim) &&
  271             (Entry < M->Len[RoC]))) {
  272             Val = M->El[RoC][Entry].Val;
  273         } else {
  274             LASError(LASRangeErr, "M_GetVal", M->Name, NULL, NULL);
  275         Val = 0.0;
  276     }
  277     else
  278         Val = 0.0;
  279     return(Val);
  280 }
  281 
  282 void M_AddVal(Matrix *M, size_t RoC, size_t Entry, Real Val)
  283 /* add a value to a matrix entry */
  284 {
  285     if (LASResult() == LASOK) {
  286         if ((M->ElOrder == Rowws && RoC > 0 && RoC <= M->RowDim) ||
  287             ((M->ElOrder == Clmws && RoC > 0 && RoC <= M->ClmDim) &&
  288             (Entry < M->Len[RoC])))
  289             M->El[RoC][Entry].Val += Val;
  290         else
  291             LASError(LASRangeErr, "M_AddVal", M->Name, NULL, NULL);
  292     }
  293 }
  294 
  295 Real M_GetEl(Matrix *M, size_t Row, size_t Clm)
  296 /* returns the value of a matrix element (all matrix elements are considered) */
  297 {
  298     Real Val;
  299     
  300     size_t Len, ElCount;
  301     ElType *PtrEl;
  302 
  303     if (LASResult() == LASOK) {
  304         if (Row > 0 && Row <= M->RowDim && Clm > 0 && Clm <= M->ClmDim) {
  305             Val = 0.0;
  306             if (M->ElOrder == Rowws) {
  307                 Len = M->Len[Row];
  308                 PtrEl = M->El[Row];
  309                 for (ElCount = Len; ElCount > 0; ElCount--) {
  310                     if ((*PtrEl).Pos == Clm)
  311                         Val = (*PtrEl).Val;
  312                     PtrEl++;
  313                 }
  314             } else if (M->ElOrder == Clmws) {
  315                 Len = M->Len[Clm];
  316                 PtrEl = M->El[Clm];
  317                 for (ElCount = Len; ElCount > 0; ElCount--) {
  318                     if ((*PtrEl).Pos == Row)
  319                         Val = (*PtrEl).Val;
  320                     PtrEl++;
  321                 }
  322             }
  323         } else {
  324             LASError(LASRangeErr, "M_GetEl", M->Name, NULL, NULL);
  325             Val = 0.0;
  326         }
  327     } else {
  328         Val = 0.0;
  329     }
  330     return(Val);
  331 }
  332 
  333 void M_SortEl(Matrix *M)
  334 /* sorts elements of a row or column in ascended order */
  335 {
  336     size_t Dim = 0, RoC;
  337 
  338     if (LASResult() == LASOK && !(*M->ElSorted)) {
  339         if (M->ElOrder == Rowws)
  340         Dim = M->ClmDim;
  341         if (M->ElOrder == Clmws)
  342         Dim = M->ClmDim;
  343         for (RoC = 1; RoC <= Dim; RoC++) {
  344             /* sort of elements by the quick sort algorithms */
  345             qsort((void *)M->El[RoC], M->Len[RoC], sizeof(ElType), ElCompar);
  346         }
  347         
  348         *M->ElSorted = True;
  349     }
  350 }
  351 
  352 static int ElCompar(const void *El1, const void *El2)
  353 /* compares positions of two matrix elements */
  354 {
  355     int Compar;
  356 
  357     Compar = 0;
  358     if (((ElType *)El1)->Pos < ((ElType *)El2)->Pos)
  359         Compar = -1;
  360     if (((ElType *)El1)->Pos > ((ElType *)El2)->Pos)
  361         Compar = +1;
  362 
  363     return(Compar);
  364 }
  365 
  366 void M_Lock(Matrix *M)
  367 /* lock the matrix M */
  368 {
  369     if (M != NULL) 
  370         M->LockLevel++;
  371 }
  372 
  373 void M_Unlock(Matrix *M)
  374 /* unlock the matrix M */
  375 {
  376     if (M != NULL) {
  377         M->LockLevel--;
  378         if (M->Instance == Tempor && M->LockLevel <= 0) {
  379             M_Destr(M); 
  380         free(M);
  381     }
  382     }
  383 }