内容


使用 Scilab 通过 PHP 进行有效的数学处理

将 Web 和科学结合起来共建更为智能的世界

Comments

诸如 Ruby、Python 和 PHP 这样的脚本语言可助力当今的服务器端 Web 开发。这些语言非常棒,借助它们,您可以轻松、快捷地构建 Web 站点。不过,它们的缺点是对于数学或科学领域常见的复杂算法无能为力。

越来越多的科学数据开始出现在 Web 上 — 通常是经过授权免费公开的。随这种开放性、认可度和可用性而来的是协作研发。全世界的人们都能够找到他人数据内的模式,促进了人们对于科学奥秘的理解。

科学计算通常需要繁重的处理和功能强大的系统。而这类系统通常很难找到 — 尤其是在科学数据所存在于的 Web 上。在本文中,我们将深入研究一种特定的方式来将科学软件 — Scilab — 的强大功能与服务器端语言 PHP 的开发简便性和 Web 友好性结合起来。

Scilab 是一个数值计算软件包,由来自 INRIA 和 ENPC(Ecole nationale des ponts et chausses)的研究人员在 1990 年开发。它是一种高级的、面向数值的编程语言,并以兼容 GPL 的 CeCILL 语言发布。Scilab 提供了简单的矩阵运算(比如乘法),也提供了高级运算库(比如复数多维算法和相关)。它可被用于信号处理、统计分析、图像增强、流体动力学仿真和数值优化。

设置

我使用的是 Ubuntu kernel 9.10 上的 Scilab V5.1.1、PHP V5.2.10、XHTML V1.0 Strict 和 Apache V2.2.12 来编写和测试本文。本文中提供的例子应该同样适用于它们的新版本,并且在某些情况下,还是后向兼容的。

设置 Scilab

Scilab 可以工作于 Linux/UNIX®、Mac OS X 或 Windows®,并可从 Scilab Web 站点下载(参见 参考资料)。本文主要针对的是 Linux/UNIX 用户,但在 Mac OS X 可以找到类似的指导。对于如何在 Windows 命令行使用 Scilab 的细节,请参见 Scilab 网站。

典型的 Linux/UNIX 系统上没有的 Scilab 的前提条件包括 Java™ 技术、Tcl 和 Tk(Scilab 引擎有时将它用于 UI)或 GNU Compiler Collection (GCC)(Scilab 用 GCC 作为其图像和视频处理工具箱的一部分)。此外,Scilab 也可通过一些 Linux 和 UNIX 包管理器得到,比如使用 Ubuntu 存储库的 Synaptic Package Manager。

设置 PHP 和 Apache

PHP 程序是一些需要通过解释器运行后才能执行的脚本。解释器可以从 PHP 网站(参见 参考资料)下载,也可通过一些 Linux 和 UNIX 包管理器得到。

为了让 PHP 作为一个服务器端语言工作,需要 Web 服务器软件。Apache HTTP Server 就是这样的一个 Web 服务器,该服务器可从 Apache 网站(参见 参考资料)下载,也可通过一些 Linux 和 UNIX 包管理器得到。

有些系统可以封装 Apache 和 PHP 以及其他一些应用程序,比如 MySQL。XAMPP 就是这样的一个例子,但您可能会发现,要执行本文中所列的任务,会有一些限制。

连接

Scilab 是一种数学算法语言,但一般的计算机程序员对它也不陌生。它是一种动态语言,专门用于数学和科学应用程序,此外,它还具有矩阵运算的巨大优势。对于我们当中的数学家和科学家,Scilab 类似于 R 编程语言,并且该系统与开源 GNU Octave 和专有 MATLAB 具有一些相似性。

在命令行连接到 Scilab

Scilab 自带一个非常有用的 GUI,您可轻松将 Scilab 脚本放入其中。不过,您也可以从命令行使用 Scilab,并且为了在稍后能让基于 Web 的系统工作,您也必须要这么做。这个复杂的命令行操作如下所示:

scilab -nwni -nb -e "m=[1 2 3; 3 4 5];disp(m);exit"

初看上去,这多少有点难以理解,因为它使用了一个很奇快的字母组合。首先是单词 scilab,这很直观,作用是激活 Scilab。随后出现的是一些标志(有关 Scilab 何时加载的参数):

  • nwni— 无需窗口系统。
  • nb— 不显示欢迎消息。
  • e— 此行的下一项是 Scilab 引擎必须执行的一个表达式。

变量赋值的一个例子是 a = 5;,其中 a 是一个变量名称,= 是赋值,5 是所赋的值。此行以分号结束(;);否则,它会在执行后打印到屏幕。

本文中的这个例子是将变量赋值给一个矩阵。使用方括号([])可以构建一个矩阵,其中每个元素以空格分隔,每行以分号分隔。所以在本例中,得到的矩阵是 m=[1 2 3; 3 4 5]

对于未来基于 Web 的系统,需要明确哪些内容想要打印到屏幕。为此,使用 Scilab 的 disp 函数,它接受一个变量 disp(m)。然后需要终止 Scilab 以释放计算资源,这可通过 exit 实现。对于如何在 Scilab 内进行脚本编写的细节,可以参见 Scilab Web 站点。

通过 PHP 连接到 Scilab

连接看似截然不同的两个系统 PHP 和 Scilab 有几种方式可选。一种方式是通过其 Java 界面发送直接 Scilab 命令链。另一个方法是通过命令行实例化 Scilab 并将 Scilab 表达式传递给它。我选择了后一种方法,因为 Java 界面处于其早期,需要改进才能在 PHP 内充分发挥其作用。并且,后一种方法还可以全面控制 Scilab 的实例,不受限于预先做好的界面。

第一个例子使用 PHP 发送在前一节中构建的简单 Scilab 命令,以纯文本的格式向屏幕打印一个矩阵。清单 1 显示了此操作所需的代码。

清单 1. 通过 PHP 将结果输出到 Scilab
    <?php
        exec('scilab -nwni -nb -e "m=[1 2 3; 3 4 5];disp(m);exit;"', $output);
        print_r($output);
    ?>

使用 exec 函数来向操作系统发送命令。该命令调用 Scilab,这与在前面一节中介绍的无异:

  • exec— 这个方便的 PHP 函数发送一个字符串供操作系统的命令行处理。在 Web 站点上使用此函数时,要格外小心:如果为用户赋予对它的访问权,那么用户 很可能也可以访问您的服务器的硬盘。它的第一个参数是要发送的命令;第二个参数是完整的多行输出结果。
  • print_r— 此命令只简单地打印所有变量,包括其结构。在本例中,$output 变量是一个一维数组,其内的每个元素都是一行输出。

下面的一个例子综合了各种不同语言的代码 — 即,XHTML Web 数据文档语言、PHP 服务器端语言以及通过 Linux/UNIX 命令行对 Scilab 的调用。请参见清单 2。

清单 2. 向 Scilab 发送复杂表达式并用 XHTML 通过 PHP 呈现输出
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Example 2: Sending equations to Scilab using a PHP web interface</title>
</head>
<body>
<p>Example 2: Sending equations to Scilab using a PHP web interface<p>
<?php

    if(isset($_GET['code']) && $_GET['code'] != "") {
        $defaultcode = str_replace('\"', '"', $_GET['code']);
        $code = preg_replace("/[\n\r]/","", $_GET['code']);
        exec('scilab -nwni -nb -e "' . $code . ';exit;"', $output);
        echo '<div id="result">Result = ';
        foreach($output as $line) {
            print_r($line);
            echo "<br />";
        }
        echo "</div>";
    } else {
        $defaultcode = "";
    }
?>
    <div id="codeeditor">
    <form action="webscilab.php" method="get">
        <textarea id="code" name="code" title="Code" rows="10" cols="30"
			style="Courier, monospace"><?php echo $defaultcode; ?>
		</textarea> <br />
        <input type="submit" id="submit" name="submit" 
			title="Submit" value="Submit" />
    </form>
    </div>
