Scilab参考资源

1. 关于Scilab已经出版的图书

2. 关于Scilab的参考文档资源

  1. 中文Scilab教育论坛(Google网上论坛)
  2. 自由科学研究站Scialb文档
  3. 国立高雄海洋科技大学(台湾)Scilab基本教材

(如果有其他文档未列入,请跟网站管理员联系)



3. Scilab 中文教程计划

希望我们大家每个人贡献一点力量,共同撰写一部Scilab中文教程,为中国的开源软件事业做出贡献。手册在以GNU Free Documentation License 1.2协议发布。

如果你想加入Scilab中文教程计划,成为一名开源文档作者 请发信到zd4004@163.com

前言(编写者必读)

目前,尚没有一份完整的中文Scilab文档,建立本文档的目的是集合大家之力量,共同攥写和维护一份Scilab中文使用文档。文档以GNU自由文档协议发布。

对于读者:

对于编写者,需要您:

Scilab概述

1. 科学计算软件与SCILAB
SCILAB是以法国国立信息与自动化研究院(INRIA)和法国桥梁学院(ENPC)的科学家为主共同开发的“开放源码”式科学计算软件。SCILAB一词源于英文 “Scientific Laboratory”(科学实验室)词头的合并。SCILAB已经得到各国研究工作者,大学教授以及教育界和工业界人士的普遍关注,并被免费地引进到他们的研究、教学以及产品研发中,目前正以每月10,000份的速度向全世界发布。
科学计算软件(如加、减、乘、除、微机分、逻辑推理等)是计算机应用的主要内容之一,并已经与实验研究、理论计算并列为三大科学方法。而以完成科学计算为目的的应用软件可以称为科学计算软件。事实上,除了科学问题方面的计算,科学计算软件同样适用于各种工程技术,金融、经济等方面的应用。目前这类软件多数是以数值计算形式为主,基于符号计算(如公式推倒)的应用软件也变得日益普及。
2. SCILAB在世界的发展状况
科学计算软件曾在工程界的研究和发展活动中掀起了一场革命。如今,这些软件已经被广泛应用到工业工程实验室中,成为各科研领域众多学者、教师和学生的必备工具。法国国立信息与自动化研究院(INRIA)无疑是这场革命的先驱者。从1994 年开始,它推出的开放源码软件SCILAB 积极地推动了这场革命。SCILAB 综合了多方面的研究成果,是众多学者心血的结晶,然而SCILAB 的诞生更应该归功于它的六位创始者----SCILAB 小组成员:INRIA 的Francois Delebecque, Claude Gomez, Maurice Goursat, Ramine Nikoukhah 与Serge Steer 以及法国国立桥梁学院(ENPC)的Jean-Phillippe Chancelier.
可以说SCILAB 软件及其工具箱已经取得了很大的成功:每月都有来自全球的近万人次登录SCILAB 网站,并下载该软件。如此国际化的成功一方面因为该软件本身的语法和基本功能完全可以和行业参照软件MATLAB相媲美,另一方面因为它是完全免费的。此外,这份成功也应归功于其源代码开放的特征;使用者可以完全控制其开发计划,并通过嵌入最新最先进的技术,还可以优化SCILAB 软件。
当然,每一个成功之后应该是有一个进步,SCILAB 完全能够而且应该看得更高,走得更远。我们的目标是:在未来几年中使SCILAB 成为一个优秀的数字科学计算工具;并在教育、研究以及工业领域内得到认可,成为一个具有国际水平的参照工具;借助于免费的优势促进其发展,加强SCILAB 使用者和参与群体的安全性;确保工业需要和行业先进技术的优先联系。为朝此目标发展,INRIA 决定在2002 年加大力度,并与学术界和工业界的合作者共同建立“SCILAB 共同体”(Consortium SCILAB)。如此宏大的计划如果仅仅局限于法国或是欧洲范围内是远远不够的,只有将其放在国际环境下才能取得成功。因此,SCILAB 小组的成员正努力逐步扩大SCILAB 在国外的影响。
3. SCILAB在中国的推广
中国科学院自动化所和法国国立信息与自动化研究院(INRIA)联合创办的中法信息、自动化与应用数学实验室吸引了中法许多大学和科研单位的科学家,这些科学家紧密合作,从事了许多基础性、公益性的前沿科学研究。
最近,双方科学家又在推动发展和普及科学计算自由软件SCILAB。他们组织了基于SCILAB平台的应用软件比赛,又出版SCILAB相关的书籍,以便让更多的同仁们了解和掌握SCILAB。中法科学家还在策划进一步完善这一具有巨大应用前景(尤其是对中国科技与教育界)的开放源代码自由软件,体现了中法科学家共有的社会责任。
十余年来,INRIA和法国国立桥梁学院(ENPC)的科学工作者坚持SCILAB的开放源代码与自由软件原则,最近又与中法联合实验室的同仁们共同努力准备将其在中国推广普及,这一行为理所当然地受到了中法两国科学家地支持。许多中国高校地学生还积极参与了基于SCILAB软件平台的应用软件比赛。中国科技部“863”计划和法国驻华使馆,也对此给予了积极的支持。由胡包钢老师编写的《科学计算自由软件——SCILAB教程》的出版,是推动该工作在中国进一步开展的重要一步。
值得一提的是“SCILAB 中国经历”的开始:法国国际农业研究发展中心(CIRAD)研究员Philippe de Reffye 功不可没,在中国的三年中,他在中国科学院与INRIA 共同创建的中法实验室(LIAMA)工作,在那里他用SCILAB 软件成功的开展了植物建模方面的研究。对于此项应用SCILAB 的创始者们是完全没有预想到的。同时,他还与中国若干数学、计算机及农业研究所之间建立了紧密的合作关系。就像种子一经播下,便迅速成长一样,SCILAB 很快就在中国交到了许多朋友。2001、2002 年连续两届的SCILAB 研讨会分别在LIAMA 和上海复旦大学成功召开。“2002 年SCILAB 竞赛”在众多中国大学的参与和支持下顺利举行,并借在北京举行的中欧信息论坛之际举行了正式的颁奖仪式。“2003年SCILAB竞赛”也已经圆满落幕,并于西安召开了2003 年中-法科学计算自由软件SCILAB 研讨会。
经过2003,2003两届SCILAB竞赛,更多的中国大学生们了解和接受了SCILAB,竞赛作品的水平逐年提高。现在,SCILAB竞赛每年举办一届,影响力越来越大,让我们盼望着更多高水平作品和更多SCILAB使用者的出现。也希望随着SCILAB在中国的传播,自由科学软件能够逐渐为广大教育科研人员所接受和使用。

