精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● VB和Basic>>● VB和Basic(1)>>文章连载>>VB邮件>>VB邮件(6.25)

主题:VB邮件(6.25)
发信人: aaaaaaaaa()
整理人: cobe(2000-02-13 00:09:53), 站内信件
                      编者的话
====================================================================
大家好!
    欢迎大家回答问题和提出问题,同时也欢迎大家
提供有关VB和VBA和ASP的好作品。
                                版主   冯德平
                                [email protected]
=============================================
            VB邮件(6.25)
a Visual Basic技巧集-数值计算  

一个 n×n 的矩阵 A,若存在一个 n×n 的矩阵 A-1,使得 AA-1=A-1A=单位矩阵
,则称 A-1 为 A 的逆矩阵,A 称为非奇异的(nonsingular),逆矩阵具有唯一性
。一个不具逆矩阵的矩阵称为奇异的(singular)。要求出一个矩阵的逆矩阵有许
多方法,这里介绍以 Gauss-Jordan Elimination 来求出逆矩阵的方法,其他还
有一些执行效率比较好的方法(例如:Exchange method),以後有机會再介绍。?
 

副程式: 

Public Sub MatrixInversion(m() As Single, ReturnValue() As Single)
     Dim i As Long, j As Long, k As Long, row As Long, Pivot As Single

     row = UBound(m, 1)
     ReDim ReturnValue(1 To row, 1 To row)
     For i = 1 To row
          ReturnValue(i, i) = 1
     Next
     For i = 1 To row
          Pivot = m(i, i)
          If Pivot <> 1 Then
               For k = 1 To row
                    m(i, k) = m(i, k) / Pivot
                    ReturnValue(i, k) = ReturnValue(i, k) / Pivot
               Next
          End If
          For j = 1 To row
               Pivot = m(j, i)
               If i <> j And Pivot <> 0 Then
                    For k = 1 To row
                         m(j, k) = m(j, k) - m(i, k) * Pivot
                         ReturnValue(j, k) = ReturnValue(j, k) - Retur
nValue(i, k) * Pivot
                    Next
               End If
          Next
     Next
End Sub
上述的 MatrixInversion 副程式至少还有三个问题存在,但是对於解决一般的矩
阵求逆问题,仍然可以适用。 
  
在副程式中并没有判断矩阵 m 是否为 n×n (方阵)。 
没有使用 Pivoting strategy,因此无法处理主对角线元素可能为零,以及舍入
误差(roundoff error)很严重的问题。 
如果 m 为一奇异矩阵,程式将會发生溢位的问题。 
参数说明: 
  
m:欲求逆矩阵之矩阵。 
ReturnValue:传回计算後之逆矩阵。 
范例: 
1.由键盘输入矩阵元素: 