</body>
</html>

首先,让我们先来分析这个 XHTML,着重于几个重要的内容。本文没有涵盖这些重点内容的所有相关细节,W3Schools 网站是一个很不错的起点(参见 参考资料)。

清单 2 中的代码是一个简单的 XHTML 表单。它使用 HTTP GET 方法来通过额外参数刷新当前页面。此表单内有两个元素:一个文本区域用来供用户输入 Scilab 代码以便执行;一个 Submit 按钮用来执行表单动作。

此代码内实施真正控制的是 PHP。在页面加载时,PHP 代码决定此页面是否是一个从表单 “重新加载” 的页面。如果是,代码就只简单地将表单的 Scilab 代码通过 exec 命令发送至 Scilab。来自表单的值存储于 PHP 的 $_GET 数组,它是一个 HTTP get 参数数组。

不过,这里有几个重要的差异。第一,由于 HTTP 和 Web 浏览器均以特定的方式运作,所以需要一种方式来允许用户重新编辑和重新执行其代码。为此,必须将所输入的代码存储在一个变量内,用其原始值替代特定的 HTTP 字符(在本例中,是引号)。PHP 的 str_replace 函数可实现此目的,以便您能够将字符打印到 textarea 表单元素的默认值。

您还必须对此代码进行某些处理。因它是从命令行被发送到 Scilab,所以必须要通过删除它们(或者更为准确地说,用空字符串来代替它们)来清理换行。在本例中,您使用了更为强大的方式:PHP 的 preg_replace,它接受正则表达式作为其搜索关键词。由于 Scilab 代码被放入 exec 函数,exit 命令遂被串接到其尾端,这样一来,就无需依赖用户每次输入 exit

接下来,是一个 PHP foreach 循环,它循环遍历每个输出行并将其很好地呈现成 XHTML,供浏览器显示。此循环迭代这个数组并打印每一行,与它在命令行上所做的无异,只不过在每次打印后均强制使用一个 XHTML 断行元素。

图形式地发送方程式并接收答案

至此,我们已经得到了一个功能比较强大的应用程序,但它与使用 Scilab 界面没有特别大的差异。而且也不是一种特别用户友好的软件使用方式。因而,下一个任务是用 XHTML 和 PHP 提供某种图形界面,为了实现这个目的,可以添加有用的表单来生成功能强大的 Scilab 表达式。

一个能很好地展示这类表单用途的例子是如下所示的这个简单的正弦计算器。为了更清晰地说明,这里只是给出 XHTML 的主体,如清单 3 所示。

清单 3. 一个基于三角形的计算器展示了 Scilab 脚本的动态生成
<body>
<p>Sine Calculator<p>
<?php
    $answer = "";
    if(isset($_GET['opposite']) && isset($_GET['hypotenuse'])) {
        $code = "result = " . $_GET['opposite'] . 
		  "/" . $_GET['hypotenuse'] . "; disp(result); exit";
        exec('scilab -nwni -nb -e "' . $code . '"', $output);
        $answer = $output[1];
    }
?>
    <div id="calculator">
    <form action="example3.php" method="get">
        <label for="opposite">Opposite</label><br />
		<input type="textbox" id="opposite" name="opposite" title="opposite" 
		  value="<?php echo $_GET['opposite']; ?>" /><br />
        <label for="hypotenuse">Hypotenuse</label><br />
		<input type="textbox" id="hypotenuse" name="hypotenuse" 
		  title="hypotenuse" value="<?php echo $_GET['hypotenuse']; ?>" />
		<br />
        <input type="submit" id="submit" name="submit" title="Submit" value="Submit" />
		<br /><br />
        <label for="result">Result</label><br />
		<input type="textbox" id="result" name="result" 
		  value="<?php echo trim($answer); ?>" /><br />
    </form>
    </div>