Scilab操作入门

介绍界面,帮助,demo等使用方法

命令提示符: -->
scilab的命令提示符是--> , 在该提示符下可以输入命令。 在运行demo时会有暂停,此时显示的提示符>>只是等待用户按Enter键,不能输入命令。 在菜单Control-> stop可以暂时停止demo的执行,之后命令提示符变为-1->, 此时可以输入命令。 使用resume命令或者选择菜单Control->resume 可以恢复demo的执行。 使用abort命令或选择菜单Control->abort可以放弃demo的执行,命令提示符重新变为-->.

数值运算

基本运算

在指令界面的 '-->'之后,即可输入运算字串。例子:

--> 1+1            //按下[Enter]
Ans      =
2.
--> log(10)         //按下[Enter]
Ans       =
2.3025851

变量与常量
在scilab中变量的宣告是很自由的,几乎大部分的字串皆可以成为变量。例如x=3;a2=14;......但是变量开头不可以是数字。同时也不可以将Scilab内定常数更改它的数值。

Scilab的内定常数多半以'%'开头,例如圆周率π,它以'%pi'来表示。自然常数e:%e。虚数i:%i。如对这些常数重新宣告会出现错误讯息。

矩阵生成

基本运算符

运算符:log系列

三角函数

三种:sin(),cos(),tan().至于cot,sec,csc这三个函数Scilab并没有设计,不过使用:1/sin() , 1/cos() , 1/tan()这样的格式即可解决。

三个反函数:asin(),acos(),atan().

双曲线函数

这是一个跟三角函数相似但内容完全不同的函数。此类函数与e有关。
三个:sinh(),cosh(),tanh()

三个反函数:asinh(),acosh(),atanh()

向量和矩阵运算

矩阵函数

统计分析函数

多项式运算

复数运算

2.5   布尔矩阵



新建网页 1

2.5  
布尔矩阵

布尔变量是指%t(表示真)和%f(表示伪),它们可以用于布尔矩阵中。布尔矩阵的操作和一般矩阵相同,例如可以连接、可以转置等。
对于布尔矩阵常用的操作符就是==和~,而且==和~还可以用于布尔矩阵的构造。
若B是一个布尔矩阵,or(B)和and(B)分别进行逻辑或运算和与运算。
 
-->%t
%t  =
 
  T
 
-->[1,2]==[1,3]
ans  =
 
  T F
 
-->[1,2]==1
ans  =
 
  T F
 
-->a=1:5; a(a>2)
ans  =
 
    3.    4.    5.
 
-->A=[%t,%f,%t,%f,%f,%f];
 
-->B=[%t,%f,%t,%f,%t,%t]
B  =
 
  T F T F T T
 
-->A|B
ans  =
 
  T F T F T T
 
