ࡱ> npm` /bjbj .yb1111V2T233333555ISKSKSKSKSKSKS$8UhW\oSQ55555oS33SSSS533ISS5ISSSS32 g|<1E. SISS0TSWOWSWS,55S55555oSoSS555T5555D+00 Xnumbers.dll tutorial General description The current, industry-wide standard precision for personal computers is 32 bits, which is equivalent to approximately eight decimals. Double precision, standard in Excel and the default in VBA, has a precision of 64 bits, or about 15 decimals. For most problems this is completely satisfactory, but there are some mathematical operations, such as the multiplication or inversion of large matrices, that require better precision and/or special approaches to keep truncation errors from accumulating in the answer. For such problems, as may be encountered in least squares fitting to multi-term polynomials, or in multivariate applications, extended precision may be needed. It may also be useful as a diagnostic tool in program development and testing, to pinpoint precisely where numerical accuracy can be lost. And as scientists increasingly learn how to use Excel for non-trivial data analysis tasks, the need for extended precision will only increase. Xnumbers.dll is an ActiveX dynamic link library, compatible with Windows 2000, NT, and XP, which allows Excel macros to operate in extended precision, of up to 200 decimals. It was created by Leonardo Volpi and his students, and is freely downloadable from http://digilander.libero.it/foxes. It handles numbers internally as character strings, divides them into packets of up to six decimals, and then manipulates these packets to perform elementary mathematical operations such as addition, subtraction, multiplication, and division. More complicated functions then use these elementary functions as building blocks. In the end, the strings are converted back to numbers. The method used is similar to that in the Fortran77 program MPFUN and in its recent successor, ARPREC, which allows arbitrary precision in Fortran90 and C++. For a description of MPFUN see D. H. Bailey, ACM Trans. Math. Software 19 (1993) 288-319; for ARPREC, see http://crd.lbl.gov/~dhbailey/mpdist/. One of the beauties of Xnumbers.dll is that it allows the user to modify existing macros while keeping its user interface untouched. In other words, all high-precision operations are performed in the background, and the software user need not see a difference in either input or output. (High-precision results can of course be displayed in full when so desired, as in the code example of Test 2b shown below). Xnumbers is free, it is powerful, and it is fun, but it does slow down the computation considerably. Extended-precision macros are therefore not recommended for routine use, and they are best labeled as such, e.g., with the prefix x, as we have done with the macros in the xMacroBundle. . Installation You will need to have an unzip routine handy, because the download is a zip file, and an Adobe Acrobat reader, because the documentation comes as a pdf (portable document format) file. Both of these can be freely downloaded from the web, and should already be on your desktop as standard tools. Here is how you can install the dynamic link library. (A specific location is selected here for your convenience, but you can of course place it somewhere else, in which case you should make the corresponding changes in what follows.) Go to the website http:// digilander.libero.it/foxes, select Downloads, and download the xnumberdll.zip to your desktop. Unzip the file, and store its three components, readme, xnumbers.dll, and Xnumbers_DLL_Ref, on the desktop. The readme file contains nothing important: read it and either discard or store somewhere. The reference file, Xnumbers_DLL_Ref, is very worthwhile and has many useful details. You may want to print it out, but please do that later, because it is a 115-page tome. For now we will focus on xnumber.dll. On your desktop, click on My Computer ( Local Disk (C:) ( Program Files ( Microsoft Office ( Office (Office11 in Excel2003) ( Library. Then press File ( New ( Folder, and change the name of the so generated folder from New Folder to Xnumbers, then open that file (which, as a new file, should be empty). If necessary, reduce the space taken up by this folder and/or move it, so that you can find xnumbers.dll on the desktop. Click on xnumbers.dll, copy it into the open folder, and close the folder. Now, xnumbers.dll is stored safely, and presumably in good company, next to Solver. In order to make sure that Excel can find it, open Excel, go to the Visual Basic Editor with Tools ( Macro ( Visual Basic Editor or, faster, with Alt(F11 (on the Mac: Opt(F11), and then, in the VBEditor menu bar, select Tools ( References. This will display the dialog box for the VBA Project. Click on Browse, select Files of type: Type Libraries (*.olb; *.tlb; *.dll), in the Add Reference dialog box go to My Computer ( Local Disk (C:) ( Program Files ( Microsoft Office ( Office ( Library ( Xnumbers, open the file, and type Xnumbers.dll in the Filre name window if it is empty. Click Open it, which will bring you back to the References VBA Project dialog box. Now use the Priority Up button to ease xnumbers up the list so that it is contiguous with the other tick-marked items. Click OK. From now on, Excel will know where to find xnumbers.dll. Using Xnumbers in Excel VBA Before the extended-precision instructions and functions (here abbreviated as Xfunctions, Xinstructions, etc.) can be used in any particular function, macro, or subroutine, the class of Xnumbers must first be invoked (in computerese: instantated) with the line Dim MP As New Xnumbers and, at the end of the code, deactivated with Set MP = Nothing Thereafter, individual Xfunctions can be called between those two statements with the prefix MP. followed by the specific Xinstruction, as in Sub Test1a() Dim a, b, c Dim MP As New Xnumbers a = "1234567890.0987654321" b = MP.xInv(a) c = MP.xExp(a, 40) Debug.Print "a = ", a Debug.Print "1 / a = ", b Debug.Print "e ^ a = ", c Set MP = Nothing End Sub which will display the values of a, b = 1/a, and c = ea in the Immediate Window. (You can open the Immediate Window in the VBEditor, with Ctrl(G.) For 1/a in the above example you will obtain answers to the default value of 30 decimal places. The numerical precision of each result can be specified individually in its instruction, as illustrated for c, which is computed and displayed to 40 decimals. In this example, the Immediate Window will show a = 1234567890.0987654321 1 / a = 8.1000000730620006590111459442E-10 e ^ a = 1.60263297808435399238741617564E+536166022 If a had been defined without double quotes in the macro, i.e., as a = 1234567890.0987654321 then the result for x in the Immediate Window would have read a = 1234567890.09877 but those for 1/a and ea would not have been changed. For more than occasional use of extended precision, it is often more convenient to use a collective statement, as in Sub Test1b() Dim a, b, c Dim MP As New Xnumbers With MP a = "1234567890.0987654321" b = .xInv(a) c = .xExp(a, 40) Debug.Print "a = ", a Debug.Print "1 / a = ", b Debug.Print "e ^ a = ", c End With Set MP = Nothing End Sub In each macro, subroutine, or function, the number of decimals used can also be set globally, as with DgtMax = 150 Upon completion of the macro, its results can be written onto the spreadsheet, where they will usually be converted back to double precision, and in their display may be limited further by the chosen cell format. Therefore, all calculations that are critical to obtaining high computational accuracy should be performed within the macro, or inside the functions and subroutines it calls, before returning the final result to the spreadsheet. From the user point of view, this is the simplest approach, because in this way the final output doesnt even show that any special processing was used, although it may generate complaints about the apparent sluggishness of the calculation. Below is a macro that takes a number from the spreadsheet, raises it to the tenth power, and returns the answer to the spreadsheet. To use it, place a number in a spreadsheet cell, or highlight any other cell containing a number, and call the macro. The answer will appear in the spreadsheet cell immediately below it, as well as in two message boxes. Sub Test2a() Dim MP As New Xnumbers Dim a Dim b As Double CellValue = Selection.Value a = MP.xPow(CellValue, 10, 40) Selection.Offset(1, 0).Select Selection.Value = a MsgBox "x ^ 10 = " & a b = a Selection.Offset(1, 0).Select Selection.Value = b MsgBox "x ^ 10 = " & b Selection.Offset(-2, 0).Select Set MP = Nothing End Sub The message boxes display both a and b; for an input value of 12.34567, the message boxes will show a = 82252032957.44822844133332922210978090071 and b = 82252032957.4482 respectively, which only differ in that b is dimensioned As Double, which will override the extended precision. Note that the answers shown on the spreadsheet, like that for b in the message box, will have been reduced to double precision, because upon converting the string back to a number, it will be stored in 64 bits. But neither the message box nor the Immediate Window has that constraint, and both can therefore display the extended-precision result in full. Still, you may want to find the extended-precision results on the spreadsheet rather than having to copy them from a message box or VBA debugging tool. You can prevent conversion into double precision by concatenating an apostrophe with the numerical value, which will make Excel treat the result as a text string: Sub Test2b() Dim MP As New Xnumbers Dim a, c Dim b As Double CellValue = Selection.Value a = MP.xPow(CellValue, 10, 40) Selection.Offset(1, 0).Select Selection.Value = a MsgBox "a = " & a b = a Selection.Offset(1, 0).Select Selection.Value = b MsgBox "a ^ 10 = " & b c = "'" & a MsgBox "a ^ 10 = " & c Selection.Offset(1, 0).Select Selection.Value = c Selection.Offset(-3, 0).Select Set MP = Nothing End Sub The column with the receiving cell should be wide enough to accommodate the extended-precision result. Alternatively, you can left-align that receiving cell, and make sure that cells to its right are empty, so that the extended-precision result can overflow into those empty cells. Now that you have the tools to write macros using Xnumbers, you will want to know the available Xinstructions. Some of the most useful ones are listed below. Apart from the usual set of elementary instructions, and an ingenious function evaluator, Xnumbers has an extensive set of instructions for manipulating vectors and matrices, and for computations involving complex numbers. In fact, so many of the latter functions are absent from VBA that Xnumbers also contains their standard, double-precision equivalents, distinguishable by the prefix s. Function Instruction Operation items within straight brackets are optional the prefix MP is implied Elementary single-argument instructions Negation .xNeg(a) a Absolute value .xAbs(a) (a( Inversion .xInv(a) 1/a Elementary two-argument operations Addition .xAdd(a,b [,DgtMax]) a+b Subtraction .xSub(a,b [,DgtMax]) ab or: .xAdd(A1, .xNeg(A2)); do NOT use xAdd(A1,A2) Multiplication .xMult(a,b [,DgtMax]) ab Division .xDiv(a,b [,DgtMax]) a/b or: .xMult(A1, .xInv(A2)) Integer division .xDivint(a,b [,DgtMax]) int (a/b) b ( 0 Integer modulus .xMod(a,b [,DgtMax]) b mod (a/b) Integer power .xPow(a,n [,Dgt_Max]) a n if n is a real number, int(n) is used for the exponent Arbitrary power .xExp_Base(a, b [,DgtMax]) ab a > 0 Square root .xSqr(a [,DgtMax]) (a a > 0 Integer root .xRoot(a,n [,DgtMax]) a1/n if n is non-integer, int(n) is substituted for n xroot(100,9,45) ( 1.66810053720005875359979114908865584747919268 Multi-argument operations V is a vector, i.e., an array of numbers vi in a contiguous row or column Summation .xSum(V [,DgtMax]) S vi Product .xProd(V [,DgtMax]) P vi Trigonometric functions all argument are in radians Sine .xSin(a [,DgtMax]) sin a Cosine .xCos(a [,DgtMax]) cos a Tangent .xTan(a [,DgtMax]) tan a Inverse Sine .xAsin(a [,DgtMax]) arcsin a Inverse Cosine .xAcos(a [,DgtMax]) arccos a Inverse Tangent .xAtan(a [,DgtMax]) arctan a Exponential and logarithmic functions Exponential .xExp(a [,DgtMax]) ea Natural Logarithm .xLn(a [,DgtMax]) ln a Decimal Logarithm .xLog(a [,DgtMax]) log a Hyperbolic Sine .xSinh(a [,DgtMax]) sinh a sinh a = ( ex ex)/2 Hyperbolic Cosine .xCosh(a [,DgtMax]) cosh a cosh a = ( ex + ex)/2 Hyperbolic Tangent .xTanh(a [,DgtMax]) tanh a tanh a = (ex ex)/( ex + ex) Inverse Hyperbolic Sine .xAsinh(a [,DgtMax]) arsinh a arsinh a = ln[a+((a2+1)] Inverse Hyperbolic Cosine .xAcosh(a [,DgtMax]) arcosh a arcosh a = ln[a+((a21)], a > 1 Inverse Hyperbolic Tangent .xAtanh(a [,DgtMax]) artanh a artanh a = (1/2) ln[(1+a)/(1a)] Statistical functions Factorial .xFact(n [,DgtMax]) n! for DgtMax < 100, returns result in scientific notation Binomial coefficient .xComb(n, m [,DgtMax])  EMBED Equation.3  Some useful constants The brackets are required, even if empty. DgtMax can go up to 415 for p, p/2, p/4, 2p, e, ln(2), ln(10), and g p .xPi( [DgtMax]) p also: .xPi2( ) for p/2, .xPi4( ) for p/4, and .x2Pi( ) for 2p e .xE( [DgtMax]) e also: .xLn2() ( 0.693147180559945309417232121458 and: .xLn10( ) ( 2.30258509299404568401799145467 g .xEu( [DgtMax]) g Euler s constant, 0.57721566490153286060651209008& More single-argument instructions Integer part .xInt(a) computes the largest integer smaller than a, e.g., xInt(2.14) = 2, xInt(2.99) = 2, xInt(2.14) = 3 Decimal part .xDec(a) computes the decimal part of a, e.g., xDec(2.14) = 0.14, xDec(2.14) = 0.14 Round .xRound(a, n) rounds a to n decimal places, e.g., xRound(2.14) = 0.14, xDec(2.14) = 0.14 Comparison .xComp(a [,b]) .xComp(a, b) = 1 for a > b, = 0 for a = b, = 1 for a < b b = 0 when omitted, i.e., .xComp(a) returns the sign of a Do NOT include logic operators inside the argument, as then the logic is applied before the extended precision. Therefore, replace If ab Then by If .xComp(a,b) > 0 Then. Formating instructions Format .xFormat(a [,Digit_Sep]) formats a in comma-separated groups of Digit_Sep default: Digit_Sep = 6. For a = 1234567.89012345, .xFormat(a) = 1,234567.890123,45 and .xFormat(a,3) = 1,234,567.890,123,45 Unformat .xUnformat(a) Removes formatting commas from a Matrix and vector operations We distinguish here between vectors V of dimension m, a positive integer, and matrices M (or A, B, C, etc.) of dimension m(n, where n is another positive integer. A matrix is called square when m = n. Individual matrix elements are denoted by aij. Absolute value .xMatMod(M [,DgtMax]) ((M(( Absolute value or modulus = EMBED Equation.3  Determinant .xMatDet(M [,DgtMax]) (M( M must be square. Returns ? when M is singular. Addition .xMatAdd(M1, M2 [,DgtMax]) M1 + M2 M1 and M2 must have the same dimension m(n Subtraction .xMatSub(M1, M2 [,DgtMax]) M1 M2 M1 and M2 must have the same dimension m(n Scalar product .xProdScal(V1, V2 [,DgtMax]) V1 ( V2 V1 and V2 must have the same dimension m Vector product .xProdVect(V1, V2 [,DgtMax]) V1 ( V2 V1 and V2 must have the same dimension m Multiplication .xMatMult(M1, M2 [,DgtMax]) M1 M2 when M1 is m(p , M2 must be p(n Integral power .xMatPow(M, n [,DgtMax]) Mn M must be square, m(m, and n a positive integer Inversion .xMatInv(M [,DgtMax]) M1 M must be square, m(m Special matrix functions LU decomposition .xMat_LU(M [,Pivot] [,DgtMax]) M must be square, m(m. Returns the Lower and Upper triangular matrices that satisfy M = L U or, when Pivot is true, M = P L U where P is the permutation matrix. LL decomposition .xMat_LL(M [,DgtMax]) Cholesky decomposition. M must be square, m(m. Linear equation solver .xSysLin(A, B [,DgtMax]) Solves A X = B to yield X = A1AX = A1B A must be square, m(m, and B must be m(1 or m(n Similarity transform .xMatBAB(A, B [,DgtMax]) Computes C = B1 A B. A and B must be square, m(m. Gauss-Jordan .xGaussJordan(M, n, m, Det, Algo, DgtMax) performs Gauss-Jordan matrix reduction. Special least squares functions Least squares fit .xRegLin_Coeff(y, x [,DgtMax] [,Intercept]) Finds least squares fit of a vector y to a vector or matrix x for both polynomial or multivariate fits, without uncertainty estimates. Optional Intercept forces the fit through the spe-cified y-value Intercept at x = 0. Passes all NIST linear least squares test sets with the default setting DgtMax = 30. Least squares result .xRegLin_Eval(coeff, x [,DgtMax]) Computes the values of ycalc based on the coefficients found (e.g., with .xRegLin_Coeff) for the specified set of x-values Functions operating on complex numbers For functions using complex arithmetic, the prefix MP.Cplx is required. Complex numbers, here denoted by z = a + jb, where j = ((1), must be defined in terms of their separate, real and imaginary components, a and b. Note that many of these instructions have the same form as those for real numbers, but are distinguishable by their prefix Cplx. For their double-precision equivalents, in the instruction just change the prefix x to s. Negation .xNeg(z [,DgtMax]) z = (a + jb) = a jb Absolute value .xAbs(z [,DgtMax]) (z( = EMBED Equation.3 = EMBED Equation.3  Inversion .xInv(z [,DgtMax]) 1/z = EMBED Equation.3 = EMBED Equation.3  Conjugate .xCon(z [,DgtMax]) z* = a jb Zero check .xIsZero(z, tiny [,DgtMax]) z ( 0 (z( = EMBED Equation.3 ( tiny Addition .xAdd(z1,z2 [,DgtMax]) z1+z2 = (a1 + a2) + j (b1 + b2) Subtraction .xSub(z1,z2 [,DgtMax]) z1z2 = (a1 a2) + j (b1 b2) Multiplication .xMult(z1,z2 [,DgtMax]) z1 z2 = (a1a2b1b2) + j (a1b2+a2b1) Division .xDiv(z1,z2 [,DgtMax]) z1/z2 = EMBED Equation.3  Integer power .xPow(z,n [,DgtMax]) zn = EMBED Equation.3  Integer root .xRoot(z,n [,k] [,DgtMax]) z1/n = EMBED Equation.3  , k = 0, 1, , n1 Square root .xSqr(z [,k] [,DgtMax]) z = EMBED Equation.3 , k = 0, 1 Exponential .xExp(z [,DgtMax]) ez =ea cos(a) + jeb cos(b) Natural logarithm .xLn(z [,DgtMax]) ln z = ln(a+jb) + arctan(a/b) Decimal logarithm .xLog(z [,DgtMax]) log z = ln(z) / ln(10) Convert to polar .xPolar(z [,DgtMax]) z =  EMBED Equation.3  Convert to rectangular .xRect(z [,DgtMax]) z =  EMBED Equation.3  Evaluating an algebraic function There are some practical restrictions with the above list. First, it may lack an operation you may want to perform. Secondly, while the elementary instructions can be nested to evaluate rather complicated algebraic expressions, this approach quickly becomes rather unwieldy. In order to calculate, e.g., the root d = [b+((b24ac)]/2a of the quadratic equation y = ax2 + bx + c one would need to write the instruction root = .xDiv(.xAdd(.xNot(b), .xSqr(.xSub(.xPow(b, 2), .xMult(4, .xMult(a, c))))), .xMult(2,a)), or, broken up, as discr = .xSub(.xPow (b, 2), .xMult(4, .xMult(a, c))), root = .xDiv(.xAdd(.xNot(b), .xSqr(discr)), .xMult(a, 2)), still quite clumsy. Therefore, a convenient function evaluator has been made available, in which f is a function in regular VBA format, and x is either a single number or a vector. Function evaluation xeval(f[,x] [,DgtMax] [,Angle]) f (x) For trigonometric functions: Angle = Rad (default), Deg, or Grad (= Degrees ( 10/9) x_eval("(1.2345^6.789)") ( 4.17958381726967068826150545493 x_eval("(sqr(5/2)+7^3.21)") ( 517.717800424940440699345256799 x_eval ("(sin(22.5)+3*cos(22.5))") ( 1.66810053720005875359979114908865584747919268 The following example (with the value of a placed inside quotation marks in order to preserve all of its more than fifteen digits) involves a single variable: Sub Test3a() Dim MP As New Xnumbers Dim a, b With MP a = "1.234567890123456789" b = .x_eval("(a ^3.456)", a) Debug.Print "a = ", a Debug.Print "a^3.456 = ", b End With Set MP = Nothing End Sub and yields, in the Immediate Window, a = 1.234567890123456789 a^3.456 = 2.07145623088457274932940268363 Expressions containing multiple variables must enter the latter in a single matrix, with their names specified as labels in the first matrix column, and their numerical values in the second matrix column, as in Sub Test3b() Dim MP As New Xnumbers Dim x(1 To 2, 1 To 2) 'dimension matrix With MP x(1, 1) = "a": x(1, 2) = .xE 'specify matrix elements x(2, 1) = "b": x(2, 2) = .xPi b = .x_eval("(a ^ b)", x) Debug.Print "e = ", x(1, 2) Debug.Print "Pi= ", x(2, 2) Debug.Print "e^Pi = ", b End With Set MP = Nothing End Sub which produces the following output in the Immediate Window: e = 2.71828182845904523536028747135 Pi= 3.14159265358979323846264338327 e^Pi = 23.1406926327793214925637779471 And here, finally, is a macro to compute the root of a quadratic equation with the usual (but, as we will see, sometimes not quite satisfactory) standard expression: Sub Test4() Dim a, b, c, root1, root2 Dim y(1 To 3, 1 To 2) Dim MP As New Xnumbers With MP a = 1 b = 100000 c = 0.000001 y(1, 1) = "a": y(1, 2) = a y(2, 1) = "b": y(2, 2) = b y(3, 1) = "c": y(3, 2) = c root1 = (-b + Sqr(b ^ 2 - 4 * a * c)) / (2 * a) root2 = .x_eval("((-b + Sqr(b ^ 2 - 4 * a * c)) _ / (2 * a))", y) Debug.Print "root1 = ", root1 Debug.Print "root2 = ", root2 End With Set MP = Nothing End Sub with the following results displayed in the Immediate Window: root1 = 7.27595761418343E-12 root2 = 0.00000000001000000000000005 The difference between these two answers shows that, when 4ac b2, double precision has difficulties evaluating this rather common formula, because it must compute the difference between two nearly equal numbers, b and the square root of b2 4ac. In this case, the quadruple precision of Xnumbers is still sufficient to get the answer right. A better way, of course, would be to use an alternative formula that does not involve that difference, such as d = 2c/[b((b24ac)]. But such an obvious choice might not be available for more complicated problems, in which case extended precision would be a best first defense, before one finds out how to improve the algorithm used. Summary Here are the rules you must follow when writing new macros that use Xnumbers, or when modifying old ones. (1) Give the macro a distinct name, such as one starting with an x. (2) If you modify an already existing macro, keep a copy of the unmodified original. High-precision macros should not be used as routine updates of general-purpose macros, since they are too slow, even when set to the standard double precision of 15 decimals. This is so because much of the extra execution time is up-front, regardless of the precision specified. (3) Before the dimensions are listed, insert the lines Dim MP As New Xnumbers With MP where MP stands for multi-precision. The default (quadruple) precision yields 30 decimals, and need not be specified. If you want a different precision, specify that here instead, as with DgtMax = 50 or, if you so prefer, with an input box that lets you specify the value of DigitsMax from the spreadsheet. (4) Just before the end of the subroutine, insert the lines End With Set MP = Nothing (5) In the dimension statements, remove the dimension specifiers As Single and As Double from any parameter you want to use in extended precision, because these dimension statements will overrule Xnumbers and keep the parameter in their dimension-specified precisions. By leaving their dimensions unspecified (but of course included in the list, otherwise Option Explicit would complain), these parameters will be assumed to be dimensioned As Variant, which is how Xnumbers can use them. (6) Then modify all precision-critical instructions to fit the Xnumber format. For complicated expressions, either break up the expression into several simpler parts, or use the xEval function. By comparing the macros in the xMacroBundle with their parents in the MacroBundle you will see that this need not involve very much work, because you need not rethink the structure of your code, merely some of its instructions. For more specifics, including additional functions and more details, see the Xnumbers_DLL_Ref manual. ***** In summary, with xnumbers.dll and a few relatively minor modifications of your macros, subroutines, and functions, you can have high-precision computations while the structure of t** + u v 7 8 ; <      - .     %'Vofgqrklv 纳htB*ph ht6]ht htCJH*ht6CJNH]ht6CJ]htCJNH htCJht6B*]phht6B*CJd]phB* vJfnU $ xa$$$ P x1$`a$gd!% $x`a$gd!% $x`a$$$ pP@ x`a$ $ P x$$ P xa$/%&./P  $%&'ABGHOPUVWX]^_`EF˻˻˱˱˻˩˩h!%CJNH jh!%CJH* jh!%CJ h!%>*CJ h!%CJ h!%NH jh!%h!% htNHhthtB*phht6B*]phBF?@IJfno  #&Uz*2SͻhtB*CJOJQJ^JphhtCJOJQJ^J htNHhtht5CJOJQJ\^JhtB*CJphhtCJNH htCJht6B*]phh!% h!%>*CJh!%CJNH jh!%CJ h!%CJ3Ubz*2 !:!m!$$ @ `x^`a$$$ @ `^`a$ $ xa$$$ @ `x^`a$$$ @ `^`a$ $ `^`a$`^`STVW\]cdhi}~ p!q!!!!!$"4"5";"<"[""""# #*#2#7#C####$$)$p$q$$$0%ټĭĭĭĭٝټټht5CJOJQJ\^JhtB*CJOJQJ^Jphht5CJOJQJ\^JhtCJNHhtCJOJQJ^Jht6CJ] htCJ jhtH* htNHht6H*]ht ht6]8m!!!"$"[""""# #&#3#D#^#x####$$ @ `^`a$x$$ @ `x^`a$$$ pP@ xxa$$ a$$$ pP@ x`a$##$)$&9(F(](c(s((((((()/)F)e)v)~)`x^``^`$$ pP@ xa$$$ pP@ x`a$$$ @ `x^`a$0%1%%%&&}'~'''''9(i(r(})~)))))))))**U*V*****0+1+++++,,,,,=-H.T..."/#///00I1J1f1g111112,2ľľľľľľľĴľĬhtB*phht56\] htNHhtht6CJ] htCJht5CJOJQJ\^JhtCJOJQJ^J htCJhtCJNH@~))**-*,=-J-a-j-z-------.1.H.`^` $x`a$$$ pP@ xa$$$ pP@ a$$$ pP@ `a$$$ pP@ x`a$H.T.k....../252d2222223$ pP8@ x 8@ x$ P8x 8@ x 8@  $ pP@ l$ x`a$`x^``^`,2-252\2]22222222222223&3'333435363L3M3Y3Z3[3\333333333333344)4*4+4,4.41424344484Q4R4_4`4f4g4h4i4k444»鱪ҵ jhI hI6]hI htCJ ht6] j|htht6CJ ] htCJ ht6B*]ph htNHhthtB*phhtB*NHph@373]33333.484k44445,565_5$ pP8@ gdI 8@ $ pP8@ lx 8@ gdI$ pP8@ x @ x $ pP8@ $ pP8@ xgdI44444444444444555(5)5*5/50565M5N5Z5[5]5^5e5f5{5|55555555586:6<6>6666666ӮڦڀhtOJQJhI6H*]ht6B*]ph jhtB*phhtB*ph htH* hI6] jhIhIht6H*] htCJ ht6]htht6CJ H*]ht6CJ]ht6CJ ] htCJ 2_5555|66787p777!8M8{88889L9$ P8x $ pP8@ $ pP8@ x @ x $ P8 8@ `x^` 8@ 6666666777778777777777 88886878J8K8d8e8x8y88888888888 9 9998999I9J9d9e9v9w999999999999999999999999 htH*ht6H*]ht6B*]phhtOJQJ htCJhIhtht6H*] ht6]ML9y9999 :,:d::::;;;Q;s;;;< $ P8 $ pP8@ $ P8x x $ pP8 @ x $ pP8@ 99:::::::::::!:#:%:&:(:):*:M:N:a:b:m:n:t:u:v:w:x:y:z::::::::::::::::;;;;!;";&;';(;);1;2;7;8;;;Q;c;d;p;q;;;;;; htNHht6B*]phhtCJEHhtCJEH jht htH*ht6H*] ht6]ht htCJH;;;;;;;<<<<<<<<<<<<<<<====>=@=L=N=b=d=p=r==============4>T>V>Z>\>^>>>>>>>>8?|?󬤜󬤜htOJQJhtB*ph jhtB*ph htCJ ht6]ht6OJQJ]ht6B*]phjhtEHUjcE htCJUVaJhtjhtU=<f<< ===6>>>8?|?? @=@T@}@@@@A @ x @ $ P8x 8@  8@ x $ pP8@  @ x @ |?@@s@t@@@@@!A"A)A2A3A5A6A@AAADAEAOAPASATA_A`AcAdAfAhAiAAAAAAA B BBNBOBBBBBBB0C1CQCRCyCzCCCCC#D$D+D,DiDjDkDlDtDuDDDD jhtht6CJ] htCJht6B*]phh htNHht6B*]phhtB*ph htCJ ht6]htFA)AfAAOB}BBBBCFCnCCCCC$ pP8@ l<$ pP8@ x @ x $ pP8@ $ P8x @ @ ^@  @  $ p8@ DDDDDDDEEEEE3E4EGEHEIEJEKEnEoEpEqErEEEEEEEEEEEEEEEEEFFFFFF F-F.F2F3F4F7F8F9F?F@F^F_FǻֲಝhtB*CJph jhtCJ htCJH* htH*ht6CJ]jhtCJEHUjCE htCJUVaJjhtCJU htCJ j|htht6H*]ht ht6]:CDEKErEEEF4FbFFFF$GWGzGGGHH6H$ pP8@ l<x$ pP8@ x$ pP8@ lx $ pP8@  $ @ xa$_F`FaFbF~FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGG"G#G$G@GAGDGEGRGSGUGVGWG`GaGeGfGgGhGlGmGvGwGxGzGGGGGGݳݫht6H*] jht htCJH* htCJhtB*CJph jht htH*htht6B*CJ]phht6CJ] jhtCJCGGGGGGGGHHHHHH6HjH|H}H~HHHH I7IKILIdIeIfIgIjIIIIIIIIIIIIIIIIIII,J=J?J]J^J_J`JcJJJJJJJK仯ht6B*CJ]phhtB*CJNHphhtB*CJph htCJH*htCJNHht6B*]ph htH*ht htCJht6CJ] jhtCJ?6HjH I7IjIIII,JcJJJJ(KYLLM @ @ ^@ $ @ @ x^@ a$$ P8x$ pP8@ x$$ pP8@ @ x^@ a$ $ pP8@ KKLKMKdKeKKKKKKKLLLLLLLMMM5MMMMMMMMMMMMMMMNN NN)N*NNN O OOOOOOO"O$OIOJOKOLOQOROeOfOgOhOiOjOj'htEHUjNE htCJUVaJjhtU j|ht jhtht6B*]phht6H*] htNH ht6]ht htCJBM5MN O&OMOOOOOP4P^PPPPPQ @ lx @ x$ pP8@  @ x $ pP8@  $ @ xa$ $ P8jO}O~OOOOOOOOOOOOOOOOOOOOOPP!P"P.P/P0P1P:P;PUIUJUYUZU]U_U`UcU htH* jhtht6B*]phjZhtEHUjE htCJUVaJjDhtEHUj E htCJUVaJjhtU htNH ht6]ht htCJ <`SSSSS+WfWWW3XX&Y3YJYSY~~~ 8@ l`^` 8@ lx^ 8@ l^ $ pP8@ $ x`a$$ pP8@ lx @ x$ pP8@   @ xcUeUhUiUVVVVVVWWJWKW`WbWcWdWfWWWWWWWWWWWWWWWXXXX3XVXWXXXX&YzYYYPZ$[H[q[y[[ĶĶīĶĶīĕĶ!ht5B*OJQJ\^Jphht6B*]ph jhtB*ph jhtB*phhtB*OJQJ^JphhtB*ph jhtB*phhtB*CJphhtB*ph htCJ htNHht ht6]4SY[YvYYYYYYY Z&ZPZ$[1[H[q[y[[[[ \ 8@ l`^` 8@ dl`^` 8@ l`^` 8@ lxx 8@ l`^`[[[f\]]^=^^^_e_%`'`(`)`+`,`9`:``````````aaaaaaaaaaaaaaaabbbccccͶججͶجب؈ htNHht6B*CJ(]ph htH* jht ht6]hthtB*NHphhtB*H*phht6B*CJ]phht6B*]phhtB*ph!ht5B*OJQJ\^JphhtB*OJQJ^Jph3 \)\B\K\\\f\\\\]]]]^^^%^0^=^X^s^^^ 8@ lxx` 8@ l`x^` 8@ lxx 8@ l`^`^^_&_D_M_^_f____bbcIcdd$xa$$xxa$$ 8@ lxx`a$$ 8@ l`x^`a$$ 8@ l`x^`a$ 8@ lxx 8@ l`^`cddd eaebeeeee$f%f:f;fffffffff=g>gDgEggg'h(hSh]hhhminiIjJjjjJkUV/UhtCJOJQJ^JhtOJQJ^J htNHht3de eeeDffffhFijj./ 8pPl @   $ @  a$$xxa$$a$$xa$ $`x^`a$$`^`a$hese routines, as well as your data input and output formats, remain unchanged. This can provide a very useful back-up for any custom macros, as it allows you to check the accuracy of your code. It can also help you identify areas of code where it is worthwhile to pay extra attention to the algorithm used. Some of the macros of the MacroBundle have already spawned x-versions which you can find in the xMacroBundle. You are of course welcome to try them out. Please let me know by e-mail, at rdelevie@ bowdoin.edu, if you encounter any problems with them. ,1h/ =!"#$% Dd J  C A? "2N41T>#5`D`!N41T>#5`& 8>xڕ?Ka繳SH,BNB R= ԐNm SC4-p2TM!]?Sj=޻{b)d1K$$Tu+bRnfΐdcߏ&@Qg1'^UweO|1Gȣ=OEѹ4Ǥ7jb{"$K-wv^)=>)+Ush7j9&9KP|GA|A9.%djL1ub@= S$ʖZr2#̍o){H?꼂lDd  J  C A? "2AC@CdSLG`!AC@CdSLG@0= xڥS=H@~ԦKu]AlVhŴB AW{ g . [E%P%{w=0bDa?ad4u.M3F?'Ȑѩ@QCk4'v필xua)ADlTG2׏o%X/Hqn|Qjg< bsGY\(3E3LwH[P{I Dž3K@&Ñ$>Rp~r=Yrˠn%Dd J  C A? "2{F*폏|)ck`![{F*폏|)(+h)xcdd``$d@9`,&FF(`Ti A?d-P=7T obIFHeA*CPD32BabԘMO_-CۺnuGvEε+[Vul0y_>rx}ǐYv: %%օk ?D+}1G\X E8.p0MfdogM+Dd J  C A? "2mxp@$ i `!amxp@$ &` Pd/xcdd``f 2 ĜL0##0KQ* Wä"d3H1)fY;X3PT obIFHeA*/&*fe-f Y, wfjQ9B&br(b5~=Wͷ zzf7zH܌{ fjWvMމ?CemUDd J  C A? "2 bsUEa]a`! bsUEa] ~ hYxڕRJ@$M Q*}Qzy -ĽH#!R)|q'+0o/ 6,\GrD!eYPLZj4!`.a2I +֘_5@F=(st\6j&]Bt?hfhn=ڨk9GG'VBOGq4? >MO_-Cۺ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdfghijklorstvuwxy{z|~}Root EntryA Fj|<qData eWordDocument@.ObjectPoolC']^|<j|<_1167746037F]^|<_|<Ole CompObjfObjInfo "%(+,-.1458;>ADGJMOPQRSTVWXY[ FMicrosoft Equation 3.0 DS Equation Equation.39q*f nm()=n!m!(n"m)!Equation Native _1167803293; F_|<_|<Ole CompObj f FMicrosoft Equation 3.0 DS Equation Equation.39q*lh  a i,jj=1n " i=1m "  FMicrosoft Equation 3.0 DS EqObjInfo Equation Native  _1167763278F_|< ka|<Ole CompObjfObjInfoEquation Native D_1167763325"Fb|<b|<uation Equation.39q*(< a+jb FMicrosoft Equation 3.0 DS Equation Equation.39qOle CompObjfObjInfoEquation Native T*81  a 2 +b 2 FMicrosoft Equation 3.0 DS Equation Equation.39q*&p 1a+jb_11677925756F ka|<b|<Ole CompObjfObjInfoEquation Native B_1167792585Fb|<b|<Ole  CompObj !f FMicrosoft Equation 3.0 DS Equation Equation.39q*QF "ab+jba 2 +b 2 FMicrosoft Equation 3.0 DS EqObjInfo!#Equation Native $m_1167766428$Fb|<`xd|<Ole &CompObj#%'fObjInfo&)Equation Native *_11677665471)F`xd|<`xd|<uation Equation.39q*= (a 1 a 2 +b 2 b 2 )+j("a 1 b 2 +a 2 b 1 )a 22 +b 22Ole /CompObj(*0fObjInfo+2Equation Native 3 FMicrosoft Equation 3.0 DS Equation Equation.39q*…8<  a 2 +b 2 exp[narctan(a/b)] FMicrosoft Equation 3.0 DS Eq_1167791987.F`xd|<e|<Ole 6CompObj-/7fObjInfo09uation Equation.39q*'h  a+jb n FMicrosoft Equation 3.0 DS Equation Equation.39qEquation Native :C_1167792290,3Fe|<e|<Ole <CompObj24=fObjInfo5?Equation Native @C_1167793420 8Fe|<g|<Ole B*'8  a+jb   FMicrosoft Equation 3.0 DS Equation Equation.39q*'8 e  CompObj79CfObjInfo:EEquation Native FC_1167793612=Fg|<g|<Ole HCompObj<>IfObjInfo?KEquation Native Li FMicrosoft Equation 3.0 DS Equation Equation.39q*Mp cos()+jsin()Oh+'0 nuGvEε+[Vul0y_>rx}ǐYv: %%օk ?D+}1G\X E8.p0MfdogMDd J  C A? "2^&Z0r`!^&Z0r. `Pxڝ=HP]b?jP!*(C`n BPqru(C $`|iAMy./y Z7:c;BƼ2e=\EqV 1W>\Dx(LJJB| UFZ;eMB;L|j5\+/Ena5/m&rFPKGDjQuAm\n`!$ _ukV>\RxڝRJP>礿ii-E! E n(bIT -ZHuG7 DpT\''87rs{%` 3KSb!/ NL9yʉLɠ11Y?up&&X bQjׄ7NWb3)Cg@e,x.gAO|B@kY桾aV2pu?=fhT<$j@g|3ZjfLjyNh;1CW"Q= ŹD ,IZ>+5~1Zr$̖w~m9~u{}ǩ?}uӇ6ڂ%o??K ߔ,y'Ao+n0GN<^;) ׾ubifZ()wô?@+d0 #Xƥ[">{ǓgT^ib?Dd J   C A ? " 2X7Ғw-kGo}I`!uX7Ғw-kGo*hCxmJPƿsM tEE`cBp)9(,?)Z=!gP$QB1UykFVqUpVjLLcK)|2Uv41%O6'r%Vxh5gK=°u|bhJrWRe8{Q4q$X}XۆѣFsvj4Hp]wW&+гSI^>&u1/^?Ua Vo5= .GWDd XhJ   C A ? " 2x[GZ%DFT`!L[GZ%DF@|xcdd`` @c112BYL%bpu 13*ߍ/b/I~׀dBV>0!V\28' F&&\A z> 1.a......!/M/{////0L0y0000 1,1d11112;2Q2s222 333y33334O4f4444 5=5T5}55556)6f66O7}77778F8n888889:K:r:::;4;b;;;;$<W<z<<<==6=j= >7>j>>>>,?c????(@YAAB5BC D&DMDDDDDE4E^EEEEEF9F`F}FFFFGEGkGGGGG"H7H`HHHHH+LfLLL3MM&N3NJNSN[NvNNNNNNN O&OPO$P1PHPqPyPPPP Q)QBQKQ\QfQQQQRRRRSSS%S0S=SXSsSSSST&TDTMT^TfTTTTWWXIXYYZ ZZZD[[[[]F^__xb{b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000(0000000000000000000000000000000000000000000000000000000000 J{bۊ0DlZي0ي0ABGHۊ0DFS0%,2469;|?D_FGKjOPyQRcU[c/69:<?BDFHIKMOPRTUWXZ\_Um!#~)H.3_5L9<AC6HMQ`SSY \^d/7;=>@ACEGJLNQSVY[]^`/82223:G:I:QDeDgDiD}DDDDDDDD?ESEUEdFxFzFFFFFGGIG]G_GgH{H}HHHHyb:::::::::::::l,b$=W;e]vL٧ @0(  B S  ?ybf r   ? E G S Y i  JCNQ\@L +/8<DO^ix"s |  !!*!F!V!z%%%%%%%%%%%%%&&,&k&{&&&&&P(](************+"+#+&+)+0+3+6+D+H+I+L+O+V+d+h+n+r+++++++++++++++++++++ ,,,,,!,$,',-,8,I,M,N,Q,T,[,z,~,,,,,,,,,,,,,-6-D-I-J-M-P-W-w-z-----..I.M.N.O.R.Y.k.p.q.r.u.|.........../ /////4/9/@/C/I/]/b/g/n/q/w///////////0 000002060;0B0]0b0g0n0q0u0{00000000000000E1K1P1W1Z1`1f1l1q1s11111111111112 2222 2+2-2\2a2f2m2y222222223393c3e3j3l3~33333333T4W4Z4a4i4p44444 555 5,505K5O5Q5Q555555555555566,6166677777777888&8I8P8q8x88888999:: :3:J:Y:`:e:k:::::;;#;);s;|;;;;;;;5<><H<N<<<<<<<<<<<I=Q=_=e=>'>,>2>:>B>>>>>??"?(?r?~???????? @@@@@LARAoA|A}AAAAAAAAhBoBBBCCCCCDDD"D$D6D:D?DEDQDhDiDDDDDDDDDDDDDDEEEE$E+E?EVEhElEuE{EEEEEEEFFCFGFPFVFdF{FFFFFFFFFFFFFFFFFF G*G.G8G>GIG`GxG|GGGGGGGGGGGGGGGGGGGGGGGH HHH'H)H/H1HIHOHTHZHgH~HHHHHHHbIbIcJeJJJJJJJJJJJJJJJJJJJK K KKKK!K&K+K0KBKFKHKLKNKRKXK\K]KbKgKlK?LDLMLTLLLLLLLLM3M9MIMLM{NNNNNNPPPPPPPP QQ)Q4Q6Q:QQQSSSSSSTT&T1TxZZZZ"[+[[[]]6^;^e^q^w__aa8b@bBbMb{bJevx'/Ya27:;$'+08== E M O i k !F!W!""-"9"A%I%Q%S%p%r%%%%%%&k&|&&&8*=*g*j*******+#+D+I+_+a+++++++ ,,1,2,I,N,z,,,,,,----/-0-D-J-b-d---..I.N.k.q......./ ///5/]/c/////0 02070]0c0{00000000 11E1L1f1l11111122 2\2b2u2x222c3f3~333333334!4T4X44444 55K5P5V5^5555555556 6,6266697?7d7j777777788I8Q8q8y8889:Y:a:::::;;s;};;;5<?<Z<^<<<<<O=R=%>(>:>Q>>>>>??E?J?r????@@j@|@xA}ACCDD6D;DDDDDEEhEmEEEEFCFHFFFFFGG*G/GxG}GGGGGGGH H'H*HIHPHHH?LELLLLL=MAM*N2N:N'>*>*>:>R>g>i>>>????,?c?????QDhDiDDDDDD?EVEdF{FFFF GIG`GgH~HHHbIbIJJJJ$P$PPPWW Z Z0Z3ZTZ[Z]ZZZZZZZZZZ7^8^>_r_d`d`xb{bJO{bt!%BI@JJhJJJL./35J`ybp@p6pp@p<p@p@UnknownG: Times New Roman5Symbol3& : Arial;Wingdings?5 : Courier New"1hFFX}S2S2!24dGbGb2QHP)?I2FunctionRobert de LevieIT