Documente Academic
Documente Profesional
Documente Cultură
Users Guide
Version 1
508-647-7000 508-647-7001 The MathWorks, Inc. 3 Apple Hill Drive Natick, MA 01760-2098
http://www.mathworks.com ftp.mathworks.com comp.soft-sys.matlab support@mathworks.com suggest@mathworks.com bugs@mathworks.com doc@mathworks.com subscribe@mathworks.com service@mathworks.com info@mathworks.com
Web Anonymous FTP server Newsgroup Technical support Product enhancement suggestions Bug reports Documentation error reports Subscribing user registration Order status, license renewals, passcodes Sales, pricing, and general information
Contents
Introduction to MatrixVB
1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2 Create a New Visual Basic Project . . . . . . . . . . . . . . . . . . . . . . . 1-2 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-7
2
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-5 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6 Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-9 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-12 ByVal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-12 Flow Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . If Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Select Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Do While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2-15 2-15 2-16 2-17 2-18
Matrices
3
What are Matrices? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2
Creating Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 Created by Matrix Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-3 Created by a Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-4 Accessing Matrix Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indexing by Parentheses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indexing by rN and iN Functions . . . . . . . . . . . . . . . . . . . . . . . . Converting Matrices to Visual Basic Types . . . . . . . . . . . . . . . .
3-6 3-6 3-6 3-7
Matrix Properties and Methods . . . . . . . . . . . . . . . . . . . . . . . . 3-8 Rows and Cols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-8 Dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-8 Saving and Loading Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . 3-9 vbsave and vbload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-9 Other File I/O Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-9
Operators
4
Visual Basic Operators and MatrixVB Equivalents . . . . . . . Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Concatenation Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4-2 4-2 4-3 4-4 4-5
Graphics
5
Using MatrixVB Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Plots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Plotting to a Visual Basic Window . . . . . . . . . . . . . . . . . . . . . . . Figure Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5-2 5-2 5-4 5-5
ii
Contents
Additional Examples
6
Enhanced Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2 Matrix Determinant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6 Fast Fourier Transform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-6 Solving Linear Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-7 Eigenvalues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-8 Complex Matrix: Polynomial Roots . . . . . . . . . . . . . . . . . . . . . 6-8 Polynomial Fit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-9 Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10 Random Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10 Generating a List of Primes . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11 LU Factorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-11 Singular Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12 Linear Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-12
A
Index
iii
iv
Contents
1
Introduction to MatrixVB
Introduction . . . . . . . . . . . . . . . . . . . . 1-2 Create a New Visual Basic Project . . . . . . . . . . . 1-2 Summary . . . . . . . . . . . . . . . . . . . . . . 1-7
Introduction to MatrixVB
Introduction
MatrixVB is a COM library, a collection of functions that enhance Visual Basics built-in functionality by allowing users easy access to many powerful computational algorithms. This chapter introduces the MatrixVB library with a complete program that demonstrates some of its computational and graphical capabilities. Along the way you will see how to: Add the MatrixVB library to a Visual Basic project Call MatrixVB functions Create matrices Set matrix elements Get matrix elements After reading this chapter you will have a running program that uses MatrixVB functionality to display fractal images.
1-2
Introduction
2 t2 erf ( x ) = -- e dt
evaluated at x=1. (The error function is not available to Visual Basic without the MatrixVB library.) The second line, x.show, opens the Matrix Viewer and shows the contents of the variable x.
The simple function may be used to convert the 1-by-1 matrix x into a double value. In the Immediate window, enter
x.simple
1-3
Introduction to MatrixVB
Example: Fractals
Double click on the Form1 window to open the Code window and begin writing code. (The Code window could also be opened from the View menu, but double-clicking on the form also automatically creates the Form_Load() subroutine.) Add these two lines to the Form_Load() subroutine:
ax = vbaxes(Form1.hWnd) Call Form_Resize
The first line instructs Visual Basic to place graphics on Form1. The axes handle is stored in the variant ax for future use; the variant must be added to the Declarations section of the code (before the first subroutine call):
Dim ax as Variant Adding a Subroutine. The Form_Load() subroutine calls another subroutine, named Form_Resize(). Since we havent defined this subroutine, we should do so now. Scroll down in the Code window, and place the cursor after the End Sub statement. Press a few carriage returns to start the new subroutine on a new line with space between this one and the previous one.
The Visual Basic code editor may type some parts automatically. For instance, as soon as the editor realizes you are starting a subroutine, it may place the End Sub command a few lines below the Private Sub declaration. To make the program more readable, the editor separates the various parts (Declarations, Subroutines, etc) from each other with a horizontal line. At this point, your program should look something like:
Dim ax As Variant Private Sub Form_Load() ax = vbaxes(Form1.hWnd) Call Form_Resize End Sub Private Sub Form_Resize()
1-4
Introduction
vbrefresh ax End Sub Adding Objects to a Form. You can add graphic objects to the Form by choosing the desired object from the Visual Basic toolbar, then indicating where on the Form you want the object. For this example, add a button to the Form. You can change its name later, but for now leave it at Command1. Double click on the button to begin editing the Command1_Click() callback function.
First make sure that the user of your program cannot press the button again before the program is finished.
Command1.Visible=false
Next create a rectangular grid on your figure; the fractal will be computed at each point in the grid. meshgrid returns two outputs in XY. Store these for later use in the arrays X and Y.
X=linspace(cx-l,cx+l,m) Y=linspace(cy-l,cy+l,m) XY=meshgrid(X,Y) X=XY(1) Y=XY(2)
Create a matrix Z to contain values just a bit greater than zero, and create a complex matrix C from the arrays X and Y.
Z=plus(zeros(m),2.22e-16) C=mcomplex(X,Y)
1-5
Introduction to MatrixVB
Z = Z +C
For k=1 to N Form1.Caption = titl & " (calculating " & k & "/" & N & ")" DoEvents Z=plus(power(Z,Z),C) Next Form1.Caption = titl
W=mexp(uminus(mabs(Z)))
Note A single marks the beginning of a comment. The Visual Basic interpreter parses nothing after the .
Run the Example. Press the Go button to run your program. Press the
Command1 button on the form to compute and display the fractal. It should look like:
1-6
Introduction
Summary
Congratulations! You have successfully written a Visual Basic program that uses the capabilities of the MatrixVB library! Your complete program listing should look like this.
Dim ax as Variant Private Sub Command1.Click() Command1.Visible=false titl="MatrixVB Fractal Demo" Form1.Caption = titl fractal parameters N=14 m=300 cx=0.025
1-7
Introduction to MatrixVB
cy=0 l=0.03 generate rectangular grid X=linspace(cx-l,cx+l,m) Y=linspace(cy-l,cy+l,m) XY=meshgrid(X,Y) X=XY(1) Y=XY(2) create arrays for fractal Z=plus(zeros(m),2.22e-16) C=mcomplex(X,Y) main calculation loop For k=1 to N Form1.Caption = titl & " (calculating " & k & "/" & N & ")" DoEvents Z=plus(power(Z,Z),C) Next Form1.Caption = titl generate fractal W=mexp(uminus(mabs(Z))) display fractal pcolor(W) colormap(summer) axis("off") End Sub Private Sub Form_Load() ax = vbaxes(Form1.hWnd) Call Form_Resize() End Sub Private Sub Form_Resize() Vbrefresh ax End Sub
For a bit of extra practice, try setting the fractal parameters (N, m, cx, cy, l) to be user inputs, using Text controls. Remember, in this case, that the val command converts string input (from the Text control) into numerical data (for the fractal calculations).
1-8
2
Introduction to Visual Basic
Variables . . . . . . . . . . . . . . . . . . . . . 2-3 Data Types . . . . . . . . . . . . . . . . . . . . . 2-5 Constants . . . . . . . . . . . . . . . . . . . . . . 2-6 Arrays . . . . . . . . . . . . . . . . . . . . . . . 2-6 Subroutines . . . . . . . . . . . . . . . . . . . . 2-9 Functions . . . . . . . . . . . . . . . . . . . . . 2-12 ByVal . . . . . . . . . . . . . . . . . . . . . . . 2-12 Flow Control If Blocks . . Select Case . Loops . . . Do While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-15 . 2-15 . 2-16 . 2-17 . 2-18
Because MatrixVB is an add-on to Visual Basic, it might help to know a bit about Visual Basic before going much farther with MatrixVB. This chapter will guide you through some of the basics of Visual Basic programming, such as variables, data types, subroutines, functions, and program flow control.
2-2
Variables
Variables
Variables are an integral part of any programming language, and of any program. Variables let you run one program on a many different sets of data, rather than having to write separate programs that do the equivalent thing for each data set. For example, you can find a simple sum of two numbers by entering a command in the Immediate window.
?3+5 8
Later, if you need the sum of two different numbers, you can again ask for that in the Immediate window
?4+19 23
and so on. Alternatively, you could write a simple calculator program that allows you to enter any two numbers and press a button to get the answer. Here is that code produces just such a calculator.
Dim a As Double Dim b As Double Dim sum As Double Private Sub Command1_Click() a = Val(Text1.Text) b = Val(Text2.Text) sum = a + b Label1.Caption = sum End Sub Private Sub Form_Load() Text1.Text = "1" Text2.Text = "2" Label1.Caption = "Press =" End Sub
Admittedly, thats a lot of code to produce the sum of a + b, and it presumes the existence of a Form with some Text objects, Labels, and a Command button.
2-3
You only have to create those things once, though, and you can use them forever. Heres the Form that goes with that code.
When the program is running, replace the Text1 and Text2 strings with the numbers you want to add, press the = button, and read the sum from the Label1 box.
2-4
Data Types
Data Types
Now look at the code more closely. The first three lines
Dim a As Double Dim b As Double Dim sum As Double
are declaration statements. These tell the Visual Basic compiler that the three variables, a, b, and sum, should be treated as double precision floating point numbers, i.e., eight bytes of memory are set aside for the contents of each of these variables. Strictly speaking, the declaration statements are not necessary. Visual Basic treats undeclared variables as Variants, a special data type that can accommodate any kind of data (numeric, string, boolean, etc). Declarations often make code easier to read and debug, though, and forcing the Visual Basic compiler to treat variables as one data type can often prevent errors that may arise if there is ambiguity in the way a variable should be handled. Other data types that can be declared are: Integer: Two-byte integers. Values from -32,768 to 32,767. Long: Four-byte integers. Values from -2,147,483,648 to 2,147,483,647. Single: Four-byte floating point numbers. Values in the range 10-45 to 1038. Double: Eight-byte floating point numbers. Values in the range 10-324 to 10308 . Currency: Fixed point values with four decimal digits, in the range -922,337,203,685,477.5808 to 922,337,203,685,477.5807. Byte: Integers in the range 0 to 255. Byte variables are typically used in accessing binary files (sound or image files, for example). Byte variables may be used in normal calculations, but the result cannot be assigned to another byte variable if the result is outside the allowable range for the byte type. String: Text. Strings may be declared as fixed-length (Dim textvar As String * 1000, for example, specifies that textvar will be 1000 characters long); otherwise the string will be resized as its contents change. Boolean: True (non-zero) or False (zero). Boolean values are initialized as False.
2-5
Date: Four-byte floating point numbers. The integer part represents the date, and the fractional part stores the time. Object: Information about graphical objects. Variant: Any kind of information. This type is the default for undeclared variables.
Constants
Variables that always have the same value while your program is executing may be declared as Constants. Constants have two advantages over normal variables.
1 The values stored in variables probably change at some point during the
programs run; constants never do. If you've declared something Constant, you will know you are debugging your program what that Constant has stored away.
2 Constants are processed faster than variables because Visual Basic has to
go back and check on the values of variables. It doesnt have to do that with Constants because it already knows the value hasnt changed. Constants are declared in much the same way as other variables, except that values must also be given in the declaration statement:
Const pi As Double = 3.14159265358979
You must supply an actual value for the Constant; you cannot use a function or other variable to supply the value.
Arrays
Arrays are variables that can hold sets of related information, rather than just one value. Unlike normal variables, though, arrays must be declared. The declaration must also specify the size of the array.
Dim A(15) As Double
This creates a double-precision array A that can store 16 values (elements A(0) through A(15)). You can assign values to the individual elements just as if they were ordinary variables.
2-6
Data Types
Later, when you need to know the contents of a particular array element, you can access it by its index.
If A(5) < 20 then
The limits of the array may also be specified in the declaration, in case the default (First element 0) doesnt appeal to you. For example
Dim A(1 to 16) As Double
creates the same 16-element array A, but the first element is A(1), the last is A(16). In fact, if you use this type of declaration, the bounds can be anything, provided the lower bound is specified first.
Dim A(150 to 165) As Double Dim A(1000 to 1015) As Double
creates a 50 by 400 array, consisting of 50 rows with 400 columns each. Reading and writing to multi-dimensional arrays is the same as for single-dimensional arrays, except you need to specify both indices:
2-7
= = = = = =
1 1 1 1 2 3
and so on. Arrays are not just for numeric data; they may be declared for any of the data types listed above.
2-8
Subroutines
Subroutines
Another important aspect of a program is the notion of a procedure. A procedure is any sequence of commands you want a program to execute. For the calculator program, the sequence might be: Read the input variables Add the input variables Display the sum In general, when you can isolate a sequence of commands that you plan to use repetitively, it is better to group them into a subroutine. Then, when you need to use them, you can simply call the subroutine instead of rewriting the whole sequence. For example, in the calculator program, the Read/Add/Display sequence is written in the following subroutine, which is executed each time you press the = button:
Private Sub Command1_Click() a = Val(Text1.Text) b = Val(Text2.Text) Sum = a + b Label1.Caption = Sum End Sub Private Sub means that this subroutine is available only to this Form; no other program you write will be able to use it. Command1_Click() is the name of the subroutine, as well as descriptive of when it will be run. The next three lines are the heart of the routine. They read the values you input to the calculator and add them. The fourth line places the sum of the two inputs in the output block on the calculator, Label1. The last line, End Sub, ends the subroutine.
2-9
is another subroutine, which runs when the Form is loaded. These lines simply initialize the calculator inputs, and use the output Label1 to tell you how to get the sum. You may also call subroutines from other parts of your code, without linking them to events such as pressing buttons or loading forms. In these cases, you can call them with the Call statement. For example, the calculator above might be programmed to display negative sums in red and positive sums in black. You could write the color-change statements in a SetColor subroutine.
Private Sub SetColor(TargetColor As Long) Label1.ForeColor = TargetColor End Sub
(Note that the data type of the input argument, TargetColor, is declared in the subroutine declaration statement.) Then you could add the following lines to the Command1_Click() routine, to check the result and decide what color the display should be.
If Sum <= 0 then SumColor = &H000000FF that means "red" Else SumColor = &H00000000 that means "black" End If
(You may also want to add Dim SumColor As Long to the declarations part of the program rather than let Visual Basic create a variant for SumColor.) Visual Basic, like some other high-level programming languages, actually offers two ways of calling subroutines. Instead of the above, you could also use:
SetColor SumColor
Some people like to use Call with the parentheses, so that its obvious they are calling subroutines, and some people dont like to type any more than is absolutely necessary. That is the only real difference between the two forms.
2-10
Subroutines
Note Visual Basic may convert the long integers &H00000000 and &H000000FF to shorter forms, &H0 and &HFF, in the Code window. Dont let that confuse you; it is basically the same as writing 100 dollars instead of 00000100 dollars. Visual Basic doesn't display unnecessary or redundant information. Also, the &H means that the integer is in hexadecimal format rather than decimal.
2-11
Functions
Functions, like subroutines, are sequences of commands that are run repeatedly, using different sets of data. Functions, however, return results to the part of the program that called the function. To stretch the calculator example a bit further, the addition line could be movedto a function call.
Function Addem(x As Double, y As Double) As Double Addem = x + y End Function
The function is then called from the Command1_Click() subroutine, in place of the line Sum = a + b.
Sum = Addem(a, b)
This passes the variables a and b to the function Addem (that calls them x and y) and assigns the results of the function to the variable Sum. Like arguments to subroutines, the type declarations for x, y, and the function return argument Addem are given in the function declaration statement.
ByVal
In Visual Basic you can pass arguments to a function by value or by reference. The difference is in the way Visual Basic treats changes to the arguments. When a variable that is passed to a function by reference is changed within the function, the change is permanent; it affects that variable even in other procedures called after that function ends. When a variable is passed by value, however, the function only sees a copy of that variable, and changes only affect the calling function. The original variable is unchanged, as far as other parts of the program are concerned. There are two ways you can avoid passing variables by reference and potentially wreaking havoc in your program by permanently changing the values of important variables: Never write functions. Use ByVal in your function declarations to specify that your arguments are by value only.
2-12
Functions
The first option is easy enough for simple programs, but practically impossible in large, complex applications. So its handy to know how to use ByVal when you start writing big functions. Suppose, in our calculator application, instead of simply adding the two numbers together, you want to find a+b and a-b, and display whichever result is greater. One way to do this is to write the Addem function as
Function Addem(x As Double, y As Double) As Double If y<0 then y=-y End If because if y<0, x+(-y) > x+y Addem = x + y End Function
Now, go back to the main subroutine (Command1_Click), and add a debug line after the function call.
Private Sub Command1_Click() a = Val(Text1.Text) b = Val(Text2.Text) Sum = Addem(a,b) Debug.Print b that prints the value of b to the Immediate window Label1.Caption = Sum End Sub
Running it with 1 and -2 for the input values gives 3 as a result and a 2 printed in the Immediate window. The function changed the value of y, which was the same as b; therefore anything written later in the program will have the altered value, not the original value. If later calculations depend on b having its original value, the results will be wrong. The way around this is to use ByVal in the function declaration.
Function Addem(ByVal x As Double, ByVal y As Double) As Double If y<0 then y=-y End If because if y<0, x+(-y) > x+y Addem = x + y
2-13
End Function
Now, running the Command1_Click subroutine above, gives the expected result 3 in the form, and the original value of b (-2) in the Immediate window. This time, the function changed y, but y was only a copy of b, not b itself. Future calculations that depend upon b having its original value will not suffer. Note also that Abs(y) is the absolute value function built into Visual Basic. Therefore, the lines
If y<0 then y=-y End If
2-14
Flow Control
Flow Control
Two additional constructs can affect the flow of a program. The first, branching, is accomplished by If or Select Case statements. One example was provided in the absolute value routine. If the value of y was less than zero, something was done that was not done if y was greater than zero. The second construct is the loop, which allows statements or procedures to be repeated numerous times.
If Blocks
If statements test a condition and, if the result is True, execute the subsequent statements. In the absolute value example, the condition was Is y less than zero?, or y<0. The statement to be executed in the event the result is true was y=-y. The If block ended with the End If statement. In the event that y was greater than zero, the condition returns False, and, because there are no instructions for what to do in that case, nothing is done. The program skips to the End If statement, and continues running.
If we had wanted to do something special to positive values of y, we could use the Else statement to specify what to do when the If condition is False:
If y < 0 then y = -y Else y = y + 2 End If
A somewhat more useful example might be a function to calculate the slope of the absolute value function for a given value x. If x<0, the slope is -1; if x>0, the slope is 1; if x=0, the slope is undefined:
Function Abs_Slope(x As Double) As Double If x<0 then Abs_Slope = -1 ElseIf x > 0 then Abs_Slope = 1 Else Abs_Slope = Null some languages would let us call this "Not-a-Number" End If
2-15
End Function
Because the results of condition checks are Boolean (True or False), they may be combined by means of Boolean operators And and Or, so that a single If may test multiple conditions at once. When conditions are combined with And, the result is True if all of the conditions are True; when combined with Or, the result is True if any of the conditions are True. Other Boolean operators also may be applied. Not toggles the value of a Boolean variable: Not True is False, Not False is True. In numeric terms (where True is 1 and False is 0), Not 1 = 0, Not 0 = 1. Xor looks at two variables, and returns True if one or the other, but not both, is True.
If blocks may also be nested within If blocks. Each nested block may have its own ElseIf or Else statements, and must have its own End If statement. For example If Score >= 60 then If Score >= 70 then If Score >= 80 then If Score >= 90 then Grade = "A" Else Grade = "B" End If Else Grade = "C" End If Else Grade = "D" End If Else Grade = "F" End If
Select Case
If a single variable or expression is to be tested against a number of possible values, only one of which (at most) will be true, the Select Case statement can be useful. For example, the series of If commands
If A = 0 then
2-16
Flow Control
b = sqrt(17)+sqrt(22) ElseIf A = 1 then b = 17 ElseIf A = 2 then b = sqrt(17) ElseIf A = 3 then b = sqrt(22) Else b = 22 End If
Only the option that matches will be executed. If there is no matching option, the Case Else option runs. If there is no match, and no Case Else option, nothing will be done.
Loops
Loops are handy when you need to repeat the same procedure numerous times, for instance, when you have a list of 17,132 names to print out. Even with the names all formatted in string variables or variants, and the print commands written up in a subroutine, you would not want to enter each name separately up to 17,132 times. To avoid this, put the names all in one array, and write the print commands in a loop.
For ii = 1 to 17132 Print Name(ii) Next
2-17
If all nested loops end at the same time, as above, the Next statements may be combined.
For ii = 1 to 4 For jj = 1 to 8 C(ii,jj) = ii/jj Next jj, ii
Do While
Sometimes, you dont know how many times you want to run a loop, but you do know you want to run it as many times as it takes to make something happen. In these cases, you want to write a Do While loop, rather than a For loop. A Do While example will calculate your machines Epsilon, or the smallest distinguishable double-precision value.
Dim eps As Double Do While eps > 0 eps = eps / 2 debug.print eps Loop
2-18
Flow Control
Loops such as this are bad because they run forever. A correctly written loop is:
Dim C(1 to 5) ii = 1 Do While ii < C(ii) = 1 ii = ii + Loop As Double 5 / ii 1
The next loop is a bit different. It has a condition that will never be true and will therefore never be executed.
Do While 1 < 0 whatever code you dont ever want to run Loop
Loops like this are occasionally useful, if you have a large block of code that you dont want to run, for some reason. The effect is similar to commenting out the code within the Do While loop, but will be easier to uncomment when you want to put it back: delete two lines, rather than delete the from the beginning of a group of lines. The sense of a Do While loop may be reversed by using the Do Until statement. In this case, the loop code is executed as long as the condition is False; as soon as the condition becomes True, the loop ends. For example, the above loop for filling the array C may also be written
Dim C(1 to 5) ii = 1 Do Until ii > C(ii) = 1 ii = ii + Loop As Double 5 / ii 1
2-19
2-20
3
Matrices
What are Matrices? . . . . . . . . . . . . . . . . . 3-2 Creating Matrices . . . . . . . . . . . . . . . . . 3-3 Created by Matrix Operation . . . . . . . . . . . . . . 3-3 Created by a Function . . . . . . . . . . . . . . . . 3-4 Accessing Matrix Elements . . . . . Indexing by Parentheses . . . . . . . Indexing by rN and iN Functions . . . . Converting Matrices to Visual Basic Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-6 3-6 3-6 3-7
Matrix Properties and Methods . . . . . . . . . . . 3-8 Rows and Cols . . . . . . . . . . . . . . . . . . . . 3-8 Dimensions . . . . . . . . . . . . . . . . . . . . . 3-8 Saving and Loading Matrices . . . . . . . . . . . . 3-9 vbsave and vbload . . . . . . . . . . . . . . . . . . 3-9 Other File I/O Routines . . . . . . . . . . . . . . . . 3-9
Matrices
3-2
Creating Matrices
Creating Matrices
MatrixVB matrices are created the same way as normal Visual Basic arrays, by including dimensions in the declaration statement. For example, the line
Dim A(1 to 2, 1 to 3) As Double
creates a 2-by-3 array A. Later in the program, the array might be filled and operated on as a result of a button click. When the code reaches a point where the array needs to be treated as a matrix, MatrixVB converts it automatically.
While A is an array, B, the result of a matrix operation, is a matrix. The show command opens the matrix viewer and displays the contents of the matrix.
3-3
Matrices
Note Although Visual Basic arrays begin counting at element 0 (if the range is not otherwise specified), MatrixVB arrays always begin counting at element 1.
Created by a Function
Many MatrixVB functions create matrices implicitly; such functions generally return these matrices as output arguments. There is no need to declare or dimension these matrices before calling the functions (though explicit Dim statements can make the code easier to debug). For example, the command
A=zeros(3,6)
When a MatrixVB function returns multiple matrix arguments, Visual Basic stores them all in a single variant. The elements of the variant are the output arguments of the function. For example, to find the eigenvalues and eigenvectors of a 5-by-5 magic square, enter the command
Eigs=eig(magic(5))
3-4
Creating Matrices
In our example the two-element variant Eigs contains the eigenvalues and eigenvectors. The first element is the matrix of eigenvectors; the second element is the matrix of eigenvalues. The show command displays the values.
Eigenvectors=Eigs(1) Eigenvectors.show Eigenvalues=Eigs(2) Eigenvalues.show
(For another example, see how the meshgrid command is used in Example: Fractals on page 1-4.)
3-5
Matrices
Indexing by Parentheses
For example, the matrix A is created and filled by
A=zeros(1,3) A(1)=4 A(2)=-5 A(3)=mcomplex(0,1)
In this case, the simple function must be used to read the contents of the variables.
?B.simple ?C.simple
3-6
The rN and iN properties are read/write; they can be used to set as well as retrieve matrix elements.
N must be 1, 2, or 3, reflecting the number of indices into the matrix.
X.r1(n) returns the double scalar at element n (linear equivalent index if X is a multi-dimensional array). X.r2(i,j) returns the double scalar at position (i,j) if X is two-dimensional. X.r3(i,j,k) returns the double scalar at position (i,j,k) if X is three-dimensional. These index functions return an error message if the requested indices are not within the specified array limits. The same access functions that are used to read individual matrix elements may also be used to set them. Here is some code that changes some elements of the 3-by-3 magic square.
X=magic(3) x=[ 8 1 6; 3 5 7; 4 9 2] a=x.r1(1) a = 8 b=x.r1(2) b = 3, the second element of X (counting down the columns, then left to right) c=x.r2(2,3) c = 7, the third element of the second row x.r2(3,1)=-999 sets the first element of the third row to -999: x = [8 1 6; 3 5 7; -999 9 2] x.r1(4)=-x.r1(4) sets the 4th element, x(1,2) to the opposite of its original value, or -1: x = [8 -1 6; 3 5 7; -999 9 2]
3-7
Matrices
Dimensions
x.dims returns the number of matrix dimensions (matrices may have up to four dimensions in MatrixVB). x.dimension(n) returns the size of the nth dimension. x=randM(7,5,4,6) ?x.dims 4 ?x.dimension(2) 5 ?x.dimension(4) 6
3-8
3-9
Matrices
(Different formats may be specified by changing the "%g\n" to a different C format string.) Unlike the vbsave function, this approach does not append an extension to the filename. If an extension is desired, it must be specified as a part of the filename in the fopen command.
3-10
4
Operators
Visual Basic Operators and MatrixVB Equivalents Arithmetic Operators . . . . . . . . . . . . . . . Comparison Operators . . . . . . . . . . . . . . Concatenation Operator . . . . . . . . . . . . . . Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2 4-2 4-3 4-4 4-5
Operators
Arithmetic Operators
Visual Basic a ^ b a * b a / b a \ b a Mod b a + b a - b -a MatrixVB power(a,b) times(a,b) rdivide(a,b) ldivide(a,b) mmod(a,b) plus(a,b) minus(a,b) uminus(a)
Standard rules of matrix operations apply to the arithmetic operators: a and b must have compatible dimensions. If one of the operands is a scalar, the operation is carried out between each element of the matrix and the scalar. For example, to add 3 to each element of a 3-by-3 magic square, try
c=plus(magic(3),3)
4-2
Comparison Operators
Visual Basic a < b a <= b a > b a >= b a = b a <> b MatrixVB lt(a,b) le(a,b) gt(a,b) ge(a,b) eq(a,b) ne(a,b)
The comparison operators require two matrices of equal dimensions, or one matrix and a scalar. The comparison is then made for each pair of corresponding elements, or between the elements of the matrix and the scalar. The result is a matrix of the same size as the matrices being compared, whose elements are either 1 (where the comparison returned a True value) or 0 (where the comparison returned False). For example, the following finds which elements of the 5-by-5 magic square are greater than or equal to 12.
c=ge(magic(5),12) c.show
4-3
Operators
Concatenation Operators
Visual Basic a & b MatrixVB strcat(a,b) horzcat(a,b) vertcat(a,b) strcat concatenates string variables. Matrices may also be concatenated by horzcat (horizontal concatenation) or vertcat (vertical concatenation). For
horizontal concatenation, both matrices must have the same number of rows; for vertical concatenation, both matrices must have the same number of columns. (horzcat and vertcat also work on string matrices.)
a=eye(3) b=ge(magic(3),5) c=horzcat(a,b) c.show d=vertcat(a,b) d.show
4-4
Logical Operators
Visual Basic a And b a Eqv b a Imp b not a a Or b a Xor b MatrixVB mand(a,b) mnot(mxor(a,b)) mor(mnot(a),b) mnot(a) mor(a,b) mxor(a,b)
Like the comparison operators, the logical operators require either two matrices of equal dimensions, or one matrix and one scalar. (mnot takes only one argument; this may be either a matrix or a scalar.). The logical operators return a matrix of the same size as the input matrix (or matrices), composed of ones (when the operation returns True) and zeros (when the operation returns False). The following code returns the logical And of the 3-by-3 identity matrix with the result of a comparison.
a=eye(3) b=ge(magic(3),5) c=mand(a,b) c.show
4-5
Operators
4-6
5
Graphics
Using MatrixVB Graphics . . Creating plots . . . . . . . . Plotting to a Visual Basic Window Figure Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-2 5-2 5-4 5-5
Graphics
Creating Plots
By default, a new figure window is opened for plot output. For example, the command
contour(hadamard(32))
5-2
Blank figure windows may be created by the figure command. figure requires one input argument, the number of the figure to create. Subsequent graphical output will be placed in this window. If multiple figure windows are open, plots will be placed in the current figure window. The gcf command may be used to determine which figure is current. The current figure window may be changed by calling figure with the number of an existing window. The following lines illustrate these commands.
figure(1) plot(randn(1000,1)) figure(2) plot(inv(hilb(12))) figure(10) contour(hadamard(128)) figure(2)
5-3
Graphics
Any graph placed in a Visual Basic window this way fills the entire window. To position the graph inside the window, place a PictureBox object on the form and call vbaxes using its window handle, rather than the forms window handle.
ax = vbaxes(Picture1.hWnd)
An example of a plot in a PictureBox is provided by the following code (assuming that a PictureBox has already been placed on Form1).
Private Sub Form_Load() ax = vbaxes(Picture1.hWnd) plot(rand(1024,3)) End Sub
5-4
Figure Menus
Figures that appear in their own windows have, by default, a menubar with File, Edit, Control, Windows, and About options. Part or all of this menu may be turned off by the mset command.
turn off the About menu:mset gcf,"MenuAbout","Off" or turn off the whole menu: mset gcf,"Menu","Off"
Some of the more useful items in this menubar are described below.
File
The File menu contains commands that allows you to print your figure or save it to a file. Allowable formats for saved figures are M-file, GIF, JPG, BMP, TIF, and PNG.
Control
The Control menu contains options that let you customize many aspects of the figure. Some of the more useful items under this menu are: Edit Plot opens a window that lets you directly edit attributes of the whole plot (the Chart options) or of the individual vectors of data plotted (the Series options). Control Bar toggles a panel of buttons across the bottom of the figure window. The buttons let you use the mouse to zoom in on areas of the figure, rotate the axes object (especially useful for three-dimensional graphs), or move the axes object in the Figure window. Mouse Zoom determines whether the mouse can be used to change the scale of the figure. If this is on, the left mouse button may be used to draw a rubberband box around a portion of the plot; when the button is released, the axes limits change to the edges of the box. White/Gray/Black Background changes the figure background to the specified color. Remove Menu hides the figures menubar (as above). Design Figure opens a Pallete of UI controls you can add to the figure. To close the Pallete and exit the Figure Designer, choose Finish Design from the Control menu.
5-5
Graphics
5-6
6
Additional Examples
Enhanced Calculator . . . . . . . . . . . . . . . . 6-2 Matrix Determinant . . . . . . . . . . . . . . . . 6-6
Fast Fourier Transform . . . . . . . . . . . . . . . 6-6 Solving Linear Systems . . . . . . . . . . . . . . . 6-7 Eigenvalues . . . . . . . . . . . . . . . . . . . . 6-8 Complex Matrix: Polynomial Roots . . . . . . . . . 6-8
Additional Examples
Enhanced Calculator
Here you can examine a more functional calculator than the one shown earlier. We additionally provide some insight into our thinking as we designed the MatrixVB program for this application. The form that goes along with the calculator program is:
The calculator contains code for addition, subtraction, multiplication, division (left and right - A divided by B and A divided into B), exponentiation, logarithm, ceil(A), floor(A), round (A) to the nearest integer, remainder (mod(A,B)), and the four logical operators AND, OR, XOR, and NOT. Each of the fifteen operators is calculated in its own subroutine; there is a SetDisplay subroutine that places the result of the calculation in the = block, a Form_Load subroutine that initializes the input arguments A and B to 1 and 2, respectively, and two Input_Change subroutines that make the values of A and B reflect the numbers shown in the Text windows. The complete program (assuming you have the form) is:
6-2
Enhanced Calculator
Public A As Double Public B As Double Public Result As Variant Private Sub Form_Load() A = Val(Input1.Text) B = Val(Input2.Text) End Sub Private Sub SetDisplay(Answer As Variant) LCD.Caption = Answer End Sub Private Sub Input1_Change() A = Val(Input1.Text) End Sub Private Sub Input2_Change() B = Val(Input2.Text) End Sub Private Sub Adder_Click() Result = A + B SetDisplay Result End Sub Private Sub Diminisher_Click() Result = A - B SetDisplay Result End Sub Private Sub Multiplier_Click() Result = A * B SetDisplay Result End Sub Private Sub DivideBy_Click() Result = A / B SetDisplay Result End Sub Private Sub DivideInto_Click() Result = ldivide(A, B) SetDisplay Result.Simple End Sub Private Sub Exponent_Click() Result = power(A, B) SetDisplay Result.Simple End Sub
6-3
Additional Examples
Private Sub logb_A_Click() log A base b Result = Log(A) / Log(B) SetDisplay Result End Sub Private Sub Ceiling_Click() Result = ceil(A) B = 0 Input2.Text = B SetDisplay Result.Simple End Sub Private Sub Floored_Click() Result = floor(A) B = 0 Input2.Text = B SetDisplay Result.Simple End Sub Private Sub RoundTable_Click() Result = Round(A) B = 0 Input2.Text = B SetDisplay Result End Sub Private Sub ANDer_Click() Result = mand(A, B) SetDisplay Result.Simple End Sub Private Sub ORer_Click() Result = mor(A, B) SetDisplay Result.Simple End Sub Private Sub XORn_Click() Result = mxor(A, B) SetDisplay Result.Simple End Sub Private Sub NOTty_Click() Result = mnot(A) B = 0 Input2.Text = B SetDisplay Result.Simple
6-4
Enhanced Calculator
End Sub Private Sub MODerate_Click() remainder of A/B Result = mmod(A, B) SetDisplay Result.Simple Result = A Mod B SetDisplay Result End Sub
A few issues arose as we wrote this program. We made A, B and Result into Public variables because its conceivable that you might want to use A, B, and Result in other programs you write. Also, it demonstrates the syntax of the Public (and Private) declarations. Result needs to be a variant because sometimes it is a matrix object and sometimes it is a double. We could have use two Result variables, e.g., Result_d for double calculations and Result_m calculations, but a variant seems more suitable. To display the matrix results, however, we needed to say SetDisplay Result.simple rather than simply SetDisplay Result when Result is a matrix. We made SetDisplay a subroutine because it is generally good to make subroutines or functions out of bits of code that get used often. In this instance, there wasnt much gained by typing SetDisplay Result at the end of every routine, rather than LCD.Caption = Result, but if the display routine had been more complex, it would have been more useful. Also, we might have included a Zero_B subroutine as well, for the line of code that sets B=0 for the operations that only need one argument. When you use subroutines and functions, do not leave their names as Command1_Click, Input1_Change, etc. Give them more descriptive names so that you will remember what the procedure is supposed to do. Make sure, though, that your names dont duplicate the names of built-in Visual Basic or MatrixVB functions. Also, when working with graphical interfaces, try not to accidentally use the name of a function as the name of, say, a pushbutton. In cases like that, neither Visual Basic nor MatrixVB quite knows what to do and will generate an error message. (We lost a few minutes sleep wondering why the ^ button wasn't working, before we realized that we called it Power, which is the name of the function we wanted to use it for.)
6-5
Additional Examples
Some of the functions incorporated into the calculator could be written using either Visual Basic or MatrixVB commands. mod, for instance, could either be Result = mmod(A,B), or Result = A Mod B. Similarly, the DivideInto routine could be either Result = ldivide(A,B) or Result = B/A. There often are several ways to solve a problem, with no real reason to favor one over the other unless a significant speed or performance difference exists.
Matrix Determinant
To find the matrix determinant, first find its entry in the Reference Guide.
y=det(x)
As expected, the function accepts one input and returns one output. Therefore, example code for det would be:
a=magic(3) b=det(a) ?b.simple -360
The fft function returns an array whose size is same as the input size. As an example, suppose the function input is an equi-logarithmic sequence from 1 to 10:
x=logspace(0,1,8) y=fft(x) y.show
6-6
6-7
Additional Examples
Eigenvalues
For the same 3-by-3 square matrix of the linear system solution (above), the eigenvectors are found to be 12.434, -6.434, and 1 using the following code:
vd=eig(a) v=vd(1) d=vd(2) v.show
The eigenvectors are obtained in the first output variable, v and the eigenvalues in the second output variable, d.
6-8
Polynomial Fit
Polynomial Fit
Suppose a polynomial fit of the third degree is required for experimental data.
x=linspace(10,100,10) y=vbload("c:\matrixVB\samples\y.dat") p=polyfit(x,y,3)
If the file y.dat (which can be found in the \samples subdirectory of the MartixVB installation directory) contains the data:
-26.99 -50 -60.94 -53.94 -22.79 38.18 135.3 274.3 461.2 702.2
The result of the fit will be p = 0.001 0.00028 -3.007 2.045 To test the fit, evaluate it and plot it along with the experimental data.
yfit=polyval(p,x) Call plot(x,y,"*",x,yfit)
6-9
Additional Examples
Filtering
The library supplies a FIR filter function, called filter. It accepts two vectors of coefficients and a vector of data.
Filter coefficients a=CreateMatrix(-10,-3.9633,6.7) b=CreateMatrix(0.03,-1.5,0.04) Number of random points N=16 random gaussian vector x=randn(N,1) Filter it y=vbfilter(b,a,x)
Random Values
Both uniform and gaussian random number generators are supplied with the library. The random number generators can supply a whole matrix or a single value.
create 20-by-30 uniformly-distributed matrix uniform=randM(20,30) create 5-by-1 normal-distributed matrix normal=randn(5,1) single gaussian variable
6-10
LU Factorization
The lu function of a square matrix x, returns three outputs, l, u, and p such that px=lu. p is the permutation matrix, l is the lower triangular, and u is the upper triangular.
x=randn(3) lup=lu(x) l=lup(1) u=lup(2) p=lup(3) d=norm(minus(mtimes(p,x),mtimes(l,u))) ?d.simple 7.85046229341888E-17
6-11
Additional Examples
Singular Values
svd computes the singular value decomposition of a matrix x. It returns u, s, and v, where u and v are unitary matrices and s contains the singular values on the diagonal. x=randn(3) usv=svd(x) u=usv(1) s=usv(2) v=usv(3) u.show s.show v.show
Linear Programming
MatrixVB supplies linear and quadratic solvers. The linear problem, stated as minimization of cx subject to ax<=b, is solved by the lp function. From the Reference Guide, note that lp accepts three inputs: c, a, and b followed by optional bounds for x. For example, given three non-negative variables, x,y and z, minimize -x+3y-2z subject to 1 20 x 3 3 04 y 7 0 56 z 2 Therefore, 1 20 3 1 a = 3 0 4 ,b = 7 ,c = 3 0 56 2 2 The code finds the optimal vector x=[17/9 0 1/3].
c=zeros(3,1) c(1)=-1 c(2)=3 c(3)=-2
6-12
Linear Programming
6-13
Additional Examples
6-14
A
Distributing Compiled Applications
The following files must be distributed along with your MatrixVB application.
v4510v.dll c4510v.dll ago4510.dll msvcrt.dll, msvcirt.dll (Visual C++ runtime files) MMatrix.dll
Do not install these files on any other operating system, such as Windows 98, ME, NT4, or 2000.
A-2
Index
A
ActiveX 1-2, 1-3 arithmetic operators 4-2 arrays 2-6 object 2-6 single 2-5 string 2-5 variant 2-6 date data type 2-6 declaration statements 2-5
B
Boolean data type 2-5 branching 2-15 byte data type 2-5
E
eig command 3-4 eig function 6-8 erf(x) 1-3
C
calculator enhanced 6-2 simple 2-3 comparison operators 4-3 compiled applications, distributing A-2 concatenation operators 4-4 constants 2-6 contour function 5-2 converting matrices 3-7 counting 3-4 creating matrices 3-2, 3-3 creating plots 5-2 currency data type 2-5
F
fast fourier transform 6-6 fft function 6-6 figure command 5-3 figure menus 5-5 file I/O 3-9 filter 6-10 flow control 2-15 fopen command 3-9 functions 2-12
D
data files 3-9 data types 2-5 Boolean 2-5 byte 2-5 currency 2-5 date 2-6 integer 2-5 long 2-5
G
gcf command 5-3 graphic objects, adding 1-5
H
hadamard function 5-2, 5-3
I-1
Index
I
Immediate window 1-3 indexing 3-6 integer data type 2-5
operators 4-2 arithmetic 4-2 comparison 4-3 concatenation 4-4 logical 4-5 overloading 4-2
L
logical operators 4-5 long data type 2-5 loop 2-15 lp function 6-12 lu factorization 6-11 lu function 6-11
P
plots, creating 5-2 plotting 5-4 polynomial fit 6-9 roots 6-9 polynomial fit 6-9 polynomial roots 6-9 primes 6-11
M
magic command 3-4, 4-2
magic square 3-4, 3-7 matrices 3-2 accessing 3-6 converting 3-7 creating 3-2, 3-3 saving and loading 3-9 matrix determinant 6-6 matrix properties 3-8 matrix viewer 1-3, 3-3 MatrixVB applications, distributing A-2 mldivide function 6-7 mset command 5-5
R
randn function 5-3, 6-10, 6-12
S
simple function 3-7
N
null matrix 3-4
single data type 2-5 singular value decomposition 6-12 solvers 6-12 string data type 2-5 subroutine, adding 1-4 subroutines 2-9
O
object data type 2-6
V
val command 1-8 variables 2-3
I-2
Index
variant data type 2-6 variants 2-5 vbaxes command 1-4, 5-4 vbload command 3-9, 6-9 vbrefresh command 1-4 vbsave command 3-9 Visual Basic data types 2-5 flow control 2-15 functions 2-12 subroutines 2-9 variables 2-3
I-3