-->A&B
ans  =
 
  T F T F F F   

Scilab语言

介绍Scilab编程语言
.....B

变量定义
......

a=input("a='')
b=input(''b='')
c=input(''c='')
d=b*b-4*a*c
if d<0
disp(''no solution'')
else t=sqrt(d)
x1=(-b+t)/(2*a)
x2=(-b-t)/(2*a)
end

......

for循环
......

while循环
......

函数定义
......

函数调用
......

向量



向量

向量(Vectors


生成向量的最常用方法就是在各个分量之间使用逗号(空格)隔开或者用分号隔开。

例如:

-->v=[2,-3+%i,7]

 v  =

 

    2.  - 3. + i      7.

 

-->v'

 ans  =

 

    2.

  - 3. - i

    7.

 

-->w=[-3;-3-%i;2]

 w  =

 

  - 3.

  - 3. - i

    2.

 

-->v'+w

 ans  =

 

  - 1.

  - 6. - 2.i

    9.

 

-->v*w

 ans  =

 

    18.

 

-->w'.*v

 ans  =

 

  - 6.    8. - 6.i    14.  

 


注意:向量的各分量之间使用逗号或者空格隔开时,生成的是行向量;而用分号隔开时,生成的是列向量。如:

-->v=[2,-3+%i,7]

 v  =

 

    2.  - 3. + i      7.

 

-->v=[2;-3+%i;7]

 v  =

 

    2.

  - 3. + i

7.     

 

空矩阵[]也是合法的向量,它有零行零列:

-->Empty=[]

 Empty  =

 

     []     

 

注意:单引号(')给出的是向量的转置(对于复向量,计算的是复共轭转置)。例如

-->A=[1,2,3]

 A  =

 

    1.    2.    3.

 

-->A'

 ans  =

 

    1.

    2.

    3.

                 

-->A=[1+%i,2+2*%i]

 A  =

 

    1. + i      2. + 2.i

 

-->A=[1+%i,2+2*%i,3+%i]

 A  =

 

    1. + i      2. + 2.i    3. + i

 

-->A'

 ans  =

 

    1. - i

    2. - 2.i

    3. - i    

 


具有相同维数的向量之间可以相加和相减。具有相同维数的行向量和列向量之间也可以进行点积运算。逐个元素之间可以进行乘法
(.*)和除法(./)

 

注意:空格在不同位置所起到的作用也是不同的,例如:

-->v=[1 +3]

 v  =

 

    1.    3.

 

-->w=[1 + 3]

 w  =

 

    4.

 

-->w=[1+ 3]

 w  =

 

    4.

 

-->u=[1, + 8- 7]

 u  =

 

    1.    1. 

 

如果要生成递增或递减的等差向量,可以采用如下的构造方法:

-->v=5:-.5:3

 v  =

 

5.    4.5    4.    3.5    3. 

 


生成的向量以第一个值开始,第三个值结束,而第二个值则作为步长(即等差序列的差值),缺省的步长是
1,如:

-->v=1:10

 v  =

 

    1.    2.    3.    4.    5.   
6.    7.    8.    9.    10.

 

常值序列可以使用ones函数和zeros函数生成,如

-->v=[1 5 6]

 v  =

 

    1.    5.    6.

 

-->ones(v)

 ans  =

 

    1.    1.    1.

 

-->ones(v')

 ans  =

 

    1.

    1.

    1.

 

-->ones(1:4)

 ans  =

 

    1.    1.    1.    1.

 

-->3*ones(1:4)

 ans  =

 

    3.    3.    3.    3.

 

-->zeros(v)

 ans  =

 

    0.    0.    0.

 

-->zeros(1:5)

 ans  =

 

    0.    0.    0.    0.    0. 

 

注意:当ones函数或zeros函数的变量是一个向量时,执行的结果是得到一个和该向量具有相同维数的全1或全0矩阵。

向量



向量

向量(Vectors


生成向量的最常用方法就是在各个分量之间使用逗号(空格)隔开或者用分号隔开。

例如:

-->v=[2,-3+%i,7]

 v  =

 

    2.  - 3. + i      7.

 

-->v'

 ans  =

 

    2.

  - 3. - i

    7.

 

-->w=[-3;-3-%i;2]

 w  =

 

  - 3.

  - 3. - i

    2.

 

-->v'+w

 ans  =

 

  - 1.

  - 6. - 2.i

    9.

 

-->v*w

 ans  =

 

    18.

 

-->w'.*v

 ans  =

 

  - 6.    8. - 6.i    14.  

 


注意:向量的各分量之间使用逗号或者空格隔开时,生成的是行向量;而用分号隔开时,生成的是列向量。如:

-->v=[2,-3+%i,7]

 v  =

 

    2.  - 3. + i      7.

 

-->v=[2;-3+%i;7]

 v  =

 

    2.

  - 3. + i

7.     

 

空矩阵[]也是合法的向量,它有零行零列:

-->Empty=[]

 Empty  =

 

     []     

 

注意:单引号(')给出的是向量的转置(对于复向量,计算的是复共轭转置)。例如

-->A=[1,2,3]

 A  =

 

    1.    2.    3.

 

-->A'

 ans  =

 

    1.

    2.

    3.

                 

-->A=[1+%i,2+2*%i]

 A  =

 

    1. + i      2. + 2.i

 

-->A=[1+%i,2+2*%i,3+%i]

 A  =

 

    1. + i      2. + 2.i    3. + i

 

-->A'

 ans  =

 

    1. - i

    2. - 2.i

    3. - i    

 


具有相同维数的向量之间可以相加和相减。具有相同维数的行向量和列向量之间也可以进行点积运算。逐个元素之间可以进行乘法
(.*)和除法(./)

 

注意:空格在不同位置所起到的作用也是不同的,例如:

-->v=[1 +3]

 v  =

 

    1.    3.

 

-->w=[1 + 3]

 w  =

 

    4.

 

-->w=[1+ 3]

 w  =

 

    4.

 

-->u=[1, + 8- 7]

 u  =

 

    1.    1. 

 

如果要生成递增或递减的等差向量,可以采用如下的构造方法:

-->v=5:-.5:3

 v  =

 

5.    4.5    4.    3.5    3. 

 


生成的向量以第一个值开始,第三个值结束,而第二个值则作为步长(即等差序列的差值),缺省的步长是
1,如:

-->v=1:10

 v  =

 

    1.    2.    3.    4.    5.   
6.    7.    8.    9.    10.

 

常值序列可以使用ones函数和zeros函数生成,如

-->v=[1 5 6]

 v  =

 

    1.    5.    6.

 

-->ones(v)

 ans  =

 

    1.    1.    1.

 

-->ones(v')

 ans  =

 

    1.

    1.

    1.

 

-->ones(1:4)

 ans  =

 

    1.    1.    1.    1.

 

-->3*ones(1:4)

 ans  =

 

    3.    3.    3.    3.

 

-->zeros(v)

 ans  =

 

    0.    0.    0.

 

-->zeros(1:5)

 ans  =

 

    0.    0.    0.    0.    0. 

 

注意:当ones函数或zeros函数的变量是一个向量时,执行的结果是得到一个和该向量具有相同维数的全1或全0矩阵。

计算结果可视化

计算结果可视化

二维平面绘图

三维立体绘图

工具箱开发

本文档来源于 http://www.scilab.org/product/toolbox_guide/html/toolbox.html 页面中的英文文档,编写自己的工具箱,除了参考此文档,也可以参考一些成熟的工具箱的代码和代码组织方式。

工具箱结构

工具箱的根目录名为工具箱的名字(比如mytoolbox),它包含8个子目录:

  • macros: Scilab宏 (例如用Scilab代码写的,以.sci为文件名扩展名的函数),buldmacros宏和loadmacros宏脚本。
  • src: 源代码(所有的 .c 和 .f 文件),一个 buildsrc脚本
  • sci_gateway: 接口程序,和一个buildsci_gateway
  • help: 英语和法语帮助,其子目录明分别为eng和fr,里面包含.xml帮助文件,buildhelp和loadhelp脚本。
  • etc: .html, .pdf, .txt, .jpeg, ...
  • unit tests: .tst files (测试你的工具箱的脚本)
  • demos: 各种展示你的工具箱的例子。
  • includes: .h 文件。

和四个文件:

  • readme.txt: 工具箱描述和安装说明。
  • builder.sce: 主builder
  • loader.sce: 主loader
  • license.txt: 协议

子目录内的builder和loader

主builder和主loader脚本运行每个子目录(如macros,src, help等)里的子builder和子loader,来生成或者装载需要的库和帮助文件。

宏目录

为了方便,在宏目录里的builder和loader分别命名为buildmacros.sce和loadmacros.sce,当然您也可以命名为其他的名字。

一个宏(macros)是以Scilab语言写的一个函数(以.sci结尾)

假设目前我们的工具箱mytoolbox只包含一个.sci文件,函数foo1(见下面的代码)的功能如下:输入一个方阵A,这个函数返回向量XXA对角线上的正数元素。

foo1.sci

function [X]=foo1(A)
	//这个函数返回方阵A对角线上的正数元素
	
	// 检查A的类型和大小
	if  type(A)<>1 then
		error("type of input argument must be a double");
	end
	if  size(A,1)<>size(A,2) then
		error("input argument must be a square matrix");
	end
	//提取对角线上的正数
	X=[];
	for i=1:size(A,1)
		if A(i,i)>0 then
			X($+1)=A(i,i);
		end
	end
endfunction

builder宏

下面的builder宏从macros目录中的.sci文件中创建一个变量,(这儿的名字是mytoolboxlib= toolbox_name +'lib')并保存到库文件中。下面的builder宏代码是通用的,它做两步操作,第一步是找到buildmacros.sce所在的位置(详细内容查看get_absolute_file_path函数的帮助),第二步是生成库文件(详细内容查看genlib函数的帮助)。

buildmacros.sce

mode(-1)   //在这种模式下,下面执行的代码不会显示在屏幕上
toolboxname='mytoolbox'  //定义工具箱的名字
pathB=get_absolute_file_path('buildmacros.sce') //获取本文件的绝对路径
disp('Building macros  in ' +pathB)   //打印提示到屏幕
genlib(toolboxname+'lib',pathB,%t)  //生成宏库
clear pathB genlib toolboxname	//清除刚才定义的变量

请将字符串'mytoolbox'题换成你的工具箱的名字。

loader宏

这个loader宏将macros目录中的所有lib都装载到scilab。跟builder宏一样,它是一个通用的脚本。它第一步确定loadmacros.sce 文件的位置,第二步装载lib到Scilab(详细内容查看load函数的帮助)

loadmacros.sce

mode(-1)  //在这种模式下,下面执行的代码不会显示在屏幕上
pathL=get_absolute_file_path('loadmacros.sce') //获取本文件的绝对路径
disp('Loading macros  in ' +pathL) //打印提示到屏幕
load(pathL+'/lib')                           //装载lib到scilab
clear pathL                                     //清除刚才定义的变量

接口和src目录

primitive是指一个Scilab函数,它使用一个接口程序来调用以C或者Fortran代码写的函数。对于每个Scilabprimitive,我们必须为它在sci_gateway目录中创建对应的接口函数。

在使用C语言的写接口程序的情况下,当一个Scilab primitive被调用的时候,接口函数收件检查输入和输出的数值,类型和大小是否正确(使用CheckRhsCheckLhs 函数),并从Scilab内部堆栈中获取rhs参数的地址,传给接口函数。

我们这里并不展开描述接口函数的所有可能情况,更多的例子请参考SCI/examples目录的例程。

接口程序例程

下面一步一步的解释几个C语言的例子,理解了这个例子,可以帮助你写出其他的接口函数,并添加到你的工具箱。

例子a:
假定一个程序vectsum,它返回输入的两个向量的和。它的C语言函数名是sci_sumab,在Scilab中调用它的命令是sumab

为了方便,Scilab中的调用命令都用"sci_"开头。

下面描述了C语言函数vectsumsci_sumab,这两个函数当我们在Scilab窗口中输入--> Y=sumab(A,B )的时候被使用。

vectsum.c

void vectsum(int n, double * a, double * b, double * y)
{
	int k;
	for (k = 0; k < n; ++k) 
	y[k] = a[k] + b[k];
}

sci_sumab.c


#include "stack-c.h"
extern int vectsum(int n, double * a, double * b, double * y); 

void sci_sumab(char *fname){  
int l1, m1, n1, l2, m2, n2, l3, n;   
		
/* 1 - Check the number of inputs/outputs arguments  */  
int minlhs=1, maxlhs=1, minrhs=2, maxrhs=2; 
CheckRhs(minrhs,maxrhs) ; 
CheckLhs(minlhs,maxlhs) ; 

/* 2 - Check inputs arguments type, and get the size and the address 
          in the Scilab stack of the inputs arguments */  
GetRhsVar(1, "d", &m1, &n1, &l1);
GetRhsVar(2, "d", &m2, &n2, &l2);
		
/* 3 - Check that the inputs arguments have the same size */
/* it's possible to use the chekdims and getscalar functions to make these checks*/ 
n=m2*n2; 
if( n1!=n2 || m1!=m2) 
{
	cerro("inputs arguments must have the same size"); 
	return 0; 
}	
if(n1!=0 && m1!=0)    
	if(n1!=1 && m1!=1)   
	{
		cerro("inputs arguments must be vectors");    
		return(0); 
	}
		 
		
/* 4 - Create a new variable corresponding to the output argument */ 
CreateVar(3,"d",&m2,&n2,&l3);   

/* 5 -call vectsum routine: returns in stk(l3) the sum of a and b*/
vectsum(n,stk(l1),stk(l2),stk(l3));  
		
/* 6 - Specif ouput argument */  
LhsVar(1) = 3;  
return 0;
}

第一步: call CheckRhsVar(minrhs,maxrhs) and CheckLhsVar(minlhs,maxlhs) instructions

CheckRhsVar
function uses the arguments minrhs and maxrhs to check that: minrhs <= number of input arguments <= maxrhs The number of inputs and outputs arguments (respectively 2 and 1) of vectsum are constant, so minrhs=maxrhs=2 and minlhs=maxlhs=1, but for certains functions (see example2) they can be variable, in this case the variables minrhs/minlhs and maxrhs/maxlhs are different.
We can use directly the defined variables Rhs(=number of inputs) and Lhs(=number of outputs) instead of the functions CheckRhsVar and CheckLhsVar.

第二步: call GetRhsVar(1,"d",&m1,&n1,&l1) instruction
GetRhsVar function checks that the type of inputs arguments of sumab are correct, and gets their size and their address in the Scilab stack.

We describe below all arguments of GetRhsVar function:

  • 1 : corresponds to the position on the stack of the first input argument of sumab, i.e A, (2 corresponds to B,...)
  • m1 : gets the rows number of A (m2 for B)
  • n1 : gets the columns number of A (n2 for B)
  • l1 : gets the address of A in the Scilab stack (l2 for B)

第三步: call CreateVar(3,"d",&m2,&n2,&l3) instruction

CreateVar function creates in the Stack at the 3th position a variable which corresponds to the output argument of vectsum (here Y)

  • 3 : position of the created variable in the stack. This position (here 3) must follows the position of the last input argument (here2) of sumab
  • "d": sets the type of the created variable, here double
  • m2: sets the rows number of the created variable(here equal to the rows number of the second input argument B: m2)
  • n2: sets the columns number of the first created variable (here equal to the columns number of the second input argument B: n2)
  • l3: gets the address of the created variable in the Scilab stack

第四步: call vectsum(n,stk(l1),stk(l2),stk(l3)) instruction
The C function vectsum returns in stk(l3) the sum of stk(l1) and stk(l2) (i.e a and b)

第六步: call LhsVar(1) = 3 instruction
The first output argument (here Y) of sumab takes the value of the variable placed in the 3th position on the stack (i.e stk(l3))

例子b:

In the second example we describe the interface program named sci_fun of the Scilab primitive named fun.
This function call the C routines fun1 and fun2 and has 2 syntaxes which are:

First syntax:
--> [X, Y ]=fun(A);
Given a vector A, this function returns the positives components of A in a vector X and the sum of its positives components in a scalar Y.

Second syntax:
--> [X ]=fun(A);
Given a vector A, this function returns the positives components of A in a vector X.

The number of outputs arguments (i.e Lhs value) is variable: for the first syntax Lhs=1, for the second syntax Lhs=2. The number of intputs arguments (i.e Rhs value) is constant: Rhs=1 (first and second syntax).
So the interface program must check that: 1<=Lhs<=2 (set minlhs=1, maxlhs=2) and Rhs=1 (set minrhs=maxrhs=1)

fun1.c (the C function fun1 creates the vector X and the scalar Y. It calls the C function fun2 to get the needed size of X in order to allocate the corresponding memory place)


extern void  fun2(double *, int, int *);

void fun1(double * a,  int na, int * nx,  double ** x , double * y){
	int i, k1=0;
	*y=0;
	fun2(a, na, nx);
	*x=(double *)malloc((*nx)*sizeof(double));
	*y=0;
	for(i=0;i<na;i++)
	if(a[i]>0) {
		*(*x+k1)=a[i];
		*y += a[i];
		k1++;
	};
}

fun2.c

void  fun2(double * a, int na, int * nx)
{
	int i;
	*nx=0;
	for(i=0;i<na;i++)
	if (a[i]>0)  
		(*nx)++;
}

sci_fun.c

#include "stack-c.h"

extern void fun1(double * ,  int, int *, double **, double *);

int sci_fun(char *fname)
{
	int la, ma, na, m=1, nx, i, lx, ls;
	double * x, s;

	/* 1 - Check the number of inputs and outputs arguments */
	/* You can use the variables: Lhs and Rhs */
	int minlhs=1, maxlhs=2, minrhs=1, maxrhs=1;
	CheckRhs(minrhs,maxrhs) ;
	CheckLhs(minlhs,maxlhs) ;

	/* 2 - Check the rhs type, get the rows number (ma) and the columns number (na) of rhs, 
            and its address (la) in the Scilab stack (first position) */
	GetRhsVar(1, "d", &ma, &na, &la); 

	/* 3 - Check rhs is a vector */
	if(ma!=0 && na!=0 )
	{
		if(ma!=1 && na!=1)
		{
			cerro("input argument must be a vector");
			return(0);
		}
	}

	fun1(stk(la), na*ma, &nx, &x, &s);

	/* 4 - Create the place for the first output argument x ( a vector of doubles, size: 1*nx )
                  to the address lx in the Scilab stack (second position) */
	CreateVar(2, "d", &m, &nx, &lx);

	/* if there are two outputs variables then: Create the place for the second output 
            s ( a double, size 1*1)  to the address ls in the Scilab stack (third position) */ 
	/* get the value of s, and put it in the Scilab stack */
	if(Lhs==2)
	{
		CreateVar(3, "d", &m, &m, &ls);
		*stk(ls)=s;
	}

	/* get the components of x, and put them in the Scilab stack */
	for(i=0;i<nx;i++) 
		stk(lx)[i]=x[i];

	/* free memory */
	free(x);

	/* 5 - Specification of outputs variables */
	LhsVar(1) = 2;
	if(Lhs==2)
		LhsVar(2) = 3;
	return 0;
}

基本的builder

现在srcsci_gateway包含了所有为primitives funsumab创建builder所需要的文件(fun1.c, fun2.c, sci_fun.c, vectsum.c, sci_sumab.c) 。

我们需要撰写两个builder:

  • 一是在src目录中,builder(叫做buildersrc)需要创建一系列跟C语言函数对应的共享库(请参考ilib_for_link函数帮助)。
  • 另一个是在interface目录中, builder(叫做buildsci_gateway)创建新的共享库来连接已经编译好的C或者Fortran语言的接口,并生成loader(参考ilib_build函数帮助)。这个loader文件调用addinter函数,加载动态连接库到Scilab(参考addinter函数帮助)。

buildsrc.sce

ilib_for_link('mytoolboxsrc',['fun1.o' 'fun2.o','vectsum.o'],[],"c")

buildsci_gateway.sce

// must be run from this directory
ilib_name  = 'libmytoolbox'     // interface library name
files = ['sci_fun.o', 'sci_sumab.o'];  // objects files
libs  = ["../src/libmytoolboxsrc"]                 // other libs needed for linking
table = [ 'fun', 'sci_fun';
'sumab','sci_sumab'];        // table of (scilab_name,interface-name)
// do not modify below
ilib_build(ilib_name,table,files,libs)

The ilib_name value is the interface library name, the vector files contains all the object interface files,
the vector libs contains the libraries needed for linking (here the library included in the src directory),
the variable table contains the primitives names (first column) and the corresponding interfaces programs names (second column)

帮助目录

这个子目录里包含.xml文件,buildhelp脚本和loadhelp脚本。

在Unix/Linux系统中,你需要sabcmd来创建帮助手册,它是Sablotron软件包的一部分,是一个XML语言解析器。可以从这儿下载:http://www.scilab.org/download/index_download.php?page=related_tool.html

创建.xml文件

这儿是一个模板,用来展示如何撰写.xml帮助文件。你需要做的只是为你的函数的.xml文件填充各个项目的内容(如Langage,title,type,date, short description,……),并将他们放入help目录中。

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE MAN SYSTEM "/home/scilab/scilab-3.0/man/manrev.dtd">
<MAN>

<LANGUAGE>eng</LANGUAGE>
<TITLE>sumab</TITLE>
<TYPE>Scilab Function  </TYPE>
<DATE>20-Mar-2006</DATE>
<SHORT_DESCRIPTION name="add function name">  add short decription here</SHORT_DESCRIPTION>

<CALLING_SEQUENCE>
<CALLING_SEQUENCE_ITEM>add function syntax</CALLING_SEQUENCE_ITEM>
</CALLING_SEQUENCE>

<PARAM>
<PARAM_INDENT>
<PARAM_ITEM>
<PARAM_NAME>add param name</PARAM_NAME>

<PARAM_DESCRIPTION>
<SP>
: add here the parameter description
</SP>
</PARAM_DESCRIPTION>

<PARAM_ITEM>
<PARAM_NAME>add param name</PARAM_NAME>
<PARAM_DESCRIPTION>

<SP>
: add here the parameter description
</SP>
</PARAM_DESCRIPTION>
</PARAM_ITEM>
</PARAM_INDENT>
</PARAM>

<DESCRIPTION>
<DESCRIPTION_INDENT>

<DESCRIPTION_ITEM>
<P>
Add here a paragraph of the function description. 
Other paragraph can be added 
</P>
</DESCRIPTION_ITEM>
<DESCRIPTION_ITEM>
<P>
Add here a paragraph of the function description 
</P>
</DESCRIPTION_ITEM>

</DESCRIPTION_INDENT>
</DESCRIPTION>

<EXAMPLE><![CDATA[
Add here scilab instructions and comments
]]></EXAMPLE>

<SEE_ALSO>
<SEE_ALSO_ITEM> <LINK> add a key here</LINK> </SEE_ALSO_ITEM>

<SEE_ALSO_ITEM> <LINK> add a key here</LINK> </SEE_ALSO_ITEM>
</SEE_ALSO>

<BIBLIO>
<Add here the function bibliography if any 
</BIBLIO>

<AUTHORS>
<AUTHORS_ITEM label='enter here the author name'>
Add here the author  references
</AUTHORS_ITEM>
</AUTHORS>
<USED_FUNCTIONS>
Add here the used function name and  references
</USED_FUNCTIONS>
</MAN>

帮助builder

builder脚本(这儿是buildhelp.sce)创建一个whatis.htm文件,里面是所有函数的简短描述,并将.xml文件转换为.html文件(更多信息请查阅xmltohtml函数帮助)。
> function)

buildhelp.sce

mode(-1) //强制进入slient模式,不显示执行的代码在屏幕
path=get_absolute_file_path('builhelp.sce'); //得到这个文件的绝对路径
add_help_chapter("Title1",path);                  //将帮助添加到帮助章节中
xmltohtml(path,"Title1")                                //将xml转为html
clear path add_help_chapter get_absolute_file_path //清除无用的变量

帮助loader

帮助loader(这儿是loadhelp.sce)添加你的函数帮助文档到Scilab的帮助浏览器中。

loadhelp.sce

mode(-1) //强制进入slient模式,不显示执行的代码在屏幕
path=get_absolute_file_path('loadhelp.sce');//得到这个文件的绝对路径
add_help_chapter("Title1",path);//加载帮助
clear path add_help_chapter get_absolute_file_

总builder和总loader

总的builder和loader在顶层执行,他们去调用每个子builder和子loader,下面的是这两个脚本的例子:

builder.sce

mode(-1);
mainpathB=get_absolute_file_path('builder.sce');
chdir(mainpathB);
if isdir('src') then //如果存在src目录
chdir('src');         //进入src目录
exec('buildsrc.sce'); //执行src目录里的builder.sce
chdir('..');           //回到上一层目录
end                     //end if;下面类似
if isdir('sci_gateway') then 
chdir('sci_gateway');
exec('buildsci_gateway.sce');
chdir('..');
end
if isdir('macros') then
chdir('macros');
exec('buildmacros.sce');
chdir('..');
end
if isdir('help') then
chdir('help');
exec('buildhelp.sce');
chdir('..');
end
clear mainpathB

loader.sce

mode(-1);
mainpathL=get_absolute_file_path('loader.sce');
chdir(mainpathL);
if isdir('sci_gateway') then
chdir('sci_gateway');
exec('loader.sce');
chdir('..');
end
if isdir('macros') then
chdir('macros');
exec('loadmacros.sce');
chdir('..');
end
if isdir('help') then
chdir('help');
exec('loadhelp.sce');
chdir('..');
end
clear mainpathL

上传你的工具箱

另外,建议使用http://sourceforge.net或者其他类似的开源平台来管理工具箱代码。SourceForge.net网站提供了管理软件的版本控制系统(SVN和CVS),主页空间,发布系统,Bug管理系统。它不仅可以让你的软件管理更规范,而且会让更多的人知道你的工具箱,让更多的人受益于你的劳动成果。

Scicos-图形化动态模型仿真器

未归类素材

Scilab 调用C/C++部分函数
调用动态链接库:
Call函数
//分为长调用和短调用2种,用c写的程序可以通过写一个接口程序,实现短调用,如果是C++写的程序,只能用长调用

-长调用:语法.[y1,y2,...]=call("func",x1,n1,"flag-x-1",...,xn,nn,"flag-x-n","out",[m,n],y1,m1,"flag-y")
参数. func: 名字,
x1,x2....xn: 输入变量名
n1,n2....nn: 输入变量x1...xn所在位置,用1,2,3...数字来表示\
flag-x-i: 输入变量x1,x2...xn的类型,用'r','i','d','c'来表示实数,整数,双浮点数,字符串
out: 输入和输出的分界线
[m,n]: 输出变量的维数
y1: 输出变量的个数
m1: 输出变量的位置
flag-y: 输出变量的类型,与flag-x-i类似
-短调用:语法.[y1,y2,...]=call("func",x1,x2,...)
//彭哲,浙江大学修改于2006年12月30日,未完待续

贡献者列表

所有参与攥写文档的人员,可以把您的名字加入到如下列表中:

于仕琪:中科院自动化所自由软件协会
李实:中科院自动化所中法联合实验室
陈新亮:中国科学院半导体研究所
彭哲:浙江大学

部分资料来自:
国立高雄海洋科技大学林正义主页