Wednesday, May 14, 2008

matlab 从queue 类构建stack类的全过程

8.9.4 继承性及其应用
8.9.4.3 利用继承性创建子类的示例

【例 8.9.4 .3-1 】把例 8.9.2-1 构成的队列作为父类,利用继承性,创建 stack 堆栈子类。
(1)建立类目录 @stack ,并使它成为当前目录 (以下指令仅对 5.3 版适用)
mkdir('e:\mat53\work','@stack') % 在 e:\mat53\work 上建子目录 @stack
cd e:\mat53\work\@stack % 是子目录 @stack 成为当前目录

(2)编写堆栈类的构造函数 @stack\stack.m
[@stack\stack.m]
function ST=stack(v)
% 调用格式
% ST=stack 创建一个 " 空 " 堆栈对象 .
% ST=stack(v) 创建包含变量 v 的堆栈对象。
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
Q=queue;
s.value=[]; % value 域被赋“空阵”
s.name= '' ; % name 域不给任何字符
elseif isa(v, 'stack' ); % 输入宗量是同类对象情况
s=v; % 直接把输入量赋给 q
Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
else % 非同类输入宗量情况
s.value=v; % 在 value 域中放置输入对象 v 的内容
s.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(s.name) % 假如输入量无名
s.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end

Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
end
ST=class(s, 'stack' ,Q); % 产生继承父类对象 Q 性质的 ST 堆栈子类

【 * 例 8.9.4 .3-2 】本例目的之一是:检查上例构造函数设计的正确性。目的之二是:观察堆栈关于队列的显示,类别判断和为 “空”判断性质的继承。

(1)堆栈对象的创建,及由于继承性,而获得正确显示。
AA=' 继承性 ';
ST=stack(AA)
ST=
AA: 继承性

(2)类别检查
class(ST)
ans =
stack

(3)由于在此设计采用了继承性,所以“是堆栈,就一定是队列”。
isa(ST,'stack')
isa(ST,'queue')
ans =
1
ans =
1

(4)检查对 isempty.m 是被继承
isempty(ST)
ans =
0


【 * 例 8.9.4 .3-3 】本例通过堆栈类对象的“压入”和“弹出”操作,进一步观察继承性。

(1)把元素压入堆栈
BB=1:6;CC=sym('x^2+4*x');
comein(ST,BB,CC)
ST=
[ 1*3 stack ]

(2)显示堆栈中第三元素的内容
display(ST,3)
The content of ST(3)
is a 'sym' object
CC=
x^2+4*x

(3)从堆栈弹出元素
[Name1,Value1,ST_1]=goout(ST)
Name1 =
AA
Value1 =
继承性
ST_1=
[ 1*2 stack ]

matlab FIFO 队列 queue 类的全过程

8.9 面向对象编程
8.9.2 面向对象编程应用示例

【例 8.9.2 -1 】本例演示:创建“先进先出” FIFO 队列 queue 类的全过程。在本例中,读者应充分注意:构架域( Fields of a structure array )和定义在其上的方法函数( Method function )之间的关系。

(1)建立类目录 @queue
(2)选择构架数组为 queue 类的数据结构
(3)创建构造函数 queue.m
[@queue\queue.m]
function q=queue(v)
%@QUEUE\QUEUE queue class constructor function
% 调用格式
% q=queue 创建一个 " 空 " 队列对象 .
% q=queue(v) 创建包含变量 v 的队列对象。
superiorto( 'double' , 'sparse' , 'struct' , 'cell' , 'char' , 'inline' , 'sym' );
% 使 queue 对象具有最高优先级 <6>
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
q.value=[]; % value 域被赋“空阵”
q.name= '' ; % name 域不给任何字符
q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签
elseif isa(v, 'queue' ); % 输入宗量是同类对象情况
q=v; % 直接把输入量赋给 q
else % 非同类输入宗量情况
q.value=v; % 在 value 域中放置输入对象 v 的内容
q.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(q.name) % 假如输入量无名
q.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end

q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签 <20>
end