Private Sub Command1_Click()
     Dim Keyin As String, m() As Single, x() As Single
     Keyin = InputBox("请输入方阵,以分号"";""来分隔列元素,以空白来分
隔栏元素。" _
               & vbNewLine & "例如有一3×3的方阵:" & vbNewLine & "1 2 
3 " & vbNewLine & _
               "4 5 6 " & vbNewLine & "7 8 9 " & vbNewLine & "则输入: 
1 2 3;4 5 6;7 8 9 ")
     If SepStrToMatrix(Keyin, ";", " ", m) Then
          Call MatrixInversion(m, x)
          Call PrintMatrix(x)
     Else
          MsgBox "方阵输入有误,请重新输入。"
     End If
End Sub
其中 SepStrToMatrix 和 PrintMatrix这两个副程式,请参阅本站的 将字串拆解
成阵列。 
若有一矩阵如下: 

       1       3       0       1
       2       2       1       3
       3       4       5       6
       0       7       3       1
执行 Command1 之後,在 VB5 的即时运算视窗可得此矩阵之逆矩阵。 
7.125 -7.75  3.125 -2.625 
-0.25  0.5 -0.25  0.25 
 2.375 -3.25  1.375 -0.8750001 
-5.375  6.25 -2.375  1.875
2.由档案读入矩阵元素: 
Private Sub Command2_Click()
     Dim FileNo As Long, Keyin As String, temp As String, m() As Singl
e, x() As Single
     FileNo = FreeFile
     Open "c:\mi.txt" For Input As #FileNo
     Do While Not EOF(FileNo)
          Line Input #FileNo, temp
          If Trim(temp) <> "" Then Keyin = Keyin & temp & ";"
     Loop
     Close #FileNo
     Keyin = Mid(Keyin, 1, Len(Keyin) - 1)
     If SepStrToMatrix(Keyin, ";", " ", m) Then
          Call MatrixInversion(m, x)
          Call PrintMatrix(x)
     Else
&nM PrintMatrix这两个副程式,请参阅本站的 将字串拆解成阵列。
若有一矩阵储存在"C:\mi.txt" 
       1       2      -1      
       2       1       0  
      -1       1       2
执行 Command2 之後,在 VB5 的即时运算视窗可得此矩阵之逆矩阵。 
-0.2222222  0.5555556 -0.1111111 
 0.4444444 -0.1111111  0.2222222 
-0.3333333  0.3333333  0.3333333
MatrixInversion 副程式中的 " If Pivot <> 1 Then ",是为了略去除数为 1 
的除法运算,还有 " If i<>j And Pivot <> 0 Then ",是为了略去乘数为 0 的
乘法运算,最终目的都是为了提升执行速度。 
如果是奇异矩阵求逆之问题,使用 MatrixInversion 副程式将會出现溢位之问题
,或是算出数值很大之逆矩阵,但是这个逆矩阵是错误的结果,你可以将原矩阵
和算出之逆矩阵相乘,看看是否为单位矩阵,以确保计算结果之正确性,这点要
非常注意。 

另外,AX=B 之线性方程组也可以用逆矩阵的方式解出 X,X=A-1B,但是并不建议
使用这种方式做,因为逆矩阵的计算效率比较差。 

 
Least-Squares curve fitting by using an arbitrary order polynomial as 
approximating function. 

最小平方近似法 (least-squares approximation) 是用来求出一组离散 (discr
ete) 数據点的近似函数 (approximating function),作实验所得的数據亦常使
用最小平方近似法来达成曲线密合 (curve fitting)。以下所介绍的最小平方近
似法是使用多项式作为近似函数,除了多项式之外,指数、对数方程式亦可作为
近似函数。关於最小平方近似法的计算原理,请参阅市面上的数值分析书籍。 


  

副程式: 
  
  

Public Sub LeastSquare(d As Long, x() As Single, f() As Single, Return
Coeff() As Single) 
     Dim i As Long, j As Long, no As Long, m() As Single 
     Dim row As Long, col As Long, n() As Single 
     row = d + 1 
     col = d + 2 
     no = UBound(x) 
     ReDim m(1 To row, 1 To col), n(0 To 2 * d) 
     For i = 0 To 2 * d 
          For j = 1 To no 
               n(i) = n(i) + x(j) ^ i 
          Next 
     Next 
     For i = 1 To row 
          For j = 1 To row 
               m(i, j) = n(i + j - 2) 
          Next 
     Next 
     For i = 1 To row 
          For j = 1 To no 
               m(i, col) = m(i, col) + x(j) ^ (i - 1) * f(j) 
          Next 
     Next 
     Call GEMP(m, ReturnCoeff) 
End Sub 
  
  
  

其中 GEMP 这个副程式,请参阅本站的 Solve a set of simultaneous linear 
equations by Gauss Elimination with maximization of pivot elements.。 


  

参数说明: 

昫:欲 Fit 多项式的羃次(degree)。 晉():自变数之值,阵列基底为 1。 昮(
):应变数之值,阵列基底为 1。 昍eturnCoeff():传回多项式之系数,阵列基
底为 1。例如:ReturnCoeff(1)代表常数项之系数,ReturnCoeff(2)代表 1 次方
之系数,依此类推。 
  
  

  

范例: 

试利用最小平方近似法,求出以下数據之 2 阶多项式近似函数。 
  
  

x1.42.53.13.95.07.19.511.914.115.016.517.2f(x)3.82.64.15.26.26.97.26.7
5.83.83.82.8 
  

Private Sub Command1_Click() 
     Dim i As Long, keyin As String, A() As Single, f() As Single, x()
 As Single, d As Long 
     keyin = InputBox("请输入自变数x值,以空白来区隔。" & vbNewLine & 
"例如:1 2 3", "x值") 
     If Not SepStrToNumArray(keyin, " ", 1, x) Then GoTo WrongValue 
     keyin = InputBox("请输入应变数f(x)值,以空白来区隔。Fit 多项式的羃
次(degree)", "多项式的羃次") 
     d = CLng(keyin) 
     Call LeastSquare(d, x, f, A) 
     For i = 1 To d + 1 
          Debug.Print A(i) 
     Next 
     Exit Sub 
WrongValue: 
     MsgBox "输入了无效的数值", vbExclamation, "警告" 
End Sub 
  
  
  

其中 SepStrToNumArray 这个副程式,请参阅本站的将字串拆解成阵列。 

执行以上的程式将可在VB的即时运算视窗显示以下结果: 
  
  

1.130045 
 1.284787 
-6.935126E-02 
  
  
  

由此可知 2 阶多项式为:1.130045 + 1.284787x - 0.06935126x2 

上面的题目用 1、3 阶多项式也可做,甚至用 10 阶多项式也可求出答案,但是
要如何知道以几阶多项式所求的答案才是和原来的数據点误差最小呢?有一个很
笨的方法就是把原来的数據点与求出的近似函数画在同一张图形上来比较,这部
分可以用 Graph Control 或 Chart Control 办到,但毕竟肉眼分辨能力有限,
其实我们可以用简单的统计分析来判断该用几阶多项式以使得误差最小,这部分
将在下次介绍。 

LeastSquare 副程式并没有错误捕捉,例如: d 小於 0 的情况,或是 x 和 f 
的阵列数目小於 2 或不相等,都會造成执行错误,这部分的错误捕捉程式码就留
给网友们自行撰写了。 
                    OnecesLi 推荐

b Visual Basic使用技巧
 
1防止程序被重复运行 如果你不希望你的VB应用程序被别人通过多次双击图标
而重复运行,导致内存不足或其它意外,你可以在程序中增加以下几行:

Private Sub Form_ Load

if appprevinstance then

msgbox ″程序正在运行,请检查窗口是否被最小化。″

end if

End Sub

2用UCase函数保障文件操作的正确性 在WIN32平台下,文件名一般为小写字母
,但在WIN95平台,有时会出现大写。为保障在WIN32平台下用VB3开发的涉及到文
件操作的程序在WIN95平台也能正常工作,可以用UCase函数转换文件名的大小写
。例如:在WIN32平台下用VB3开发一个媒体浏览器,可以用以下程序段实现自动
播放,而不论文件的后缀名为大写的“ AVI”、“WAV”、“MID”,还是小写的
“ avi”、“wav”、“mid”,还是大小写混合:

Sub File1_Click()

MMcontrol1filename=File1Path&″\″&File1filename

t=UCase(Right(File1filename,3))

If t=″AVI″ Or t=″WAV″ Or t=″MID″ The n

MMcontrol1Command=″close″

MMcontrol1Command=″play″

End if

End Sub
        
3在VB5中汉字的长度为1而不是2 在VB3中每个汉字的长度为2,而在VB4和VB5
中每个汉字的长度为1。在截取汉字字符串的子串时需特别引起注意,这种变化对
设计汉字的排序、检索、筛选程序带来了较大的方便。另外,在 VB5中汉字的AS
CII码小于0,而在VB3或C++里,汉字的 ASCII码均大于零。
              刘一  推荐 

c Visual Studio 6.0,NT的奏鸣曲
 
 
 
Visual Basic一直是工作效率最高的Windows开发工具,其6.0版继承了这一传统
。该产品具有直观的开发环境,而且随时提供弹出式信息以及自动编码帮助功能
,继续为其他快速应用程序开发工具树立了高标准。 

Visual Basic 6.0长期关注那些喜欢该工具的方便性而又不局限于仅仅在Window
s客户机上进行部署的开发人员。你可以很容易地选择和使用Visual Basic中的新
增工具,这些工具通过一个Web浏览器来将Dynamic HTML前端代码发布到你的用户
界面上。 
   
不同于容易被人识别的脚本和反编译的Java类,编译后的Visual Basic DLLs提供
了用户可接受的对专有编程逻辑的保护机制。 
   
不管开发人员是不是以Web作为应用程序的目标,他们都会涌向更新的Visual Ba
sic,因为它能够在多种体系结构上轻松设计和部署应用程序。其高效率、直观的
可视化数据环境设计器(Data Environment Designer)为用户提供了包括数据表关
系、表查询设计、自动生成的SQL代码以及生动的预览结果等等的联合视图。 
   
你能够利用多种数据源来创建可重用的数据集合,这些集合可被看成是集成的对
象,即使是当低级数据集合驻留于不同的机器并且使用不同的数据库服务器平台
时也是如此。 
   
Visual Basic 6.0中的数据管理工具同Inprise公司的Borland Delphi 4.0中的类
似功能并驾齐驱。这两种产品都能够通过有效地管理层次化结构数据关系来加快
网络事务的处理。它们还为从便携式机器上下载数据和断开数据连接提供了方便
。 
   
Delphi工具在某种程度上来说更易于用在应用程序的设计上,但是,你可能会更
欣赏由Microsoft公司的Visual Studio Analyzer所创建的性能优化功能。Visua
l Studio Analyzer可以跨越该套件中的组件工具和数据库连接工具进行工作。 

   
Visual Basic 5.0版本强调的是从原始编译器(native compiler)中获得的性能增
强。与此不同,Visual Basic 6.0具有精简的多层次设计功能。但是,该版本与
5.0版本相比,在性能上并未高出多少,在最坏的情况下(比如函数调用密集的T
ak)进行基准测试时,Visual Basic至少要比Visual C++慢七倍。 
   
Visual Basic因减少了应用程序的开发和配置时间(尽管该产品外观上的简单可
能会误导用户)而大放异彩。如果程序开发人员使用它的每一种可行的提高应用
程序运行速度的方法(比如,声明变量类型而不是采用通用的效率较低的缺省数
据类型),则Visual Basic代码很快会变得像Pascal系列编程语言那样既罗嗦又
复杂。 

但是,Visual Basic中某些实质性的性能提高是不能按算法标准通过基准测试来
衡量的。例如,Visual Basic能够更快地生成表单,这应该归功于它更完整地采
用了32位的APIs(应用程序接口)。开发人员还可以通过使用6.0版本的COM线程
以及稳定的类创建选项来明显地提高其应用程序的性能。 
   
在许多情况下,明显的性能提高(即提高对用户的响应速度)在努力避免给人留
下速度慢的印象方面要占90%以上。Visual Basic在精确和自由选择的口号下为开
发人员提供了一种新的机会,使得应用程序即使在后台正忙于运行的情况下也能
够在前台进行交互。 
          tynit 推荐
=============================================
              VB问答
问题部分:
回答部分:
=============================================
                其它
====================================================================
欢迎订阅VB免费邮件:
订阅地址  http://server.com/WebApps/mail-list-subscribe.cgi?id=16852  

====================================================================  

如果您觉得这个邮件列表好的话,请告诉您的朋友。  
====================================================================
欢迎投稿  [email protected]  
====================================================================  

网易上的主页地址:http://www4.netease.com/~aaaaaaaaa 
本网站主页镜像地址:goodvbhome.yeah.net 
====================================================================

--
欢迎访问主页:goodvbhonme.yeah.net
或:http://www4.netease.com/~aaaaaaaaa
http://personal.gz168.gnet.gd.cn/vbok/

※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.46.211]

[关闭][返回]