I have updated the Matrix Library to make it more useful. Mainly, I've removed the 2x2 limitations from calculating determinants and finding inverses. I also added several new functions:
isSize: Checks the size of a matrix by rows and columns
newMatrix: Creates a new matrix of the specified size
transpose: Transposes the given matrix (rows -> cols)
augment: Augments A with matrix B -> AB
multRow: Multiplies the given row by constant k, k != 0
multRowAdd: Multiplies the source row by constant k, k != 0
then adds that row to the dest row
swapRow: Swaps row i with row j
ref: Uses Gauss elimination to reduce to row-echelon
format
rref: Uses Gauss-Jordan elimination to reduce to
reduced-row-echelon format
swapCol: Swaps column i for column j
delCol: Deletes the specified column
delRow: Deletes the specified row
minor: Returns the row minor, Mij
The most important additions were the elementary row operations, multRow, swapRow and multRowAdd - these were used to implement the row-echelon reduction methods. det(), ref() and rref() are the most *interesting* additions, although, I think the algorithms are not very efficient.
Posted in Math and Python on January 31st
The ASCII style of the site is novel, although not very functional. Google is not correctly indexing the site - the googlebot does not understand that there are columns of text, and treats the menus as part of the paragraph. Furthermore, search results from VisualCore.com are showing up at the bottom of the list. Another and perhaps bigger problem, is that copying text off the site is painful. If it is multiple lines, you always get chunks of the menu mixed in with the code (or other content) you are trying to copy.
So I have been working on a new graphical style, hopefully the initial release will be by Sunday (tomorrow). The layout work is done, I just need to flesh out the page content. I am also adding the ability to post comments to everything, which will be nice.
After the initial release, I plan to employ a few of the various open source JavaScript libraries, to see how they perform and to get some experience with them. For now, I plan on using Prototype (of course), Scriptaculous, Moo.Fx, LightBox, and maybe ASP.NET AJAX - although, it is a little bulky, so I'm not sure about that yet.
Posted in Design on January 26th
Recently, I have been learning how to create mathematical models in code so I figured I would share a little. Models are used to show how some phenomenon in life behaves and are typically based on an equation that represents the thing to be modeled. So the trick is to find a way to solve those equations in code.
Euler's method (pronounced Oiler) is one way of doing this, and I will show a very simple example using the following differential equation:
dy/dx = 2x
When solved by integration, the actual solution is:
y = x ^ 2
So that is the value that we want to obtain from the program after it completes. The Euler method requires initial known values for a starting point and then determines the slope of the tangent line at that point in order to find the next *approximate* point on the curve. The initial x, y values can be arbitrary (x=1 and y=1 are used in the example), but it must be a solution to the system - using x=1, y=8 would be bad since x^2=8 is false.
Since this is an approximation, the the final result will always be off by some margin of error (for example, for xMax=2, y should equal 4, since 2 ^ 2 = 4, but when you run this code, you will see that it is off by a small amount). This error is a function of the step size, dx. Smaller step sizes are generally more accurate. In the example below, a step size of 0.01 is used, which results in an error of 0.25% and a step size of 0.005 results in an error of 0.103%.
In the code below, xMax is the ending x-value that will be approximated, dx is the step size, and x & y are the initial known values. The code was written to be run as a console application in VB.NET 2005.
Sub Main()
Dim x As Double = 1
Dim y As Double = 1
Dim xMax As Double = 2
Dim dx As Double = 0.01
Console.WriteLine("X , Y -- % Error")
Do While x < xMax
Euler(x, y, dx)
Console.WriteLine( _
"{0:f2} , {1:f2} -- Error: {2:f3}%", _
x, y, (1 - (y / x ^ 2)) * 100)
Loop
Console.Read()
End Sub
Sub Euler(ByRef x As Double, _
ByRef y As Double, _
ByVal dx As Double)
Dim slope As Double = 2 * x
Dim change As Double = slope * dx
y += change
x += dx
End Sub
Here is a sample run:
X , Y -- % Error
...
1.91 , 3.64 -- Error: 0.249%
1.92 , 3.68 -- Error: 0.250%
1.93 , 3.72 -- Error: 0.250%
1.94 , 3.75 -- Error: 0.250%
1.95 , 3.79 -- Error: 0.250%
1.96 , 3.83 -- Error: 0.250%
1.97 , 3.87 -- Error: 0.250%
1.98 , 3.91 -- Error: 0.250%
1.99 , 3.95 -- Error: 0.250%
2.00 , 3.99 -- Error: 0.250%
As you can see from the sample run, the output claims that:
x ^ 2 = y
2 ^ 2 = 3.99
illustrating the approximation error. However, models are not supposed to be exact, they are supposed to be a representation that exhibits behavior similar to the thing your are trying to analyze. Also, there are much better approximation methods (such as Runge-Kutta). You wouldn't want to really use this method to solve the equation in this example, this was just to establish how the concept works. As the complexity of the model grows, this method becomes much more attractive.
This basic framework can be used to model all sorts of neat stuff. Coming up, I will post an example model for a cooling liquid using this method in conjunction with Newton's law of cooling, and then gravity and falling objects.
You can read more about Euler's method here.
Posted in Math, VB.NET, Modeling and Algorithms on January 20th
I recently ran across an interesting question in a usenet post; How do you convert an arbitrary color to a known / system color?
After some thought, I reasoned: in order to find the nearest known color, you must get the difference for each known color based on your sampled color. You could do this by looping through each known color in the enumeration Drawing.KnownColor.
Next, you could compare the R, G, and B values (or H, S, V values if that is more appropriate) for the known to the sample. To get the distance, you could either do a simple sum of the absolute differences, or if you are a Man or Woman of science, you would use the RMS (Root Mean Square) value. Finally, you keep the value with the smallest difference and return it.
In my sample code below, I also created a structure for returning the Name, Color and the Distance - this is just a little sugar to help the medicine go down, not really necessary.
Private R As New Random
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim randColor As Color = _
Color.FromArgb(R.Next(0, 255), _
R.Next(0, 255), _
R.Next(0, 255))
Me.RandomColorBox.BackColor = randColor
Me.RandomColorLabel.Text = randColor.ToString
'// now match to nearest known color
Dim nearest As ColorName = FindNearestKnown(randColor)
Me.KnownColorLabel.Text = nearest.Name
Me.NearestColorBox.BackColor = nearest.Color
End Sub
Structure ColorName
Public Color As Color
Public Name As String
Public Distance As Integer
End Structure
Public Function FindNearestKnown(ByVal c As Color) _
As ColorName
Dim best As ColorName
best.Name = Nothing
For Each colorName As String In _
[Enum].GetNames(GetType(KnownColor))
Dim known As Color = Color.FromName(colorName)
Dim dist As Integer
dist = Math.Abs(CInt(c.R) - known.R) _
+ Math.Abs(CInt(c.G) - known.G) _
+ Math.Abs(CInt(c.B) - known.B)
If best.Name Is Nothing _
OrElse dist < best.Distance Then
best.Color = known
best.Name = colorName
best.Distance = dist
End If
Next
Return best
End Function
Posted in VB.NET and Windows on January 20th