Ⅰ 编译移植busybox出错,arm-linux-gcc版本4.3.3 busybox版本1.16.0 错误代码如下:
找不到链接库,不这些都是数学库,加参数 -lm 应该就能解决。
但编译过程这个东西应该是自己加。
busybox 一般都是静态的,编译静态程序,很多时候需要他以来的函数库也是静态的。你这个问题应该是编译环境不匹配。你编译了 uclibc 并且正确安装了没?
不滚磨和过话说,不过是个编游凳译,人家本来就支持 arm ,“移植”这两个字大盯应该是不需要用了。
Ⅱ 如何使Linux系统上的程序开机后自动运行
阅读之前建议先看一下附图。本文中假设inittab中设置的init tree为:/etc/rc.d/rc0.d /etc/rc.d/rc1.d /etc/rc.d/rc2.d /etc/rc.d/rc3.d /etc/rc.d/rc4.d /etc/rc.d/rc5.d /etc/rc.d/rc6.d /etc/rc.d/init.d1. 关于Linux的段穗启动init是所有进程之父 init读取/etc/inittab,执行rc.sysinit脚本 (注意文件名是不一定的,有些unix甚至会将语句直接写在inittab中) rc.sysinit脚本作了很多工作: init $PATH config network start swap function set hostname check root file system, repair if needed check root space ....rc.sysinit根据inittab执行rc?.d脚本 Linux是多用户系统,getty是多用户与单用户的分水岭 在getty之前运行的是系统脚本2. 关于rc.d所有启动脚本放置在 /etc/rc.d/init.d下 rc? number决定执行的顺序3. 启动脚本示例这是一个用来启动httpd的 /etc/rc.d/init.d/握悄卜apache 脚本: 代码: #!/bin/bash source /etc/sysconfig/rc source $rc_functions case "" in start) echo "Starting Apache daemon..." /usr/local/apache2/bin/apachectl -k start evaluate_retval ;; stop) echo "Stopping Apache daemon..." /usr/local/apache2/bin/apachectl -k stop evaluate_retval ;; restart) echo "Restarting Apache daemon..." /usr/local/apache2/bin/apachectl -k restart evaluate_retval ;; status) statusproc /usr/local/apache2/bin/httpd ;; *) echo "Usage: " exit 1 ;;esac可以看出他接受start,stop,restart,status参运缺数
Ⅲ 简单计算器编程
嘿嘿,C++实现姿没个Console环境中的计算器很简单,鉴于你没给悬赏分,我也懒得打字了,从别处粘贴过来的代码,非常简单,你可以参考一下。
// Ex6_09Extended.cpp
// A program to implement a calculator accepting parentheses
#include <iostream> // For stream input/output
#include <cstdlib> // For the exit() function
#include <cctype> // For the isdigit() function
#include <迹团纳cstring> // For the strcpy() function
using std::cin;
using std::cout;
using std::endl;
void eatspaces(char* str); // Function to eliminate blanks
double expr(char* str); // Function evaluating an expression
double term(char* str, int& index); // Function analyzing a term
double number(char* str, int& index); // Function to recognize a number
char* extract(char* str, int& index); // Function to extract a substring
const int MAX = 80; //或竖 Maximum expression length,
// including '\0'
int main()
{
char buffer[MAX] = {0}; // Input area for expression to be evaluated
cout << endl
<< "Welcome to your friendly calculator."
<< endl
<< "Enter an expression, or an empty line to quit."
<< endl;
for(;;)
{
cin.getline(buffer, sizeof buffer); // Read an input line
eatspaces(buffer); // Remove blanks from input
if(!buffer[0]) // Empty line ends calculator
return 0;
cout << "\t= " << expr(buffer) // Output value of expression
<< endl << endl;
}
}
// Function to eliminate spaces from a string
void eatspaces(char* str)
{
int i = 0; // 'Copy to' index to string
int j = 0; // 'Copy from' index to string
while((*(str + i) = *(str + j++)) != '\0') // Loop while character
// copied is not \0
if(*(str + i) != ' ') // Increment i as long as
i++; // character is not a space
return;
}
// Function to evaluate an arithmetic expression
double expr(char* str)
{
double value = 0.0; // Store result here
int index = 0; // Keeps track of current character position
value = term(str, index); // Get first term
for(;;) // Indefinite loop, all exits inside
{
switch(*(str + index++)) // Choose action based on current character
{
case '\0': // We're at the end of the string
return value; // so return what we have got
case '+': // + found so add in the
value += term(str, index); // next term
break;
case '-': // - found so subtract
value -= term(str, index); // the next term
break;
default: // If we reach here the string
cout << endl // is junk
<< "Arrrgh!*#!! There's an error"
<< endl;
exit(1);
}
}
}
// Function to get the value of a term
double term(char* str, int& index)
{
double value = 0.0; // Somewhere to accumulate
// the result
value = number(str, index); // Get the first number in the term
// Loop as long as we have a good operator
while((*(str + index) == '*') || (*(str + index) == '/'))
{
if(*(str + index) == '*') // If it's multiply,
value *= number(str, ++index); // multiply by next number
if(*(str + index) == '/') // If it's divide,
value /= number(str, ++index); // divide by next number
}
return value; // We've finished, so return what
// we've got
}
// Function to recognize a number in a string
double number(char* str, int& index)
{
double value = 0.0; // Store the resulting value
if(*(str + index) == '(') // Start of parentheses
{
char* psubstr = 0; // Pointer for substring
psubstr = extract(str, ++index); // Extract substring in brackets
value = expr(psubstr); // Get the value of the substring
delete[]psubstr; // Clean up the free store
return value; // Return substring value
}
while(isdigit(*(str + index))) // Loop accumulating leading digits
value = 10*value + (*(str + index++) - '0');
// Not a digit when we get to here
if(*(str + index) != '.') // so check for decimal point
return value; // and if not, return value
double factor = 1.0; // Factor for decimal places
while(isdigit(*(str + (++index)))) // Loop as long as we have digits
{
factor *= 0.1; // Decrease factor by factor of 10
value = value + (*(str + index) - '0')*factor; // Add decimal place
}
return value; // On loop exit we are done
}
// Function to extract a substring between parentheses
// (requires cstring)
char* extract(char* str, int& index)
{
char buffer[MAX]; // Temporary space for substring
char* pstr = 0; // Pointer to new string for return
int numL = 0; // Count of left parentheses found
int bufindex = index; // Save starting value for index
do
{
buffer[index - bufindex] = *(str + index);
switch(buffer[index - bufindex])
{
case ')':
if(numL == 0)
{
size_t size = index - bufindex;
buffer[index - bufindex] = '\0'; // Replace ')' with '\0'
++index;
pstr = new char[index - bufindex];
if(!pstr)
{
cout << "Memory allocation failed,"
<< " program terminated.";
exit(1);
}
strcpy_s(pstr, index-bufindex, buffer); // Copy substring to new memory
return pstr; // Return substring in new memory
}
else
numL--; // Rece count of '(' to be matched
break;
case '(':
numL++; // Increase count of '(' to be
// matched
break;
}
} while(*(str + index++) != '\0'); // Loop - don't overrun end of string
cout << "Ran off the end of the expression, must be bad input."
<< endl;
exit(1);
return pstr;
}
上面的代码来自《Lvor Horton's Begining Visual C++ 2008》一书,非常适合C++初学者。用上面代码实现的计算器可以进行诸如(1+3)*6/2之类的加减乘除和带括号的表达式运算。
此外,在Linux系统的Shell环境中,有个bc计算器程序,功能更强一些,有兴趣的话可以找来源代码看看。
Ⅳ linux shell 关联数组的一个小问题
shell 并不漏悄支持关联数组。
只有awk才支持关联数组凯州。
shell只支持index数字类型的数组,凡是不是数字的,都会当做0,或者-1,也就是最后的那返孙渣个元素。
详细参见bash的man手册。
Arrays
Bash provides one-dimensional array variables. Any variable may be used as an array; the declare builtin
will explicitly declare an array. There is no maximum limit on the size of an array, nor any requirement
that members be indexed or assigned contiguously. Arrays are indexed using integers and are zero-based.
An array is created automatically if any variable is assigned to using the syntax name[subscript]=value.
The subscript is treated as an arithmetic expression that must evaluate to a number greater than or equal
to zero. To explicitly declare an array, use declare -a name (see SHELL BUILTIN COMMANDS below).
declare -a name[subscript] is also accepted; the subscript is ignored. Attributes may be specified for
an array variable using the declare and readonly builtins. Each attribute applies to all members of an
array.
Arrays are assigned to using compound assignments of the form name=(value1 ... valuen), where each value
is of the form [subscript]=string. Only string is required. If the optional brackets and subscript are
supplied, that index is assigned to; otherwise the index of the element assigned is the last index
assigned to by the statement plus one. Indexing starts at zero. This syntax is also accepted by the
declare builtin. Indivial array elements may be assigned to using the name[subscript]=value syntax
introced above.
Any element of an array may be referenced using ${name[subscript]}. The braces are required to avoid
conflicts with pathname expansion. If subscript is @ or *, the word expands to all members of name.
These subscripts differ only when the word appears within double quotes. If the word is double-quoted,
${name[*]} expands to a single word with the value of each array member separated by the first character
of the IFS special variable, and ${name[@]} expands each element of name to a separate word. When there
are no array members, ${name[@]} expands to nothing. If the double-quoted expansion occurs within a
word, the expansion of the first parameter is joined with the beginning part of the original word, and
the expansion of the last parameter is joined with the last part of the original word. This is analogous
to the expansion of the special parameters * and @ (see Special Parameters above). ${#name[subscript]}
expands to the length of ${name[subscript]}. If subscript is * or @, the expansion is the number of ele-
ments in the array. Referencing an array variable without a subscript is equivalent to referencing ele-
ment zero.
The unset builtin is used to destroy arrays. unset name[subscript] destroys the array element at index
subscript. Care must be taken to avoid unwanted side effects caused by filename generation. unset name,
where name is an array, or unset name[subscript], where subscript is * or @, removes the entire array.
The declare, local, and readonly builtins each accept a -a option to specify an array. The read builtin
accepts a -a option to assign a list of words read from the standard input to an array. The set and
declare builtins display array values in a way that allows them to be reused as assignments.
Ⅳ 成为Linux高手要看那些书籍,有什么先后顺序
你要往linux发展是具体要想学什么的呢,开发?系统?数据库?
如果是想往服务器方面发展的话就看各种服务的书(先知道都有哪些服务,是用来做什么的,然后知道它的原理,最后再学习具体搭建与实现,面试的时候最多问的就是原理了),如果是要搞开发的话看嵌入式的书(主要是内核方面,嵌入式最好是培训),嵌入式我不熟,如果想搞服务器的话我可以推荐几本书。
当然了,最开始肯定是看鸟哥了,没的选择,容易看懂,然后看这本---[Linux服务器配置全程实录],大部分的linux服务都涉及到了,再之后,你可能要单独去找shell的书,推荐《shell范例精解》《abs》《Shell脚本专家》《linux命令行, shell宝典》,当然《精通正则表达式》这本书可不能少,grep、sed、awk都需要用到正则,学完shell之后试着自己写些小脚本,不用多,10几20行的写写,试着理解/etc/init.d目录下的服务启动时的启动流程,学完这些后面的书就不多了,学着用些书本上没有的工具,比如nagions\cacti\nagix等等开源软件环境的搭建,这些东西涉及到前面的东西,再之后就是集群和存储了,我培训考试考两个ha(高可用)和lb(负载均衡)我只搭了一个出来,呵呵,基本上集群和存储都是虚拟环境下试验的。还要特别说明的是,学完单个服务并不表示就结束了,而是另一个开始,几个小的综合环境,比如:PXE,LDAP,你可以试试看,最后,当然还有VPN、VOIP这些东西了,我想说的是,如果你精通了我所说的所有东西,先不管你目前工资多少,起码精通完之后,再有一两年相关工作经验,工资基本上就到万了
Ⅵ 《自然》评选改变科学的10个计算机代码项目
从Fortran到arXiv.org,这些计算机编码和平台让生物学、气候科学和物理学等学科的发展达到了真正“日新月异”的速度。
2019年,事件视界望远镜团队让世界首次看到了黑洞的样子。不过,研究人员公布的这张发光环形物体的图像并不是传统的图片,而是经过计算获得的。利用位于美国、墨西哥、智利、西班牙和南极地区的射电望远镜所得到的数据,研究人员进行了数学转换,最终合成了这张标志性的图片。研究团队还发布了实现这一壮举所用的编程代码,并撰文记录这一发现,其他研究者也可以在此基础上进一步加以分析。
这种模式正变得越来越普遍。从天文学到动物学,在现代每一项重大科学发现的背后,都有计算机的参与。美国斯坦福大学的计算生物学家迈克尔·莱维特因“为复杂化学系统创造了多尺度模型”与另两位研究者分享了2013年诺贝尔化学奖,他指出,今天的笔记本电脑内存和时钟速度是他在1967年开始获奖工作时实验室制造的计算机的1万倍。“我们今天确实拥有相当可观的计算能力,”他说,“问题在于,我们仍然需要思考。”
如果没有能够解决研究问题的软件,以及知道如何编写并使用软件的研究人员,一台计算机无论再强大,也是毫无用处的。如今的科学研究从根本上已经与计算机软件联系在一起,后者已经渗透到研究工作的各个方面。近日,《自然》(Nature)杂志将目光投向了幕后,着眼于过去几十年来改变科学研究的关键计算机代码,并列出了其中10个关键的计算机项目。
这台CDC 3600型计算机于1963年交付给位于科罗拉多州博尔德的国家大气研究中心,研究者在Fortran编译器的帮助对其进行了编程
语言先驱:Fortran编译器(1957年)
最初的现代计算机并不容易操作。当时的编程实际上是手工将电线连接成一排排电路来实现的。后来出现了机器语言和汇编语言,允许用户用代码为计算机编程,但这两种语言都需要对计算机的架构有深入的了解,使得许多科学家难以掌握。
20世纪50年代,随着符号语言的发展,特别是由约翰·巴克斯及其团队在加州圣何塞的IBM开发的“公式翻译”语言Fortran,这种情况发生了变化。利用Fortran,用户可以用人类可读的指令来编程,例如x = 3 + 5。然后由编译器将这些指令转换成快速、高效的机器代码。
不过,这一过程仍然很不容易。早期的程序员使用打孔卡来输入代码,而复杂的模拟可能需要数万张打孔卡。尽管如此,新泽西州普林斯顿大学的气候学家真锅淑郎(Syukuro Manabe)还是指出,Fortran让非计算机科学家也能编程,“这是我们第一次能够自己给计算机编程”。他和同事们利用这种语言开发的气候模型是最早取得成功的模型之一。
Fortran发展至今已经到了第八个十年,它仍然广泛应用于气候建模、流体动力学、计算化学等学科,这些学科都涉及到复杂线性代数并需要强大的计算机来快速处理数字。Fortran生成的代码速度很快,而且仍然有很多程序员知道如何编写。古早的Fortran代码库仍然活跃在世界各地的实验室和超级计算机上。“以前的程序员知道他们在做什么,”美国海军研究院的应用数学家和气候模型师弗兰克·吉拉尔多说,“他们非常注重内存,因为他们拥有的内存非常少。”
信号处理器:快速傅立叶变换(1965)
当射电天文学家扫描天空时,他们捕捉到的是随时间变化的复杂信号杂音。为了理解这些无线电波的本质,他们需要看到这些信号作为频率的函数时是什么样的。一种名为“傅里叶变换”的数学过程可以帮到研究人员,但它的效率很低,对于一个大小为N的数据集需要N^2次计算。
1965年,美国数学家詹姆斯·库利和约翰·杜基想出了一种加速该过程的方法。快速傅里叶变换(FFT)通过递归(一种通过重复将问题分解为同类的子问题而解决问题的编程方法)将计算傅里叶变换的问题简化为N log2(N)步。随着N的增加,速度也会提高。对于1000个点,速度提升大约是100倍;100万个点则是5万倍。
这个“发现”实际上是一个再发现,因为德国数学家高斯在1805年就对此进行了研究,但他从未发表过。而詹姆斯·库利和约翰·杜基做到了,他们开启了傅里叶变换在数字信号处理、图像分析、结构生物学等领域的应用,成为应用数学和工程领域的重大事件之一。FFT在代码中的应用已有很多次,近年一个流行的方案是FFTW,被认为是世界上最快的FFT。
保罗·亚当斯是加州劳伦斯伯克利国家实验室分子生物物理学和综合生物成像部门的主任,他回忆称,当他在1995年改进细菌蛋白质凝胶的结构时,即使使用FFT和超级计算机,也需要“很多个小时,甚至数天”的计算。“如果在没有FFT的情况下尝试做这些,我不知道在现实中应该如何做到,”他说,“那可能要花很长时间。”
分子编目:生物数据库(1965年)
数据库是当今科学研究中不可或缺的组成部分,以至于人们很容易忘记它们也是由软件驱动的。过去的几十年中,数据库资源的规模急剧膨胀,影响了许多领域,但或许没有哪个领域的变化会比生物学领域更引人注目。
蛋白质数据库Protein Data Bank拥有超过17万个分子结构的档案,包括这种细菌的“表达子”(expressome),其功能是结合RNA和蛋白质合成的过程。
今天,科学家所用的庞大基因组和蛋白质数据库源于美国物理化学家玛格丽特·戴霍夫的工作,她也是生物信息学领域的先驱。20世纪60年代初,当生物学家们致力于梳理蛋白质的氨基酸序列时,戴霍夫开始整理这些信息,以寻找不同物种之间进化关系的线索。她与三位合著者于1965年发表了《蛋白质序列和结构图谱》,描述了当时已知的65种蛋白质的序列、结构和相似性。 历史 学家布鲁诺·斯特拉瑟在2010年写道,这是第一个“与特定研究问题无关”的数据集,它将数据编码在打孔卡中,这使得扩展数据库和搜索成为可能。
其他“计算机化”的生物数据库紧随其后。蛋白质数据库Protein Data Bank于1971年投入使用,如今详细记录了超过17万个大分子结构。加州大学圣地亚哥分校的进化生物学家拉塞尔·杜利特尔在1981年创建了另一个名为Newat的蛋白质数据库。1982年,美国国立卫生研究院(NIH)与多个机构合作,成立了GenBank数据库,这是一个开放获取的DNA序列数据库。
这些数据库资源在1983年7月证明了其存在价值。当时,由伦敦帝国癌症研究基金会蛋白质生物化学家迈克尔·沃特菲尔德领导的团队,与杜利特尔的团队各自独立报道了一个特殊的人类生长因子序列与一种导致猴子出现癌症的病毒蛋白质之间的相似性。观察结果显示了一种病毒诱发肿瘤机制——通过模仿一种生长因子,病毒会诱导细胞不受控制地生长。美国国家生物技术信息中心(NCBI)前主任詹姆斯·奥斯特尔说:“这一结果让一些对计算机和统计学不感兴趣的生物学家头脑里灵光一闪:我们可以通过比较序列来了解有关癌症的一些情况。”
奥斯特尔还表示,这一发现标志着“客观生物学的到来”。除了设计实验来验证特定的假设,研究人员还可以挖掘公共数据集,寻找那些实际收集数据的人可能从未想到的联系。当不同的数据集连接在一起时,这种力量就会急剧增长。例如,NCBI的程序员在1991年通过Entrez实现了这一点;Entrez是一个可以让研究人员在DNA、蛋白质和文献之间自由检索和比对的工具。
预测领先者:大气环流模式(1969年)
在第二次世界大战结束时,计算机先驱约翰·冯·诺伊曼开始将几年前用于计算弹道轨迹和武器设计的计算机转向天气预测问题。真锅淑郎解释道,在那之前,“天气预报只是经验性的”,即利用经验和直觉来预测接下来会发生什么。相比之下,冯·诺伊曼的团队“试图基于物理定律进行数值天气预测”。
新泽西州普林斯顿的美国国家海洋和大气管理局(NOAA)地球物理流体动力学实验室的建模系统部门负责人Venkatramani Balaji表示,几十年来,人们已经熟知这些方程式。但早期的气象学家无法实际解决这些问题。要做到这一点,需要输入当前的条件,计算它们在短时间内会如何变化,并不断重复。这个过程非常耗时,以至于在天气状况实际出现之前还无法完成数学运算。1922年,数学家刘易斯·弗莱·理查森花了几个月时间计算德国慕尼黑的6小时预报。根据一段 历史 记载,他的结果是“极不准确的”,包括“在任何已知的陆地条件下都不可能发生的”预测。计算机使这个问题变得很容易解决。
20世纪40年代末,冯·诺伊曼在普林斯顿高等研究院建立了天气预报团队。1955年,第二个团队——地球物理流体动力学实验室——开始进行他所谓的“无限预测”,也就是气候建模。
真锅淑郎于1958年加入气候建模团队,开始研究大气模型;他的同事柯克·布莱恩将这一模型应用在海洋研究中。1969年,他们成功将二者结合起来,创造了《自然》杂志在2006年所说的科学计算“里程碑”。
今天的模型可以将地球表面划分为一个个25公里 25公里的正方形,并将大气层划分为数十层。相比之下,真锅淑郎和布莱恩的海洋-大气联合模型划分的面积为500平方公里,将大气分为9个层次,只覆盖了地球的六分之一。尽管如此,Venkatramani Balaji表示,“这个模型做得很好”,使研究团队第一次能够通过计算机预测二氧化碳含量上升的影响。
数字运算机:BLAS(1979年)
科学计算通常涉及到使用向量和矩阵进行相对简单的数学运算,但这样的向量和矩阵实在太多了。但在20世纪70年代,还没有一套普遍认可的计算工具来执行这些运算。因此,从事科学工作的程序员会将时间花在设计高效的代码来进行基本的数学运算,而不是专注于科学问题。
加州劳伦斯利弗莫尔国家实验室的Cray-1超级计算机。在BLAS编程工具于1979年问世之前,并没有线性代数标准可供研究人员在Cray-1超级计算机等机器上工作
编程世界需要一个标准。1979年,这样的标准出现了:基本线性代数程序集(Basic Linear Algebra Subprograms,简称BLAS)。这是一个应用程序接口(API)标准,用以规范发布基础线性代数操作的数值库,如矢量或矩阵乘法。该标准一直发展到1990年,为向量数学和后来矩阵数学定义了数十个基本例程。
美国田纳西大学计算机科学家、BLAS开发团队成员杰克·唐加拉表示,事实上,BLAS把矩阵和向量数学简化成了和加法和减法一样基本的计算单元。
美国德克萨斯大学奥斯汀分校的计算机科学家Robert van de Geijn指出,BLAS“可能是为科学计算定义的最重要的接口”。除了为常用函数提供标准化的名称之外,研究人员还可以确保基于BLAS的代码在任何计算机上以相同方式工作。该标准还使计算机制造商能够优化BLAS的安装启用,以实现在其硬件上的快速操作。
40多年来,BLAS代表了科学计算堆栈的核心,也就是使科学软件运转的代码。美国乔治·华盛顿大学的机械和航空航天工程师洛雷娜·巴尔巴称其为“五层代码中的机械”。而杰克·唐加拉说:“它为我们的计算提供了基础结构。”
显微镜必备:NIH Image(1987年)
20世纪80年代初,程序员韦恩·拉斯班德在马里兰州贝塞斯达的美国国立卫生研究院的脑成像实验室工作。该实验室拥有一台扫描仪,可以对X光片进行数字化处理,但无法在电脑上显示或分析。为此,拉斯班德写了一个程序。
这个程序是专门为一台价值15万美元的PDP-11小型计算机设计的,这是一台安装在架子上的计算机,显然不适合个人使用。然后,在1987年,苹果公司发布了Macintosh II,这是一个更友好、更实惠的选择。拉斯班德说:“在我看来,这显然是一种更好的实验室图像分析系统。”他将软件转移到新的平台上,并重新命名,建立了一个图像分析生态系统。
NIH Image及其后续版本使研究人员能在任何计算机上查看和量化几乎任何图像。该软件系列包括ImageJ,一个拉斯班德为Windows和Linux用户编写的基于Java的版本;以及Fiji,这是ImageJ的分发版,由德国德累斯顿的马克斯普朗克分子细胞生物学和遗传学研究所的Pavel Tomancak团队开发,其中包括关键的插件。“ImageJ无疑是我们所拥有的最基础的工具,”布洛德研究所(由麻省理工学院和哈佛大学联合创立)成像平台的计算生物学家贝丝·契米妮说,“我从来没有和一个使用过显微镜,但没有使用过ImageJ或Fiji的生物学家说过话。”
拉斯班德表示,部分原因可能是这些工具是免费的。但威斯康星大学麦迪逊分校的生物医学工程师Kevin Eliceiri指出,另一个原因是用户可以很容易地根据自己的需求定制工具。自拉斯班德退休后,Kevin Eliceiri的团队一直领导着ImageJ的开发。ImageJ提供了一个看似简单、极简主义的用户界面,自20世纪90年代以来基本上没有改变。然而,由于其内置的宏记录器(允许用户通过记录鼠标点击和菜单选择的序列来保存工作流)、广泛的文件格式兼容性和灵活的插件架构,该工具具有无限的可扩展性。该团队的编程主管柯蒂斯·鲁登表示,有“数以百计的人”为ImageJ贡献了插件。这些新添加的功能极大扩展了研究人员的工具集,例如在视频中跟踪对象或自动识别细胞的功能。
Kevin Eliceiri说:“这个程序的目的不是做到一切或终结一切,而是服务于用户的目标。不像Photoshop和其他程序,ImageJ可以成为你想要的任何东西。”
序列搜索器:BLAST (1990年)
可能没有什么能比把软件名称变成动词更能说明文化的相关性了。提到搜索,你会想到谷歌;而提到遗传学,研究者会立刻想到BLAST。
通过诸如替代、删除、缺失和重排等方式,生物将进化中的改变蚀刻在分子序列中。寻找序列之间的相似性——特别是蛋白质之间的相似性——可以让研究人员发现进化关系,并深入了解基因功能。在迅速膨胀的分子信息数据库中,想要快速而准确地做到这一点并不容易。
玛格丽特·戴霍夫在1978年提供了关键的进展。她设计了一种“点接受突变”矩阵,使研究人员不仅可以根据两种蛋白质序列的相似程度,还可以根据进化距离来为评估它们的亲缘关系。
1985年,弗吉尼亚大学的威廉·皮尔森和NCBI的大卫·利普曼引入了FASTP,这是一种结合了戴霍夫矩阵和快速搜索能力的算法。
数年后,利普曼与NCBI的沃伦·吉什和斯蒂芬·阿特舒尔,宾夕法尼亚州立大学的韦伯·米勒,以及亚利桑那大学的吉恩·迈尔斯一起开发了一种更强大的改进技术:BLAST(Basic Local Alignment Search Tool)。BLAST发布于1990年,将处理快速增长的数据库所需的搜索速度,与提取进化上更为遥远的匹配结果的能力结合起来。与此同时,该工具还可以计算出这些匹配发生的概率。
阿特舒尔表示,计算结果出来得非常快,“你可以输入搜索内容,喝一口咖啡,搜索就完成了。”但更重要的是,BLAST很容易使用。在一个通过邮寄更新数据库的时代,沃伦·吉什建立了一个电子邮件系统,后来又建立了一个基于网络的架构,允许用户在NCBI计算机上远程运行搜索,从而确保搜索结果始终是最新的。
哈佛大学的计算生物学家肖恩·艾迪表示,BLAST系统为当时处于萌芽阶段的基因组生物学领域提供了一个变革性的工具,即一种根据相关基因找出未知基因可能功能的方法。对于各地的测序实验室,它还提供了一个新颖的动词。“它是众多由名词变成动词的例子之一,”艾迪说,“你会说,你正准备BLAST一下你的序列。”
预印本平台:arXiv.org (1991年)
20世纪80年代末,高能物理学家经常将他们已投稿的论文手稿副本邮寄给同行,征求他们的意见——但只发给少数人。物理学家保罗·金斯帕格在2017年写道:“处于食物链较低位置的人依赖于一线研究者的成果,而非精英机构中有抱负的研究人员则往往身处特权圈以外。”
1991年,当时在新墨西哥州洛斯阿拉莫斯国家实验室工作的金斯帕格编写了一个电子邮件自动应答程序,希望建立一个公平的竞争环境。订阅者每天都会收到预印本列表,每一篇都与文章标识符相关联。只需通过一封电子邮件,世界各地的用户就可以从实验室的计算机系统中提交或检索论文,并获得新论文的列表,或按作者或标题进行搜索。
金斯帕格的计划是将论文保留三个月,并将内容限制在高能物理学界。但一位同事说服他无限期地保留这些文章。他说:“就在那一刻,它从布告栏变成了档案馆。”于是,论文开始从比各个领域如潮水般涌来。1993年,金斯伯格将这个系统迁移到互联网上,并在1998年将其命名为arXiv.org,沿用至今。
arXiv成立已近30年,拥有约180万份预印本,全部免费提供,而且每月有超过1.5万份论文提交,下载量达3000万次。十年前,《自然-光子学》(Nature Photonics)的编辑在评论arXiv创立20周年时写道:“不难看出为什么arXiv的服务会如此受欢迎,这个系统让研究人员能快速而方便地插上旗帜,显示他们所做的工作,同时避免投稿传统同行评议期刊时的麻烦和时间成本。”
arXiv网站的成功也促进了生物学、医学、 社会 学和其他学科同类预印本网站的繁荣。在如今已出版的数万份关于新冠病毒的预印本中就可以看到这种影响。“很高兴看到30年前在粒子物理学界之外被认为是异端的方法,现在被普遍认为是平淡无奇和自然而然的,”金斯伯格说,“从这个意义上说,它就像一个成功的研究项目。”
数据浏览器:IPython Notebook (2011年)
2001年,费尔南多·佩雷斯还是一位希望“寻找拖延症”的研究生,当时他决定采用Python的一个核心组件。
Python是一种解释型语言,这意味着程序是逐行执行的。程序员可以使用一种称为“读取-评估-打印循环”(read–evaluate–print loop,简称REPL)的计算调用和响应工具,在其中输入代码,然后由解释器执行代码。REPL允许快速 探索 和迭代,但佩雷斯指出,Python的REPL并不是为科学目的而构建的。例如,它不允许用户方便地预加载代码模块,也不允许打开数据可视化。因此,佩雷斯自己编写了另一个版本。
结果就是IPython的诞生,这是一个“交互式”Python解释器,由佩雷斯在2001年12月推出,共有259行代码。十年后,佩雷斯与物理学家布莱恩·格兰杰和数学家埃文·帕特森合作,将该工具迁移到web浏览器上,推出了IPython Notebook,开启了一场数据科学革命。
与其他计算型Notebook一样,IPython Notebook将代码、结果、图形和文本合并在一个文档中。但与其他类似项目不同的是,IPython Notebook是开源的,邀请了大量开发者社区的参与其中。而且它支持Python,一种很受科学家欢迎的语言。2014年,IPython演变为Jupyter,支持大约100种语言,允许用户在远程超级计算机上 探索 数据,就像在自己的笔记本电脑上一样轻松。
《自然》杂志在2018年写道:“对于数据科学家,Jupyter实际上已经成为一个标准。”当时,在GitHub代码共享平台上有250万个Jupyter Notebook;如今,这一数字已经发展到1000万个,在2016年引力波的发现,以及2019年的黑洞成像工作中,它们都发挥了重要的作用。佩雷斯说:“我们对这些项目做出了很小的贡献,这是非常值得的。”
快速学习器:AlexNet(2012年)
人工智能有两种类型。一种是使用编码规则,另一种则通过模拟大脑的神经结构来让计算机“学习”。加拿大多伦多大学的计算机科学家杰弗里•辛顿表示,几十年来,人工智能研究人员一直认为后者是“一派胡言”。但在2012年,他的研究生亚力克斯·克里泽夫斯基和伊尔亚·苏茨克维证明了事实并非如此。
在一年一度的ImageNet比赛中,研究人员被要求在一个包含100万张日常物体图像的数据库中训练人工智能,然后在一个单独图像集上测试生成的算法。辛顿表示,当时最好的算法错误分类了大约四分之一的图像。克里泽夫斯基和苏茨克维的AlexNet是一种基于神经网络的“深度学习”算法,它将错误率降低到了16%。辛顿说:“我们基本上把错误率减半了,或者说几乎减半了。”
辛顿还指出,该团队在2012年的成功反映了足够大的训练数据集与出色的编程,以及新出现的图形处理单元的强大能力的结合。图形处理单元是最初设计用来加速计算机视频性能的处理器。“突然之间,我们可以将(算法)运行速度提高30倍,”他说,“或者说,学习多达30倍的数据。”
真正的算法突破实际上发生在三年前,当时辛顿的实验室创建了一个神经网络,可以比经过几十年改进的传统人工智能更准确地识别语音。“只是稍微好一点,”辛顿说,“但这已经预示了某些东西。”
这些成功预示着深度学习在实验室研究、临床医学和其他领域的崛起。通过人工智能的深度学习,手机能够理解语音查询,图像分析工具能够很容易地在显微照片中识别出细胞;这就是为什么AlexNet会成为众多从根本上改变科学,也改变世界的工具之一。(任天)
Ⅶ 关于linux里运行mathematica的.nb文件
输入1+1,然后按shift+enter,或前陵者数字键并晌盘的回车键,或者选定单元然右击选“慧蔽戚evaluate cell”,这三种方法都能运行该单元内的代码
Ⅷ 在Linux环境下模拟实现简单命令解释器
我记得以前有一个网站,可以在线模拟,不管什么命令都可以执行,包括rm -rf /
只是不记得那个网站了。