(4)为 queue 对象编写显示函数 display.m
[@queue\display.m]
function display(q,ki,kj)
%QUEUE\DISPLAY command window display of a queue object.
% 调用格式
% display(q) 笼统显示整个队列
% display(q,ki) 单下标法显示具体队列元素的内容
% display(q,ki,kj) 双下标法显示具体队列元素的内容
if nargin==0;error( ' 缺少输入宗量,即被显示对象 ! ' ); end
switch nargin
case 1 % 显示整个队列
[m,n]=size(q);
vname=inputname(1); % 被显示对象 q 的名称
if isempty(vname) % 显示对象若无名称
fprintf( 'ans=\n' ); % 按 MATLAB 惯例,屏幕显示 ans 缺省名
elseif fprintf( '%s=\n' ,vname); % 对象有名称时,则屏幕以字符串形式显示名称
end ;

if isempty(q) % 假如被显示对象为“空”
fprintf( ' [ empty ' ) %<17>
fprintf( '%s' ,class(q)) %<18>
fprintf( ' ]\n\n' ); %<19>
elseif m*n==1; % 被显示对象今包含一个“元素”时
fprintf( ' %s: ' ,q.name); % 屏幕先以字符串形式显示所存放对象的名称
disp(q.value); % 紧接着,不换行,显示所存放对象的内容
fprintf( '\n' );
else % 被显示对象今包含多个“元素”时
fprintf( ' [ %d*%d ' ,m,n) % 以下 3 条指令只显示队列“元素”排列 <25>
fprintf( '%s' ,class(q)) %<26>
fprintf( ' ]\n\n' ); %<27>
end