</body>

上述代码采用了与 清单 2 内的代码编辑器相同的方式。这次,创建的是一个简单的文本框表单,对应于直角三角形的对边和斜边。此表单之后被采纳,计算被从 $_GET 数组串接。原理虽然很简单,但它却可以为强大的科学或数学应用程序提供一个基础。

用 PHP 在 Scilab 中处理图形

Scilab 具有基于数据输出图形的功能。该功能使得 Scilab 极为强大并可被用于 Web 应用程序。它不仅能向屏幕输出图形,而且还能输出到文件,包括适合于 Web 浏览器呈现的文件格式(即 GIF 和 JPEG)。在清单 4 的 Scilab 代码内,一个示例图形被打印到一个 JPEG 文件。

清单 4. Scilab 图形输出脚本的示例
scf(0);
plot2d();
xs2jpg(0,'example4.jpg');

生成图形有很多方式,但是这个 “图形到文件的” 函数 xs2jpg 是其中很有用的一个。为了通过 PHP 运行此代码,需要一个图形库。所以,与在命令行上使用 nwni 标志不同,我们现在使用的是 nw,它仍旧限制 Scilab 为命令行计算,但是加载图形库。

这个功能具有被构造到 PHP 的潜力。清单 5 内的代码(基于 清单 2 内的代码)显示了这样一个例子。(请注意要让此代码正确地工作,需要进行一些权限的设置,而且还有其他的一些替代方法可能效果会更好一些。)

清单 5. 用 XHTML 输出并显示 Scilab 图形的一种快速但不严谨的方式
<body>
<p>Example 4: Sending equations to Scilab and receiving JPEGs<p>
<?php

    if(isset($_GET['code']) && $_GET['code'] != "") {
        $filename = time() . ".jpg";
        $defaultcode = str_replace('\"', '"', $_GET['code']);
        $code = preg_replace("/[\n\r]/","", $_GET['code']);
        $exec = 'scilab -nw -nb -e "' . $code . 
			'xs2jpg(0,\"/var/www/webscilab/' . $filename . '\");exit;"';
        exec($exec);
        ?>
        <div id="result">
          <img src="<?php echo $filename; ?>" alt="result" />
        </div>
        <?php
    } else {
        $defaultcode = "scf(0);
plot2d();";
    }
?>
    <div id="codeeditor">
    <form action="example4.php" method="get">
        <textarea id="code" name="code" title="Code" 
		  rows="10" cols="30" style="Courier, monospace">
			<?php echo $defaultcode; ?>
		</textarea> <br />
        <input type="submit" id="submit" name="submit" title="Submit" value="Submit" />
    </form>
    </div>
</body>

请注意为了创建这个 JEPG 文件,使用了与 xs2jpg 函数的串接。此外,还注意为了生成一个可被链接到的(几乎)惟一的文件名,还使用了时间戳函数,链接是在随后的 XHTML img 标签内实现的。当然,这远非一个完整的解决方案,因为它是试验性的并且依赖于不甚理想的权限设置,但是您可以看出这类任务是可能的。

结束语

本文展示了如何使用 PHP 从命令行连接到 Scilab。您可以将来自用户的 Scilab 脚本发送到 Scilab,并且您可以构建易于使用的界面来生成 Scilab 脚本,因而在保持功能性的同时对用户隐藏了 Scilab 的复杂性。最后,您可以试用 Scilab 的图形库并通过 XHTML 链接到一个已保存的图形。

我希望您能够继续尝试这个独特的软件并在本文铺垫的基础上展开工作。特别是,了解 Scilab 的模拟退火(annealing)和遗传算法函数或图像和视频处理库,后者提供了处理所上传的图片和短片的功能。有了 Web 上的有效数学处理以及各种开源工具和技术,您就能够与他人协作,让我们的星球变得更智能。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=483221
ArticleTitle=使用 Scilab 通过 PHP 进行有效的数学处理
publish-date=04162010