University of Waterloo Faculty of Engineering Department of Electrical and Computer Engineering NE 216 Laboratory 1 FALL 2011 Prepared by Surname/Last Name, Legal Given/First Name(s) UW Student ID Number: 2NNNNNNN UW User ID: uwuserid @uwaterloo.ca Prepared by Surname/Last Name, Legal Given/First Name(s) UW Student ID Number: 2NNNNNNN UW User ID: uwuserid @uwaterloo.ca 2A Nanotechnology Engineering Today’s Date 1.0 Differentiating your UW User ID and your UW Student ID Number Your UW User ID is up to eight letters or numbers that allows you to log onto Quest, Unix, etc. Enter it your: Your UW User ID Your UW Student ID number is eight digits starting with 2 that uniquely identifies you as a student at the University of Waterloo. Enter it your UW Student ID Number here: Your UW Student ID Number In general, do not give your UW Student ID Number to anyone except those working in an official capacity with the University of Waterloo. Especially, do not include it automatically in your signature; however, you should include both your UW User ID and your UW Student ID Number in any e-mail correspondence with a university official. In balance of this laboratory will look at halting conditions. 1.1 Determining the problem of non-convergence Any numerical algorithm may never actually halt—perhaps because there is no solution, or there may be a characteristic of the problem that does not allow a solution to be found. For example, the following is an implementation of the secant method. Given two points, we find the interpolating line that passes through them and then we find the root of that line. Figure 1. Interpolating two points and finding the root of the interpolating polynomial. 2 function [x2] = secant( f, x0, x1 ) while true x2 = ...; if x1 == x2 return; end x0 = x1; x1 = x2; end end As a reminder, File→New→Function and cut-and-paste the above code into the editor and the name of the file must be the name of the function followed with a ".m"; in this case, the file name would be "secant.m". The interpolating polynomial is y f x0 x x0 x x1 f x1 x0 x1 x1 x0 0 f x0 x x0 x x1 f x1 x0 x1 x1 x0 Solve the equation for x which is the root of the interpolating polynomial (the blue point in Figure 1) and assign that value to x2. You can try your function out: >> secant( @cos, 1, 1.1 ) ans = 1.570796326794897 Once this works, you can continue. 3 What happens if you execute >> secant( @log, 4, 2 ) ? You should make use of Ctrl-C in order to halt your program. To observe what is happening, you can either remove a semi-colon from one of the lines in your function (this will print it to the screen as the function executes) or you can use the debugger by clicking to the left of the line you want Matlab to stop at, as shown in Figure 2. Figure 2. Using the debugger. The next time you run, you be in the debugger as soon as the execution reaches the line you highlighted. To clear the break point, click on the break point a second time. In the Matlab command window, you can now determine the value of a variable: K>> x0 x0 = 1.100000000000000 4 You can now perform one of a number of options, as is shown in Figure 3. Figure 3. Options available in debugging. These options perform the following actions: 1. Step: execute the statement we are currently on. If it is a for, while or if statement or a function call, it will execute the entire loop, condition, or function call. 2. Step in: execute the statement we are currently on. If it is a for, while or if statement or a function call, step into the body of that structure and stop at the first statement in that for, while or if statement, or function call. 3. Step out: whatever body you are in, whether it be a for, while or if statement or a function call, continue executing it to the end and stop at the next statement following it. 4. Continue: Continue executing until either we return to the Matlab prompt or we reach the next break point. 5. Exit debug mode: This should be self evident.... These names are visible if you hover over the icons. Based on your use of the debugger and the information that was provided during the presentation, why is secant( @log, 4, 2 ) going into an infinite loop? Your answer here. 5 In the Matlab command window, enter your UW User IDs and take a screen shot of the Matlab (in Windows, Ctrl-Alt-PrtScn) and paste that image (Ctrl-V) into Figure 4. You should be see the offending value of x2 that is causing Matlab to go into an infinite loop. Figure 4. Your screenshot. 6 1.2 Limiting the number of iterations. Thus, rather than using a while-true loop, we will allow the user to pass a second parameter, N_max, the maximum number of iterations. function [x2] = secant( f, x0, x1, N_max ) for i = 1:N_max % the body of the while loop here... end end Notice that the parameters that define the mathematical problem come first (we want to find a root of f(x) using the secant method starting with x0 and x1. The parameter Nmax determines the behaviour of the numerical algorithm and does not affect the problem, so we place it at the end. Thus, if the function iterations more than Nmax times and does not converge, the for loop will end and the function will exit. At this point, we must indicate that there is a problem; otherwise, the function will just return the last value of x2—something we did not want because it is not valid. Instead, we will signal that an exception has occurred; that is, we will throw an exception: throw( MException( 'MATLAB:numeric_exception', ... '..' ) ); In this case, the throw command indicates a message is to be sent. That message is an MException and the first argument of MException is the message identifier. The identifier must be a string starting with the seven characters 'Matlab:' and the remaining characters (letters, numbers, or underscores) should describe what is happening. In the above, the identifier is that a numeric exception has occurred. After the for loop, replace the .. add a message that you think would be useful for the user. In this message, you can use regular any character on the keyboard with a few exceptions which you can find if you do a search for strings in the Matlab help dialog shown in Figure 5. 7 Figure 5. The Matlab help dialog. First, save the function function [y] = f1a( x ) y = x.^2 + 1; end and then test your output by running the two instructions: secant( @sin, 3, 3.1, 20 ) secant( @f1a, 3, 3.1, 20 ) Copy and paste your Matlab commands and the output here. 8 1.3 When to Stop in the x-direction Consider the following example: function [y] = f1b( x ) y = cos(1./x); end When the following command >> secant( @f1b, 0.000722, 0.0007221, 100 ) is executed, at least with the author’s implementation, the algorithm goes into an infinite loop with the values of x2 being: 7.226104113139403e-004 7.226104113139402e-004 7.226104113139401e-004 7.226104113139403e-004 7.226104113139402e-004 7.226104113139401e-004 7.226104113139403e-004 As you can see, even though the correct answer is 0.00072261041131394023···, the answer oscillates around the solution. Thus, we really should stop, but what value of x should we return as the approximation of the root? In addition, is there any engineer in the world who really needs sixteen digits of precision, or even 10? Would not under many conditions an approximation of 0.00072261 be good enough; after all, the relative error of this approximation is 0.000057 %. What we need is an alternate terminating condition: one that the user can control. We will say that an approximation close enough if two approximations are sufficiently close. That is, if x2 x1 step . If two successive approximations are sufficiently close, we will also assume that x2 x* step where x* is the actual solution. Thus, rather than checking if x1 == x2, we will instead check that abs( x2 - x1 ) < eps_step This parameter must also be passed. We pass it as the fourth parameter and move N_max to the fifth location with the justification that eps_step indicates when to halt successfully (relatively more important) while N_max indicates when to signal a failure. 9 function [x2] = secant( f, x0, x1, eps_step, N_max ) % Enter the body of your function here end Now, test your code here: secant( @f1b, 0.000722, 0.0007221, 1e-4, 100 ) Copy and paste your Matlab commands and the output here. 10 1.4 When to Stop in the y-direction Using the same function, >> x1b = secant( @f1b, 0.000722, 0.0007221, 1e-6, 100 ) x1b = 7.230088870592349e-004 >> f1b( x1b ) ans = 0.690876363485700 >> x1b = secant( @f1b, 0.000722, 0.0007221, 1e-7, 100 ) x1b = 7.226118709557649e-004 >> f1b( x1b ) ans = 0.002795351509144 >> x1b = secant( @f1b, 0.000722, 0.0007221, 1e-8, 100 ) x1b = 7.226104111736519e-004 >> f1b( x1b ) ans = -2.686662956663953e-007 Thus, in the first case, even though we stopped when successive steps in the x-direction were sufficiently small, the answer was still not optimal: f1b( 0.000723) is very large— around 0.69—and not something we would call a root! Thus, we cannot stop just because step size is sufficiently small between approximations: we must also make sure that we are getting something that is close enough to a real answer. Therefore, we will add a second condition: f x2 abs . Because both conditions must be met, we must use && and add eps_abs as a fifth parameter, relegating N_max again to the sixth location. function [x2] = secant( f, x0, x1, eps_step, eps_abs, N_max ) % Enter the body of your function here end 11 Now, when you execute: x1 = secant( @f1b, 0.000722, 0.0007221, 1e-6, 1e-16, 100 ) f1b( x1b ) the answer should converge and the answer should be a reasonably good approximation of a root. Copy and paste your Matlab commands and the output here. 12 1.5 Comments Next, any significant amount of code that you write today, even if you read it again six months from now, you will likely not remember what you meant to do. It is therefore best if you start now learning how to comment: get into the habit now and it will become part of your routine. More importantly, when you are employed as an engineer, others will be doing the coding for you and if you do not set good commenting standards, your employees, too, will become lazy costing you your bonus (most significantly, maintenance costs will increase—the author remembers spending in some cases hours trying to determine why the original author of a piece of code wrote what he did—it was wrong, but because there was no description or justification, it cost approximately $200 of developer time to determine the mistake—probably much more than it cost to have the original author write those few lines of code. Cut and paste the following into your code and then replace it once you have added comments. Any red text must be removed. % Secant method % % % % % % % % % % % % % % % % Write a description of what the function is suppose to do here. paragraph or two. Parameters ========== f x0 x1 eps_step eps_abs N_max It should be a For each of these, replace the ... with a comment about the parameter, what it means, what it controls. ... ... ... ... ... ... Return Values ============= x2 ... For each return value, indicate the significance. In the body of the function, any significant block of code, for-loop, or ifstatement should have a comment before it indicating the purpose. This need only be a few lines or even one line. Do not over comment--we do not need one comment per line. function [x2] = secant( f, x0, x1, eps_step, eps_abs, N_max ) % Enter the body of your function here end 13 These are short-answer questions. Please note, all subsequent laboratories will not have such a section. This is here to help your understanding of floating-point numbers. 1.6a General knowledge: if you accidently assign to a name that is being used as a function, you get a very specific error. For example, consider >> sum = sum( 1:100 ); What happens if you try to call sum again? The exact error message is “Enter Error Message Here”. Does this differ from the error message when you try the following? >> M = [1 2 3; 4 5 6; 7 8 9]; >> M( 1:100 ) Yes/No You can unassign names that are accidently assigned by typing, for example, >> clear sum 1.6b Split the following numbers into the sign bit, the eleven exponent bits, and the 52 mantissa bits: format hex 10532.0947265625 ans = 40c4920c20000000 1 sign bit: 11 exponent bits: 52 mantissa bits: You can use 0...0 to indicate all trailing zero bits. Consider using the Microsoft Calculator with the View→Scientific option selected. Alternatively, you can also use: 0 1 2 3 4 5 6 7 0000 0001 0010 0011 0100 0101 0110 0111 8 9 a b c d e f 14 1000 1001 1010 1011 1100 1101 1110 1111 1.6c Place an x in the appropriate column of Table 1 to indicate whether the doubleprecision floating-point numbers represent positive or negative values. Table 1. Positive and negative floating-point numbers. Representation Positive Negative 3f293ac9d935310c 1ce0f5ff5675cf94 d933f307fea5b029 b5fe6a8a831e7905 28a43e05659feaf3 3744be1ee8f9f90c x 1.6d For each of the numbers in Table 2, find the exponent as a decimal power of two. As an example, the first three questions have already been completed: Table 2 Exponents of double-precision floating-point numbers. Representation Exponent 3ff0000000000000 3f193ac9d935310c 4020f5ff5675cf94 4033f307fea5b029 408e6a8a831e7905 3f743e05659feaf3 3f84be1ee8f9f90c 3ef0f5ff5675cf94 0 -14 3 ? ? ? ? ? Note that you can check your answer by comparing the first three hexadecimal digits of the number. For example, the first three hexadecimal digits of 2-14, 2-13, 22 and 23 are 3f1, 3f1, 401 and 402, respectively. 15 1.6e The variable eps is automatically assigned the distance from 1 to the next largest floating-point number; that is, 1 + eps is not equal to 1: >> 1 ans = 3ff0000000000000 >> 1 + eps ans = 3ff0000000000001 Find the next smaller floating point number before 1 by subtracting off an appropriate multiple of eps. Hints: it’s not 1 – eps and use format hex. >> format hex >> 1 - ??? % Enter your code and the output here 1.6f The variable eps is equal to 2–n for what value of n? What other number does this value of n represent with respect to the double format? Your answer here. 1.6g What is the correct mantissa of the following double-precision floating point numbers shown in Table 3? Table 3. Mantissas of floating-point numbers. Representation Mantissa 3f193a0000000000 1.1001001110100...0 4020f10000000000 1.0000111100010...0 4033f00000000000 1.???? 414e600000000000 1.???? 3f74300000000000 1.???? 1.6h What is the smallest integer power n of 10 such that 10n is not a denormalized number (that is, the exponent as hexadecimal numbers are not yet 000). >> 1e-??? % Enter your code and the output here 1.6i What is the smallest integer power n of 10 such that 10n is not zero? >> 1e-??? % Enter your code and the output here 1.6j What is the largest integer power n of 10 such that 10n is not infinity? >> 1e??? % Enter your code and the output here 16 1.6k Calculate each of the following to determine the result. Expression Inf Inf Inf Inf + * / Output 0 0 0 0 Inf ? ? ? ? ? ? ? ? ? ? ? ? 0 - Inf 0 / Inf Inf + Inf Inf – Inf Inf * Inf Inf / Inf Inf^-Inf 0^0 Inf^0 1.6l Is the representation of NaN and -Nan different in as double-precision floating-point numbers (use format hex)? Yes or No? 1.6m You are given these five double-precision floating point numbers. 1ec08f8bf99a36fe 67caccf63d443628 6910b6f1ba816f22 46b6acf2673e096a 183dc6edceef302d Order them from smallest to largest and place them in Table 4. Table 4. Order of floating-point numbers. Smallest 3ff0000000000000 Largest 3ff0000000000000 3ff0000000000000 3ff0000000000000 3ff0000000000000 17 1.6nYou are given these six double-precision floating point numbers. cd617c809c482961 54d3c359e37c5187 4d41c8436fa8ce8e bb825a24626f4112 c42c3c937cc00418 2d91ca5f2651c8b8 Order them from smallest (the largest negative number) to largest (the largest positive number) and place your answer in Table 5. Table 5. Order of floating-point numbers. Smallest 3ff0000000000000 Largest 3ff0000000000000 3ff0000000000000 3ff0000000000000 3ff0000000000000 3ff0000000000000 18