| Dahua 的个人资料笑对人生,傲立寰宇照片日志列表 | 帮助 |
|
5月30日 回望第一学年考试周结束后,在MIT的第一学年落下帷幕了,接下来将是长达3个多月的长假。很多同学外出旅游,或者回家度假。而我将留在校园,继续我的research。 经过了一个学年的努力,最重要的目标终于达成了:通过TQE。 在MIT的研究生在学位答辩之前需要经过两次qualify,分别叫TQE(Technical Qualification Exam)和RQE(Research Qualification Exam),它们分别和课程与研究相关。每个系对于qualify有不同的policy,而对于Computer Science的学生来说,TQE并不是一次专门的考试,而是要求修四门主课,必须达到3A1B以上,才算通过TQE。为了保证足够的广度,系里把所开的全部主课分成三大领域(System, Theory, Artificial Intelligence),它们各自又分为三个子领域(共9个)。学生可以自由选四门主课列入自己的TQE Plan,但是这四门课程要求属于四个不同子领域,并且必须覆盖三大领域。 在这个学年里,我修的四门课,分别是
在昨天,成绩全部出来了,以4A通过了这些课程,终于长舒了一口气,这意味着TQE的圆满完成,在接下来的日子可以专心做research了。 坦率地说,MIT CS的课程并不是特别艰深,只要认真去学,在这里的中国学生拿A并不是很难的事情。但是,很多课程确实很重,需要付出大量的时间和精力。为了这些课程,我也放弃了这一学年的主要学术会议了。 MIT的课程在国际上享有盛誉,因为大部分课程是通过OCW(http://ocw.mit.edu)向全世界公开的,可能不少朋友都曾经接触过。不过,在网上看公开的课程资料,和真正参与到这些课程中,感觉还是不一样的。就我个人感觉来说,这里很多课程的课程质量确实是一流的。其实从高中开始,我就有逃课的习惯,直到后来在科大读本科,以及在香港中文大学读硕士的时候,都大量缺课(这不见得是好事,不要随意模仿,呵呵~~~)。主要原因是感觉老师上课的节奏和我的思维节奏不是特别吻合——我更喜欢到图书馆自己看书。在MIT,老师从不点名,但是,我却极少缺课(除了临时的情况,缺过几堂)——老师所讲的课还是有很大的吸引力的。而且每堂课容量很大,我很少觉得老师讲得太慢了,甚至有些地方还未必能当时跟上,需要课后仔细回味。 我所上的这些课程都没有教科书,Lecture Notes都是授课老师(也可能包括他们的学生)自己编写,Problem Set也是老师自己设计。上课的教授都是在学术研究中非常有成就的学者,他们中很多都在顶尖学术会议和期刊上发表了大量paper。上课的内容也贴近学术研究的前沿。其中Advanced Computer Networks这门课,每堂课程的内容几乎都是近年发表的两三篇SIGCOMM的paper(这些paper有一半是MIT发表的)。有一些老教授上课时喜欢说类似这样的话:“今天讲的这个理论是我的某某学生提出的,当年他也和你们一样修我这门课”。 老师们在讲述一个理论,一个方法的时候,很鼓励学生去发现它们的问题和局限。在很多作业和考试题中,都有要求评论某个方法的缺点的题目。比较有意思的是Natural Language Processing的课,这门课每隔两三周,会布置一篇文章回去阅读(通常是发表在Science等顶尖刊物的经典paper),然后要求写一份评论,既要求写正面的,也要求写反面的。为了完成这种任务,我们回去只能把这篇文章反来复去看很多遍去分析其中潜藏的谬误,比如某个理论可能暗含了一些假设,一个表面完美的实验可能隐藏了不公平的因素。然后,大家会带着这些思考到课堂上讨论。 这些锻炼的影响是潜移默化的。上个月审了一些ECCV paper,我发现这种影响被带到了审稿过程中去了。以前审稿会或多或少使用诸如“方法不新”,“实验不充分”这类放之四海皆准,却没什么信息量的理由来批判一些文章。而这次,这类理由一条都没有用,而是逐条抽出文章中的谬误加以剖析批评。这样的评论更为深刻有力,不过,这些paper的处境可能也堪忧了。。。 CS大部分课程都有一个大的course project,而且占评分比重很大(一般在40% - 50%)。所有的project都是非命题的,从选择topic,survey,理论,实验,到最后的paper(report)都是学生自主完成。在topic选择完成后,一般需要先提交一份proposal,老师会给与指导意见。对于每个project,我还是尽己所能做到最好,平均在每个project上投入的时间和精力,绝不亚于一篇CVPR/ICCV。 这些project最后都得到了不错的评价,至于老师们对于project的实际要求有多高,这个我就说不准了。 这一年的压力是很大的,因为,这几门课的成败关系到能否顺利拿到PhD。不过,上课的过程非常有收获,也得到了很大的锻炼。除了上课,还投入相当多的时间学习数学(主要涉及泛函分析,优化理论,现代统计学,测度理论,平滑流行理论,李群论等,有一些是复习巩固,一些是新学),让自己的基础更加扎实。Research的过程拖得比较慢,但也有了一些重要的进展。 在香港的时候发了一些paper,觉得自己走在了领域的前端。而这一年让我重新变成一个学生:我还有很多东西不懂,需要继续学习。 5月24日 编辑器漫谈这篇文章谈到的话题——编辑器,和学术没有直接联系,可是却影响着我们每天的工作效率。我们平常使用电脑的过程中,至少有三类软件是必不可少的:操作系统,网络浏览器,以及编辑器。 网上的很多技术论坛充斥的着这样的争论:Windows vs. Linux,或者IE vs. Firefox。可是,这些争论虽然炽热,但其历史久远的程度却无法和下面的这个争辩相提并论:Vi/Vim vs. Emacs。熟悉Unix/Linux的朋友都知道它们的鼎鼎大名,这两款编辑器都诞生于1976年,其作者也分别是计算机界举足轻重的人物,Bill Joy (Sun的共同创始人和首席科学家),和Richard Stallman (GNU的创立者和自由软件的教父)。这两种编辑器代表了不同的设计哲学,自其诞生起,关于它们孰优孰劣的争论便无日无之,伴随着它们的成长,直到现在。在Wiki上有专门一个词条,叫做"Editor War",它描述了这场延续了超过30年依然没有尽头的“战争”。 在这篇文章中,我无意介入这场争论,而是以一个使用者的角度,回顾在我成长的不同阶段所观察到的各种编辑器的变迁。 遥远的Dos时代:WPS & CCED & Turbo IDE 在1994年的时候,我刚上初中,家里给我买了第一台电脑——那是一台486,使用MS-Dos 6.22 + Windows 3.1。虽然,Windows在那时已经初具规模,但是由于历史的原因,当时Dos下的软件远比Windows下面的丰富,因此大部分工作还是在Dos完成。 当时在国内,大家流行的是学习中文打字——尤其是五笔字型,由于相比于当时智能化程度还很低的拼音具有无可比拟的录入速度,广受青睐。国外的编辑器对于中文一般支持不好,而且不符合中国人的使用方式,使用的人不多。当时主流的文字处理方式是用WPS处理一般的文章,用CCED编撰表格。国内很多文章都是用20行20列的原稿纸撰写——一个方格一个字。这种排版方式只有WPS独家支持,而用Word实现非常困难而且使用不便。 一点题外话,这两款软件的作者,求伯君和朱崇君,是国内早期程序员的杰出代表。当时有一篇广为流传的报道——求伯君卖屋做软件,它让求伯君以及他创立的金山公司成为国产软件事业旗帜。除了WPS,新一代的电脑用户更加熟悉的金山词霸也是金山的作品。平心而论,WPS还是一款非常优秀的软件,也符合国内大部分用户的需要的。由于和微软商业竞争上的失策以及盗版的侵蚀,WPS跌下王座,辉煌不再,令人惋惜。 而程序的撰写,主要使用每种语言自己的IDE,比如Quick Basic, Turbo Pascal, Turbo C/C++,都有自己专用的集成编辑环境。这些软件一张1.44M的软盘就能装下,虽然功能远不如现在用DVD才能装下的Visual Studio,不过其设计确实非常经典,使用也很方便。 在那个时候Turbo Pascal/C的出品人Borland公司是程序设计领域的领袖。可是到了Windows时代,除了Delphi的短暂风行,已经根本无力和Visual Studio抗衡,在一系列战略失误之后,最近把它的程序设计软件事业(旗下的CodeGear公司),以两千多万美元的低价贱卖给一个别的公司。(两千多万美元,对于一般人来说听着很多,但是相比现在的IT业动辄十亿百亿的交易来说,这实在是惨淡得令人伤心。)除了Borland高层在战略上的把握连连失误之外,Borland的顶尖人才大量流失也是其失败的重要原因,连Turbo Pascal和Delphi的首席架构师,也在1996年被微软挖走,为微软开发了一种非常优秀的语言C#。 Windows时代:Microsoft独领风骚 在90年代中期开始,Word开始大量进入国内用户的视野,并且逐步取代了WPS,占据了文字处理的垄断地位。我最早使用Word,是在Word 5.0/6.0版的时候,当时相应的Office版本是4.3。到了Windows 95之后,办公套件的版本开始改用年代表示,到现在已经更新了多个版本:Office 95, 97, 2000, 2003, 2007。 Word 6.0给我的最印象深刻的体验就是所见即所得(WYSIWYG)——字体段落风格直接就显示在工作区里,虽然现在看来这是理所当然,这在当时可是个新概念,WPS等当时还是主流的软件都还不能实现这点,主要还是依靠特殊控制符来表达排版。当时,Office对我有着非常大的吸引力,包括Word/Excel/PowerPoint/Access,每个新版本出来都要详细学习一番。我家里的书柜中还摆放了不少这些软件的教程——不过已经很久没看了,它们是那个时代的印记。 不过,Word功能再强大,也是不能拿来写程序的。在Windows时代的程序开发,经历了短暂的战国时代后,由Microsoft的Visual Studio一统天下。在Windows刚出来的时候,那是一团混乱。习惯了Dos编程的程序员们完全不知道怎么在Windows下面写程序。仓卒之间,开发商就把Dos下的那些开发软件改改拿去出Windows下面的版本:比如Borland C++ 4.0/5.0和Microsoft C 7.0。由于这些东西本身不是为windows写的,用它们开发windows程序困难很多,而且很不稳定。混乱期结束后,真正的windows开发工具出来了,最著名的是Borland Delphi/C++ Builder和Microsoft Visual Studio(包括被广为使用的VC6和VB6)。 Borland和Microsoft的产品一度势均力敌,相持不下。随着它的一些顶尖设计师,包括Anders Hejlsberg被挖到微软,Visual Studio有了长足进步,对于Borland的产品有着越来越明显的优势。Microsoft依赖其强势的市场地位,开始推广.Net,并且推出了C#——这是Anders Hejlsberg领导下的一款力作,在很多方面都是非常优秀的。这时候Borland开始手足无措,左右摇摆,一时要搞Borland.Net来迎合新的趋势,却无法抗衡微软的先天优势,一时又要搞Kylix支持跨平台开发,却发现Linux市场太小无法养活自己,而且那里是开源的天下,商业软件不是那么受欢迎,Mac更是Apple的封闭王国,水泼不进。在进退失据之中逐步失去市场。 在很长一段时间,从高中开始,直到到去MIT之前,我一直是用Visual Studio作为自己的主要开发工具,经历了它从第一代版本VS97, VS6.0, VS.Net 2002, VS.Net 2003直到VS.Net 2005。功能强大而又体贴,是一款值得信赖的软件。我个人不是热别喜欢VS 6.0(虽然到了今天,它依然有大量的人在使用),主要是它对于ISO C++的标准支持得不是特别好,对于很多高级的模板用法编译上存在问题。但是,到了VS2003/2005,这些问题不复存在了。而对于C#的喜爱,也加深了我对于Visual Studio.Net的依赖。 专业领域:向文本回归 Windows是视觉的盛宴,所有的软件都热衷于“所见即所得”的方式——也给用户种下了“所见即所得”是理所当然的印象。在这种方式下,编辑成为了输入文字,以及通过大量的鼠标操作(interaction)来选择和调节样式的工作。Interactive的工作方式,简单,直观,对于普通用户来说确实是最好的。但是对于一些专业要求比较高的工作未必尽然。 从计算机科学的角度看来,它最大的问题在于内容和排版样式紧密耦合。这使得贯彻排版的一致性变得非常困难,基本需要每篇文章逐句逐段的调节。当需要更换排版方式的时候,整个耗时费力的排版过程需要重新进行。Word的样式表在部分解决了这个问题,但是,大量的细调依旧不可避免。 在很多专门领域,要求同一内容方便施加不同的排版方式(学术会议稿件),或者要求排版方式一致地贯彻在大量的文件之中(比如系统性的产生大批帮助文件)。这就需要内容和排版分离来大幅度提高效率——因为它要求内容和排版分离的编辑方式,而不是“所见即所得”的耦合方式。 首先是Latex。这是学术论文撰写的重要方式。它是以纯文本形式编写,以特殊指令,比如\section, \table, \equation等等来标示不同的内容,并通过style file来贯彻最后的排版样式。相比于Word,Latex产生的学术文档一般具有更高的排版质量。公式输入也更为方便(在熟练掌握主要的数学符号输入的情况下)。不过,坦白地说,虽然相比于Word,Latex对于内容和样式有更大程度的的分离,但是,样式还是在一定程度上耦合在所编辑的文本中,比如figure的位置和大小调节,以及\textbf, \emph这些直接写在文中而非style file中的指令。 Latex这样的编译式文字处理形式(以文本编辑源文件,并通过编译生成排版后的结果),还有着另外一个优点,便于自动产生。对于有大量图表的文章,我常用的一种方式就是写一个脚本把实验结果直接生成Latex图表,从而节省手工录入的过程,既提高了效率,又减少了错误。 真正的和排版无关的表达形式是XML,它单纯地放置内容,并且通过XSL(XML Stylesheet Language)来描述内容的表现方式。这种方式被大量运用于自动化的网页和文档的生成过程。我曾经在MATLAB Exchange发表过的一些Toolbox,后来就采用了这种方式大批生成帮助页。 http://web.mit.edu/dhlin/www/softwares/dmtoolbox_doc/helps/mdoc.dmtoolbox.mdir.xml http://web.mit.edu/dhlin/www/softwares/sltoolbox_doc/helps/mdoc.sltoolbox.mdir.xml 大家可以到上面这个网址看看效果(index页面有时传输略缓慢)。主要是,撰写一些脚本从matlab源码的头注释中自动提取帮助内容,产生XML文件,并且通过XSL来定义表现形式。 文本如何产生呢?一种就是上述的用程序批量生成,还有很多还是要文本编辑器来编辑。在Windows里面,文本编辑基本上是百花齐放的局面。没有一种编辑器占垄断地位,我个人用得比较多的是UltraEdit,有时也用EditPlus和NotePad++。一般来说,一些专门格式的文件都用专门的编辑器编写,比如Latex,常用WinEdt或者LatexEditor;XML则用XML Spy,HTML主要用Visual Studio或者DreamWeaver。 在MIT的工作:文本编辑的世界 到了MIT——这是自由软件的大本营,工作方式进一步受到身边环境的同化,全面向Linux转移,这一年里Linux基本就是我的工作环境。(不要误解,这里从来不强迫大家使用什么操作系统,很多人还是坚持用windows的,呵呵,不过如果在公开邮件中宣传Windows可能会惹来Richard Stallman的责难) 在这里,我用Latex写作业,报告和paper,用Latex-Beamer来编写presentation(不再用ppt了),也和使用多年的Visual Studio说再见了。现在,软件的编译构建通过自行撰写MakeFile来完成。这是一种全新的体验——就是你能在这个过程中全面了解和控制每个过程运作的细节——这一切都是自己编写指令完成,而不再是隐藏在按钮后面的神秘过程。你可以非常自由而灵活地把握和定制流程的走向。 看上去有点麻烦,不过磨刀不误砍柴功,通过一个设计良好的脚本(这在一开始可能需要花点时间),可以把大量过程自动化(而使用传统工作方式,可能需要很多次操作),从而很大程度上提高工作效率,而且能很好保证过程的一致性和正确性。 这一次,都只是围绕着一个核心——编辑文本(无论是Latex source, Makefile, Bash script还是Program source code都是以文本形式存在的)。和Windows一样,Linux也有着无数的编辑器,但是有两种是长期占据优势地位的,就是文章一开始提到的Vi/Vim和Emacs。 在Windows里面,编辑器是普通的工具,在Linux里面,在相当程度上,这两种编辑器各自代表着一种文化潮流,其地位不是Windows那些编辑器可以相提并论的。Emacs诞生于MIT,Vi/Vim起源于Berkeley,在我身边的人中使用Emacs的占多数。这是一种强大得令人难以置信的编辑系统。它的使用说明长达561页,这仅仅是使用说明。还有一本长达300多页的说明,告诉你怎么用Emacs LISP来配置这个编辑器。 Emacs被很多人认为就是一个完备的“操作系统”。在这个编辑器里面,你除了编写各种格式的文件之外,可以构建和运行程序,收发邮件,以文本方式浏览网页(它以一种很聪明的方式把网页的内容以比较友好的文本方式呈现给你),还可以玩游戏,和煮咖啡(这个功能对于我来说暂时属于传说)。在某些自由软件社区,Emacs是一种信仰和生活方式,通过经过精心配置的Emacs,你基本上可以不离开它完成几乎全部工作(Hmm, 拿它来打3D游戏似乎还不现实,但是俄罗斯方块之类的是绰绰有余了,呵呵)。 我对于Emacs还没有那么忠诚,不过它在过去的这个学年确实是我的主要编辑工具,我用它完成了我全部的course project——它被用来撰写C/C++, Python, Java, 和Latex。但是,MATLAB还是用matlab自带的editor来写——值得一提的是MATLAB的editor有一种Emacs模式。 Emacs其实是一个非常灵活的软件,对非常核心的部件都可以全面定制,而远不仅仅是key mapping, color scheme等表面的东西。对它的配置,使用一种专门为它设计的语言,叫做Emacs LISP,这是一种基于LISP的专用语言。但学习起来,可能不那么容易。Emacs的配置过程颇为繁琐,它主要通过.emacs文件配置,大家可以在网上看看那些被分享的.emacs配置文件,基本都在数百行以上。也就是说,在让你的Emacs编辑器完全符合你的心意之前,需要编写一个几百行的配置脚本。当然,你用默认的配置也可以,不过在某些格式的文件的编写中没有那么好使。我在第一次使用前,花了整整三天才把它配得比较顺手了。当然了,第一次配好后,把.emacs存下来,以后就省心了——即使重装系统,把那个.emacs拷贝过来就行。 Emacs给人的感觉是有点过于重量级了,即使在一台配备Quadcore(3G Xeon x 4) + 8G Ram的工作站上,打开大部分插件时,还是有时感到一点delay。不要小看这一点delay,在代码编辑的过程中,在效率上会带来不可忽略的开销,(想想击键时需要等待0.2秒的感觉)。后来,始终觉得Emacs不太适合进行轻量级的编辑,于是转向Vim。 Vim也是一种非常优秀和强大的编辑器,编辑效率比Emacs更高。Emacs通过Ctrl, Alt, Shift这些辅助组合键来触发各种功能。而Vim则采用模式方式,它有多种mode。在Insert mode里面,就像普通编辑器那样,比如输入dd,就是敲进去两个字符dd;而在normal mode里面,dd就是删除当前行。它在编辑命令上下了很多的功夫,编辑功能特别强大。比如单是删除就有非常多的方式,dw 删除一个单词,d3w 删除三个单词,d4j 删除接下来三行,d5k 删除前面五行, dG 删除到文章末尾,d$删除到行尾,dft删除到下一个出现的字母t,d'a删除到下个书签为a的地方。。。。。。还有其它非常多样的编辑方式。这使得很多以前需要敲很多键才能完成的功能,在几个键内迅速实现。不过Vim的学习曲线比较陡峭,上手比较难,需要反复大量联系才能熟练,很多人看着几个模式来回切换就晕,更不用说用说那些千变万化的命令组合。不过经过一段时间的坚持练习,后面的编辑速度可以成倍提高,非一般编辑器能比。 相比于Emacs, Vim相对较轻(虽然也在变得臃肿之中),而且很多必要的部件本身就配置得不错,人工配置的工作量比较少。它也有一门专门的语言来配置,叫做Vim Script,新版的Vim也可以用python来配置了。对于我自己使用感觉来说,它的Line Number Display和Omni Completion是相比于Emacs更出色的亮点,而且编辑上感觉不到延时,也不需要老是把手指伸到Ctrl, Alt这种地方去了。
文本编辑是计算机一个很基础的用处,以至于我们常常忽略它。不过,当你深入到它的世界,却可以发现它独特的魅力。 5月21日 哀悼同胞随着最后一个project的完成,第一学年结束了。 这不是一个值得庆祝的时刻——当数万无价的生命无可挽回,当无数的同胞仍在失去亲人的痛苦之中,举国同哀的时候。 对于中华民族来说,2008年是不平凡的一年,我们共同经历了最严峻的挑战。在过去的半年里,我从未如此强烈地感觉到自己对于这片养育了自己的土地的血浓于水的情感。即使到了期末最紧张的时候,依然长时间地看着一篇篇或令人沉重,或令人感动的报道而不能自拔。 身在他乡,方知故乡情重。 虽然无法提供更多的帮助,在这里的大家还是尽了努力,向灾区的人民表达了自己的心意——虽处万里之遥,我们感同身受。 此时此刻,最想要表达的,就是对遇难同胞最深的哀悼。 愿,逝者安息,生者平安。 5月7日 让MATLAB更快MATLAB是一门在数值运算方面非常高效的语言,对于提高MATLAB的效率,有一些大家熟知的方法,比如避免使用for循环,向量化,使用C-mex写核心,等等。这些原则大体是没错的,但是教条地运用有时反而会降低效率。 根据问题的规模,适当选择向量化的策略 向量化的基本思想是以空间换时间,通过把要处理的对象转化成一个矩阵,集中处理。这比起非向量化的处理方式往往需要消耗更多的内存。在内存紧张的时候,内存分配的开销可能是很大的。 比如,给定一个列向量v1,和一个行向量v2, 计算矩阵M,使得M(i, j) = v1(i) + v2(j)。一种常用的向量化实现: m = length(v1); n = length(v2); M = repmat(v1, [1, n]) + repmat(v2, [m, 1]); 这个过程中,除了M以外,还要创建两个大小为m x n的临时矩阵。repmat创建临时矩阵有一定的overhead,主要花费在元素索引上。由于元素加法的向量化收益本身并不显著,扣除repmat的额外开销后,得益就更小了。另外,当这些矩阵很大,接近物理内存容纳能力的时候,必然导致和虚拟内存进行频繁的交换,耗费大量的IO时间,向量化可能得不偿失。这种情况下,下面这种向量化程度略低的方式可能是更好的选择: M = zeros(m, n);
if m < n
for i = 1 : m
M(i, :) = v1(i) + v2;
end
else
for i = 1 : n
M(:, i) = v1 + v2(i);
end
end
这个例子是要说明在设计向量化的时候,要对其它潜在的影响因素也进行考虑,权衡得失。对于这个例子本身,在2007版以后的matlab,有一个通用的简洁的写法。 M = bsxfun(@plus, v1, v2); MATLAB内部对于bsxfun有很专业的优化,这个写法在时间和空间上都比较节省。 对一组d x d矩阵求逆,假设这些矩阵放在大小为d x d x n的数组里。在一般条件下,多个矩阵求逆没有特别的向量化方法,通常就是逐个求 n = size(A, 3);
B = zeros(size(A));
for i = 1 : n
B(:, :, i) = inv(A(:, :, i));
end
不过,当d很小而n很大的时候,比如对大量2x2矩阵求逆(这在设计几何的问题中很常见),那么直接利用2x2矩阵的求逆共识,进行向量化了: a = reshape(A(1, 1, :), [1, n]); b = reshape(A(1, 2, :), [1, n]); c = reshape(A(2, 1, :), [1, n]); d = reshape(A(2, 2, :), [1, n]); g = 1 ./ (a .* d - b .* c); r11 = d .* g; r12 = -b .* g; r21 = -c .* g; r22 = a .* g; B = reshape([r11; r21; r12; r22], [2, 2, n]); 在正式的代码中,还需要处理可能为奇异(a*d-b*c=0)的情况。 某些非数值计算问题的向量化 有些问题,表面上不像是数值计算,但是通过适当的转化,也可以通过向量化解决。 非等量复制: 比如有一组数[10, 20, 30], 各自要复制成[3, 2, 5]份,最终产生出 [10 10 10 20 20 30 30 30 30 30]。这个问题,虽然简单,但是因为不是那么“整齐”,因此向量化不是特别直接。下面给出一种思路: 首先产生出起始位置标志向量[1 0 0 1 0 1 0 0 0 0],然后通过cumsum,产生出[1 1 1 2 2 3 3 3 3 3],最后以此为索引,可以得到结果。 % vs: the values to be copied % ns: the numbers of copies vs = vs(ns > 0); ns = ns(ns > 0); sp = [1, cumsum(ns(1:end-1)) + 1]; result = vs(cumsum(sp)); 对于图像处理或者二维信号问题,善用filter。 比如,要对每个像素,基于其局部邻域进行一些计算。即使整个计算本身不是线性的,但是只要能分解成线性局部运算的组合,就可以利用filter。 比如,对于图像I, 产生V,使得V(i, j)是像素I(i, j)周围w x w邻域的像素的方差。 I = im2double(I); h = ones(w, w) / (w * w); M = imfilter(I, h, 'symmetric'); M2 = imfilter(I.^2, h, 'symmetric'); V = M2 - M.^2; |
|
|