case 2 % 单下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ')' ])
disp([ 'is a ''' ,class(q(ki).value), ''' object' ])
fprintf( ' %s=\n' ,q(ki).name);
disp(q(ki).value);
fprintf( '\n' );
case 3 % 双下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ',' ,int2str(kj), ')' ])
disp([ 'is a ''' ,class(q(ki,kj).value), ''' object' ])
fprintf( ' %s=\n' ,q(ki,kj).name);
disp(q(ki,kj).value);
fprintf( '\n' );
end

(5)编写重载函数 isempty.m
[@queue\isempty.m]
function f=isempty(q)
%@QUEUE\ISEMPTY True for an empty queue object.
f=0;
[m,n]=size(q);
if m*n==1;
if isempty(q.value) & isempty(q.name) %<6>
f=1;
end ;
end ;

(6)编写“入队”、“离队”函数
[ @queue\comein.m]
function q=comein(p,varargin)
% @QUEUE\COMEIN a variable comes to the end of a queue.
% 调用格式
% comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列,
% 其名沿用 p 位置上的输入队列名 .
% q=comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列 q .
if nargin<2 error( 'comein needs at least two arguments.' ); end ;
if ~isa(p, 'queue' ) error([inputname(1), ' is not a queue' ]); end ;
q0=p;
qzzy=class(p); % 获取第一输入宗量的类别字符串 <10>
for i=1:length(varargin)
temp=varargin{i};
s=eval([qzzy, '(temp)' ]); % 使后来元素成为与第一输入宗量相同的类别 <13>
s.name=inputname(i+1);
if isempty(s.name) % 假如某输入宗量本身无名称
s.name=[ '(' class(temp) ')' ]; % 则把它的类别名作为名称使用
end

if isempty(q0) % 假如前队列是“空”队列
q0=s; % 则直接进入队列
else % 假如前队列非“空”
q0=[q0 s]; % 则新变量排在队尾
end
end

if nargout==0; % 假如没有输出宗量
assignin( 'caller' ,inputname(1),q0); % 新队列沿用第一个输入队列名
evalin( 'caller' ,inputname(1));
else % 假如有输入输出宗量
q=q0; % 新队列名为 q
end

[@queue\goout.m]
function [n,v,q]=goout(p)
% @QUEUE\GOOUT removes the first(the front) element from a queue.
% 调用格式
% goout(p) 从队列 p 中的第一个元素离队 .
% v=goout(p) v 是从 p 队列中移出的那第一个元素的“值”
% [n,v]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% [n,v,q]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% q 是被移去第一个元素后的新队列
if nargin==0 ;error( 'No queue specifide.' ); end ;
if nargout>3;error( 'Too many output arguments.' ); end ;
if nargin>1 error( 'Too many input arguments.' ); end ;
if ~isa(p, 'queue' );error([inputname(1), ' is not a queue.' ]); end ;
if isempty(p)
q1=p;
else
[m,n]=size(p);
v1=p(1).value;n1=p(1).name;
if m*n==1
q1=queue;
else
q1=p(2:end);
end
end

if nargout<3;
assignin( 'caller' ,inputname(1),q1);
end ;

if nargout==0,
evalin( 'caller' ,inputname(1));
end
if nargout>=1;v=v1; end ;
if nargout>=2;n=n1; end ;
if nargout==3;q=q1; end ;

【 * 例 8.9.2 -2 】本例的目的:一,检验例 8.9.2-1 所编写的程序的正确性;二,演示所设计的新类是如何被运作的。

(1)创建一个队列对象,并显示。
qe='Hello! 你好 ! '; % 字符串
Q=queue(qe) % 生成队列对象 Q ,并显示
Q=
qe: Hello! 你好 !

(2)类别检查和是否对象判断
class(Q) % 类别检查
isobject(Q) % 是否对象判断
isa(Q,'queue') % 是否队列判断
ans =
queue
ans =
1
ans =
1

(3)是否“空”队列判断
isempty(Q)
ans =
0

【 * 例 8.9.2 -3 】本例目的:一,演示“入队”、“离队”函数的调用方法;二,演示 @queue\display 显示队列具体元素细节的功能。

(1)利用“入队”函数,使队列变长。
a=[1,2,3;4,5,6];b{1}='This';b{2}=' is ';b{3}='a cell array';
comein(Q,a,b) % 增长队列,并显示整个队列的“宏观”情况
Q=
[ 1*3 queue ]

(2)显示队列 Q 中具体元素的内容
display(Q,2) % 给出 Q 队列第 2 个元素的类别、内容:变量名和值
The content of Q(2)
is a 'double' object
a=
1 2 3
4 5 6

(3)把 Q 队列第 1 个元素和其余部分分离,并生成新队列 QQ
[nn,vv,QQ]=goout(Q)
nn =
qe
vv =
Hello! 你好 !
QQ=
[ 1*2 queue ]

(4)采用双下标法,显示 QQ(1,2) 的内容
display(QQ,1,2)
The content of QQ(1,2)
is a 'cell' object
b=
'This' ' is ' 'a cell array'

【例 8.9.2 -4 】利用指令 methods 可以获知对任何类定义的(在类目录上的)所有方法函数。
methods queue
Methods for class queue:

comein display goout isempty queue

Sunday, May 11, 2008

IE Automation & Tabs

A comment to one of my other posts asked about how to launch IE and open several additional tabs.

IE7 does not support specifying multiple URLs on the command line, but another way to do this is to use IE Automation to launch IE as an out-of-proc COM server and then call methods such as IWebBrowser2::Navigate2. While you can do this using C++ or any language that supports COM, the easiest is to use Windows Scripting Host.

First, create a 'lanuchie.js' file using your favorite text editor, add the following, and save:

var navOpenInBackgroundTab = 0x1000;
var oIE = new ActiveXObject("InternetExplorer.Application");
oIE.Navigate2("http://blogs.msdn.com");
oIE.Navigate2("http://blogs.msdn.com/tonyschr", navOpenInBackgroundTab);
oIE.Navigate2("http://blogs.msdn.com/oldnewthing", navOpenInBackgroundTab);
oIE.Navigate2("http://blogs.msdn.com/ericlippert", navOpenInBackgroundTab);
oIE.Visible = true;
Now from the command line you can do:

wscript.exe launchie.js
to open IE, navigate the first tab, and then open three background tabs.

One caveat: due to some IE features such as Protected Mode you will sometimes observe that the links are opened in an existing IE window.

Published Friday, January 19, 2007 10:51 AM by tonyschr

Monday, May 5, 2008

定理(Theorem)、命題(Proposition)、輔助定理(Lemma)、引申定理(Corollary)、假設(Assumption)

名詞定義:
定理(Theorem)、命題(Proposition)、輔助定理(Lemma)、引申定理(Corollary)、假設(Assumption)

名詞解釋

Theorem:就是定理,比較重要的,簡寫是 Thm。

Lemma:小小的定理,通常是為了證明後面的定理,如果證明的篇幅很長時,可能會把證明拆成幾個部分來敘述,雖然篇幅可能變多,但脈絡卻很清楚。

Corollary:推論。由定理立即可推知的結果。

Property:性質,結果雖然值得一記,卻沒定理來的深刻。

Proposition:有人翻譯為「命題」, 有些作者喜歡用,大概也可以算是比較簡單的定理的一種稱呼。

Claim:證明時先敘述一個結果,再作證明。看的人比較輕鬆。

Note:通常只是一個註解。

Remark:涉及一些結論,比較起來 "Note" 比較像說明, "remark" 則常是非正式的定理。

至於「定義」可以想成是一個若且唯若的定理,

Wednesday, April 23, 2008

CSS Code for the blog

CODE {
color: black;
display: block; /* fixes a strange ie margin bug */
font-family: Courier New;
font-size: 8pt;
overflow:auto;
background: #f0f0f0 url(http://yongzhen.zhuang.googlepages.com/Code_BG.gif) left top repeat-y;
border: 1px solid #ccc;
padding: 10px 10px 10px 21px;
max-height:200px;
line-height: 1.2em;
}

We can use element <code></code>. The appearance is like this

<code>
write my code here...........
</code>

C++ STL - Iterator的erase



std::vector<int> v;
v.push_back(0);
std::vector<int>::iterator vi = v.begin();
while(vi != v.end())
{
if(*vi == 0)
{
v.erase(vi++);
continue;
}
++vi;
}


以上這段code在VC2003上run是正常的, 用gcc 3.2.2的話會造成segmentation fault。

很明顯的, vi++這個iterator的運算在兩個平台上有不同的implementation, gcc是先erase才做++的動作, 因為erase後iterator會指向無法預測的地方, 所以才會產生seg-fault。而VC2003則是先++才把原iterator傳進去, 所以沒有問題。

正確的寫法應該是 vi = v.erase(vi);

Sunday, April 20, 2008

微软成立SQL Server中国研发中心 关注BI等领域

CNET科技资讯网6月12日北京报道 今天,微软中国研发集团宣布建立SQL Server中国研发中心。这是继移动技术中心之后,该研发集团成立的第二家着眼当前技术热点的研发机构。

微软表示,该中心成立后会特别关注中国和东亚地区的市场需求。目前,该中心在上海和北京拥有大约30名员工,正式研发人员的规模将在2-3年内达到上百人。

微软全球资深副总裁、微软中国研发集团主席张亚勤博士指出:“随着“以数据为核心的计算”(Data Centric Computing)渐成主流,对数据的分析和处理将成为全球计算科技研发和体验的一大核心。希望SQL Server中国研发中心能够在此领域作出重大贡献。”

SQL Server 中国研发中心任命孙博凯(Prakash Sundaresan)为总监,孙博凯此前在上海工作过18个月。孙表示:“SQL Server中国研发中心关注的领域主要包括: 数据可编程性、商业智能以及开发工具的升级、管理和支持。”

微软称,SQL Server不但可以满足不同规模的企业对海量数据处理、高性能计算、高可靠性解决方案的迫切需求,且能够令企业拥有更高的生产力、卓越的操控力和最佳的商业洞察力。全球数据库市场统计表明,近两年SQL Server的年销售额超过25亿美元,并保持了15%以上的年增长率。在中国,其市场增长率也获得快速提升。

微软成立SQL Server中国研发中心 关注BI等领域

图:张亚勤向孙博凯赠送礼物