home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1987 / 10 / shamlst.oct < prev    next >
Text File  |  1987-09-14  |  10KB  |  442 lines

  1. Listing 1.  QuickBASIC library to implement opaque matrices.
  2.  
  3. ' QuickBASIC implementation of an opaque numeric matrix
  4. ' Matrix is stored as arrays of columns
  5. ' OPTION BASE 0 must be used, although the row/column indices
  6. ' start at one.
  7.  
  8. SUB InitMat(Mat#(1), Max.Row%, Max.Col%) STATIC
  9. ' Initialize matrix
  10.  
  11. Mat#(0) = Max.Row% + Max.Col% / 1000
  12.  
  13. FOR I% = 1 TO UBound(Mat#)
  14.    Mat#(I%) = 0
  15. NEXT I%
  16.  
  17. END SUB ' CreateMat
  18.  
  19.  
  20. SUB StoreElem(Mat#(1), Row%, Col%, Elem#, OK%) STATIC
  21.  
  22. ' Store Elem# in matrix position (Row%,Col%)
  23. ' OK% is zero if error has occurred, -1 if operation was done
  24.  
  25. STATIC I%, MaxR%, MaxC%
  26.  
  27. MaxR% = INT(Mat#(0))
  28. MaxC% = 1000 * (Mat#(0) - MaxR%)
  29.  
  30. IF (MaxR% < Row%) OR (MaxC% < Col%) OR (Row% < 1) OR (Col% < 1) THEN
  31.    OK% = 0 ' Bad row or column numbers.
  32.    EXIT SUB
  33. END IF
  34.  
  35. OK% = -1
  36.  
  37. ' Calculate index
  38. I% = Row% + (Col% - 1) * MaxR%
  39. ' for the arrays of rows representation use
  40. '    I% = Col% + (Row% - 1) * MaxC%
  41.  
  42.  
  43. ' Store element
  44. Mat#(I%) = Elem#
  45.  
  46. END SUB ' StoreElem
  47.  
  48.  
  49. SUB RecallElem(Mat#(1), Row%, Col%, Elem#, OK%) STATIC
  50.  
  51. ' Recall Elem# in matrix position (Row%,Col%)
  52. ' OK% is zero if error has occurred, -1 if operation was done
  53.  
  54. STATIC I%, MaxR%, MaxC%
  55.  
  56. MaxR% = INT(Mat#(0))
  57. MaxC% = 1000 * (Mat#(0) - MaxR%)
  58.  
  59. IF (MaxR% < Row%) OR (MaxC% < Col%) OR (Row% < 1) OR (Col% < 1) THEN
  60.    OK% = 0 ' Bad row or column numbers.
  61.    EXIT SUB
  62. END IF
  63.  
  64. OK% = -1
  65.  
  66. ' Calculate index
  67. I% = Row% + (Col% - 1) * MaxR%
  68. ' for the arrays of rows representation use
  69. '    I% = Col% + (Row% - 1) * MaxC%
  70.  
  71. ' Recall element
  72. Elem# = Mat#(I%)
  73.  
  74. END SUB ' RecallElem
  75.  
  76.  
  77.  
  78. Listing 2.  True BASIC module that implements an array-based binary tree.
  79.  
  80. MODULE  Binary_Tree
  81.  
  82. ! TRUE BASIC module that implements a single binary tree
  83. ! Copyright (c) 1987  Namir Clement Shammas
  84.  
  85. DECLARE DEF NIL, TRUE, FALSE
  86. SHARE Left(1), Right(1), Node_Count, Num_Nodes, Bin_Tree$(1)
  87.  
  88.  
  89. !------------ Module initialization ---------
  90. LET Num_Nodes = 0
  91.  
  92. !----------- local functions -----------
  93. DEF NIL = MAXNUM
  94. DEF TRUE = 1
  95. DEF FALSE = 0
  96.  
  97.  
  98. SUB Initialize(Item$)
  99. ! Subroutine to initialize the binary tree
  100.  
  101. LET Num_Nodes = 1
  102. LET Tree_Size = 1
  103. LET Bin_Tree$(1) = Item$
  104. LET Left(1) = NIL
  105. LET Right(1) = NIL
  106.  
  107. END SUB
  108.  
  109.  
  110. SUB Search(Item$, Found, Index)
  111. ! Search for Item$ and return Index if found.
  112.  
  113. LET Found = FALSE
  114. LET Index = 1
  115.  
  116. DO WHILE (Index <> NIL) AND (Found = FALSE)
  117.    IF Bin_Tree$(Index) = Item$ THEN
  118.       LET Found = TRUE
  119.    ELSE
  120.       IF Bin_Tree$(Index) < Item$ THEN
  121.          LET Index = Right(Index)
  122.       ELSE
  123.          LET Index = Left(Index)
  124.       END IF
  125.    END IF
  126. LOOP
  127.  
  128. END SUB
  129.  
  130.  
  131. SUB Insert(Item$)
  132. ! Insert Item$ in the "dynamic" binary tree structure
  133.  
  134. LET Num_Nodes = Num_Nodes + 1
  135.  
  136. IF Num_Nodes > Tree_Size THEN
  137.    LET Tree_Size = Num_Nodes
  138.    MAT REDIM Bin_Tree$(Tree_Size), Left(Tree_Size), Right(Tree_Size)
  139. END IF
  140.  
  141. LET Index = 1
  142. LET Found = FALSE
  143.  
  144. DO WHILE Index <> NIL
  145.    IF Bin_Tree$(Index) < Item$ THEN
  146.       IF Right(Index) <> NIL THEN
  147.          LET Index = Right(Index)
  148.       ELSE
  149.          LET Right(Index) = Num_Nodes
  150.          LET Index = NIL
  151.       END IF
  152.    ELSE
  153.       IF Left(Index) <> NIL THEN
  154.          LET Index = Left(Index)
  155.       ELSE
  156.          LET Left(Index) = Num_Nodes
  157.          LET Index = NIL
  158.       END IF
  159.    END IF
  160. LOOP
  161.  
  162. LET Bin_Tree$(Num_Nodes) = Item$
  163. LET Right(Num_Nodes) = NIL
  164. LET Left(Num_Nodes) = NIL
  165.  
  166. END SUB
  167.  
  168. END MODULE
  169.  
  170.  
  171.  
  172. Listing 3.  Pascal code for emulating opaque complex data types.
  173.  
  174.  
  175.  
  176. TYPE
  177.     Opaque_Complex_type = ^Opaque_Complex_type_record;
  178.  
  179.     { record type is deliberately empty }
  180.     Opaque_Complex_type_record = RECORD
  181.                                  END;
  182.  
  183.  
  184.     Actual_Complex_type = ^Actual_Complex_type_record;
  185.  
  186.     Actual_Complex_type_record = RECORD
  187.                                     Reel,
  188.                                     Imag : REAL;
  189.                                  END;
  190.  
  191.     Convert_Complex = RECORD
  192.                         CASE BOOLEAN OF
  193.                             TRUE  : (Opaque : Opaque_Complex_type);
  194.                             FALSE : (Actual : Actual_Complex_type)
  195.                         END;
  196.  
  197.  
  198.  
  199. FUNCTION Convert_Opaque_to_Actual( Opaque_Complex : Opaque_Complex_type ) :
  200.                                     Actual_Complex_type;
  201.  
  202. VAR Transfer : Convert_Complex;
  203.  
  204. BEGIN
  205.     Transfer.Opaque := Opaque_Complex;
  206.     Convert_Opaque_to_Actual := Transfer.Actual
  207. END; { Convert_Opaque_to_Actual }
  208.  
  209.  
  210.  
  211. FUNCTION Convert_Actual_to_Opaque( Actual_Complex : Actual_Complex_type ) :
  212.                                     Opaque_Complex_type;
  213.  
  214. VAR Transfer : Convert_Complex;
  215.  
  216. BEGIN
  217.     Transfer.Actual := Actual_Complex;
  218.     Convert_Actual_to_Opaque := Transfer.Opaque
  219. END; { Convert_Actual_to_Opaque }
  220.  
  221.  
  222.  
  223. FUNCTION Real_Imag_Complex(Re, Im : REAL) : Opaque_Complex_type;
  224. { Convert from Real/Imaginary numbers to opaque complex numbers }
  225. VAR Transfer : Actual_Complex_type;
  226.  
  227. BEGIN
  228.     NEW(Transfer);
  229.     Transfer^.Reel := Re;
  230.     Transfer^.Imag := Im;
  231.     Real_Imag_Complex:= Convert_Actual_to_Opaque(Transfer);
  232. END; { Real_Imag_Complex }
  233.  
  234.  
  235. FUNCTION Polar_Complex(Angle, Modulus : REAL) : Opaque_Complex_type;
  236. { Convert from polar coordinates to opaque complex numbers }
  237. VAR Transfer : Actual_Complex_type;
  238.  
  239. BEGIN
  240.     NEW(Transfer);
  241.     Transfer^.Reel := Modulus * SIN(Angle);
  242.     Transfer^.Imag := Modulus * COS(Angle);
  243.     Real_Imag_Complex:= Convert_Actual_to_Opaque(Transfer);
  244. END; { Polar_Complex }
  245.  
  246.  
  247.  
  248. PROCEDURE Get_Real_Imag(MyComplex : Opaque_Complex_type;
  249.                         VAR Re, Im : REAL { output});
  250. { Convert opaque complex numbers into Real/Imaginary components }
  251. VAR Transfer : Actual_Complex_type;
  252.  
  253. BEGIN
  254.     Transfer := Convert_Opaque_to_Actual(MyComplex);
  255.     Re := Transfer^.Reel;
  256.     Im := Transfer^.Imag;
  257. END; { Get_Real_Imag }
  258.  
  259.  
  260. PROCEDURE Get_Polar(MyComplex : Opaque_Complex_type;
  261.                     VAR Angle, Modulus : REAL { output});
  262. { Convert opaque complex numbers into polar components }
  263. VAR Transfer : Actual_Complex_type;
  264.  
  265. BEGIN
  266.     Transfer := Convert_Opaque_to_Actual(MyComplex);
  267.     WITH Transfer^ DO BEGIN
  268.         Modulus := SQRT(SQR(Reel) + SQR(Imag));
  269.         Angle   := Imag / Reel;
  270.     END; { WITH }
  271. END; { Get_Polar }
  272.  
  273.  
  274.  
  275. FUNCTION Add_Complex(C1, C2 : Opaque_Complex_type) : Opaque_Complex_type;
  276.  
  277.  
  278. VAR Transfer : Actual_Complex_type;
  279.     Re, Im : REAL;
  280.  
  281. BEGIN
  282.     { Get first complex number }
  283.     Transfer := Convert_Opaque_to_Actual(C1);
  284.     Re := Transfer^.Reel;
  285.     Im := Transfer^.Imag;
  286.     { Get second complex number }
  287.     Transfer := Convert_Opaque_to_Actual(C2);
  288.     Re := Re + Transfer^.Reel;
  289.     Im := Im + Transfer^.Imag;
  290.     { Update result }
  291.     Transfer^.Reel := Re;
  292.     Transfer^.Imag := Im;
  293.     Add_Complex := Convert_Actual_to_Opaque(Transfer);
  294. END; { Add_Complex }
  295.  
  296.  
  297.  
  298. Listing 4.  Modula-2 code for opaque complex data types.
  299.  
  300.  
  301. DEFINITION MODULE Complex;
  302.  
  303. EXPORT QUALIFIED Complex, RealImagComplex, PolarComplex,
  304.  
  305.  
  306. TYPE  Complex; (* opaque type *)
  307.  
  308.  
  309. PROCEDURE RealImagComplex(Re, Im : REAL) : Complex;
  310. (* Convert from Real/Imaginary numbers to opaque complex numbers *)
  311.  
  312. PROCEDURE PolarComplex(Angle, Modulus : REAL) : Complex;
  313. (* Convert from polar coordinates to opaque complex numbers *)
  314.  
  315. PROCEDURE GetRealImag(MyComplex : Complex; VAR Re, Im : REAL (* output *));
  316. (* Convert opaque complex numbers into Real/Imaginary components *)
  317.  
  318.  
  319. PROCEDURE GetPolar(MyComplex : Complex; VAR Angle, Modulus : REAL (* output*));
  320. (* Convert opaque complex numbers into polar components *)
  321.  
  322. PROCEDURE AddComplex(C1, C2 : Complex) : Complex;
  323.  
  324. END Complex.
  325.  
  326.  
  327.  
  328. IMPLEMENTATION MODULE Complex;
  329.  
  330. FROM MathLib0 IMPORT sqrt, sin, cos;
  331.  
  332. TYPE
  333.  
  334.     ComplexRecord = RECORD
  335.                        Reel,
  336.                        Imag : REAL;
  337.                     END;
  338.  
  339.     (* opaque type mus be a pointer *)
  340.     Complex = POINTER TO ComplexRecord;
  341.   
  342.  
  343. PROCEDURE RealImagComplex(Re, Im : REAL) : Complex;
  344. (* Convert from Real/Imaginary numbers to opaque complex numbers *)
  345.  
  346. VAR C : Complex;
  347.  
  348. BEGIN
  349.     NEW(C);
  350.     C^.Reel := Re;
  351.     C^.Imag := Im;
  352.     RETURN(C)
  353. END RealImagComplex;
  354.  
  355.  
  356. FUNCTION PolarComplex(Angle, Modulus : REAL) : Complex;
  357. (* Convert from polar coordinates to opaque complex numbers *)
  358.  
  359. VAR C : Complex;
  360.  
  361. BEGIN
  362.     NEW(C);
  363.     C^.Reel := Modulus * sin(Angle);
  364.     C^.Imag := Modulus * cos(Angle);
  365.     RETURN(C)
  366. END PolarComplex;
  367.  
  368.  
  369.  
  370. PROCEDURE GetRealImag(MyComplex : Complex; VAR Re, Im : REAL (* output *));
  371. (* Convert opaque complex numbers into Real/Imaginary components *)
  372.  
  373. BEGIN
  374.     Re := MyComplex^.Reel;
  375.     Im := MyComplex^.Imag;
  376. END GetRealImag;
  377.  
  378.  
  379. PROCEDURE GetPolar(MyComplex : Complex; VAR Angle, Modulus : REAL (* output*));
  380. (* Convert opaque complex numbers into polar components *)
  381.  
  382. BEGIN
  383.     WITH MyComplex DO
  384.       Modulus := sqrt(Reel*Reel + Imag*Imag);
  385.       Angle   := Imag / Reel;
  386.     END;
  387. END GetPolar;
  388.  
  389.  
  390.  
  391. PROCEDURE AddComplex(C1, C2 : Complex) : Complex;
  392.  
  393. VAR C : Complex;
  394.     Re, Im : REAL;
  395.  
  396. BEGIN
  397.     (* Get first complex number *)
  398.     Re := C1^.Reel;
  399.     Im := C1^.Imag;
  400.     (* Get second complex number *)
  401.     Re := Re + C2^.Reel;
  402.     Im := Im + C2^.Imag;
  403.     (* Update result *)
  404.     C^.Reel := Re;
  405.     C^.Imag := Im;
  406.     RETURN(C)
  407. END AddComplex;
  408.  
  409. END Complex.
  410.  
  411.  
  412.  
  413.  
  414.  
  415. SUB Jekyll.and.Hyde(<argument list>, Menu.Choice) STATIC
  416.  
  417. STATIC <list of scalar and arrays used to implement opaque structure>
  418.  
  419. SELECT CASE Menu.Choice
  420.  
  421.   CASE 1
  422.  
  423.       <sequence of statements>
  424.  
  425.   CASE 2
  426.  
  427.       <sequence of statements>
  428.  
  429.   CASE 3
  430.  
  431.       <sequence of statements>
  432.  
  433.   ELSE
  434.      
  435.       <sequence of statements>
  436.  
  437. END SELECT
  438.  
  439. END SUB
  440.  
  441. Example 1: General scheme for using static local variables in QuickBASIC and Turbo BASIC
  442.