针对高度依赖数学的用户编码,推荐一种脚本或插件语言?

48

我已为这个问题发起了悬赏

......因为我真的希望社区可以提供意见。我可以(也确实)查看几种语言/框架,并认为“嗯,这可能可以正常工作”——但我真的很感激基于我面临的问题的建议,特别是来自任何具有集成/使用您推荐内容经验的人。


我从事科学分析软件的开发。它提供了许多用于数据数学转换的工具。其中一个工具允许用户输入自己的方程式,该方程式在数据集(一个大的二维或三维值矩阵)上运行并进行评估。
这个工具有一个图形化的方程式编辑器,内部构建了一个面向对象的表达式树,每个操作都有不同的对象(例如,Logarithm类的实例是树中计算值基数对数的节点;它有两个子节点作为输入)。以下是其中一部分的屏幕截图:

enter image description here

您可以在左侧看到它正在构建的树,右侧菜单中有许多(50个?)潜在操作。
这有一些缺点:
- 对于复杂方程,图形编辑器变得笨拙。 - 有一些难以用图形表示的操作,例如创建大矩阵(例如n x n卷积的内核)。 - 它只允许方程式:没有分支或其他逻辑。
当它更简单时,它很整洁,但对于我们的用户想要使用它进行的操作来说不再如此。如果我现在写它,我会用完全不同的方式 - 这是我的机会 :)
我想为用户提供更强大的东西,并让他们编写可以执行更高级操作的代码 - 脚本或编译代码。 我正在寻求SO关于应该使用哪种技术或采取何种方法的建议。
这个问题的其余部分相当长 - 很抱歉。我尝试详细描述问题。先感谢您阅读 :)
重要约束条件:
我们的数学运算是在大矩阵上进行的。在上述方程中,V1代表输入(可能有多个),是2D或3D的,每个维度都可以很大:在数千或数十万的数量级上。(我们很少一次计算所有内容,只是切片/段。但如果答案涉及需要编排数据的内容,请注意大小和速度是要考虑的因素。)
我们提供的操作允许您编写,例如,2 x V,它将V中的每个元素乘以2。结果是另一个相同大小的矩阵。换句话说,包括标准数学原语的脚本或编程语言是不够的:我们需要能够控制可用的原语如何实现它们。
这些操作可能很复杂:输入可以简单地是一个数字(2、5.3、pi),也可以是包含数值布尔值复数(成对的值)数据的1、2或3维矩阵。我目前的想法是使用强大到可以将我们的数据类型公开为类并实现标准运算符的语言。一个简单的评估器是不够的。
与其只编写在一个或多个输入上迭代计算以提供输出的操作(目前可以通过表达式评估器轻松实现),不如让用户能够:为输入提供不同大小的输出;调用其他函数等。对于主机程序,能够询问用户代码将需要哪个部分或切片的输入来评估输出的一部分或切片将非常有用。我认为公开我们的某些类并使用面向对象的语言可能是实现这些点的最佳方式。
我们的受众主要是研究科学家,他们要么不习惯编码,要么可能习惯于像Matlab或R这样的语言。
我们使用Embarcadero C++ Builder 2010进行开发,还有少量Delphi。这可能会限制我们可以利用的内容 - 只因为某些东西是C++,并不意味着它只是针对VC++或GCC进行了编码就能起作用。它还必须适用于商业软件的使用。
我们的软件目前具有COM接口,并且应用程序的一部分可以通过我们的应用程序作为外部进程COM服务器自动化。如果需要,我们可以向某些内部对象添加COM接口,或者专门为此制作第二个COM框架。
“工具”,包括这个工具,正在迁移到多线程框架。最终解决方案需要能够在任何线程中执行,并且在许多线程中同时有多个实例。这可能会影响托管的语言运行时 - 例如,Python 2.x具有全局锁。
使用具有数学或科学用途库的语言将是很好的选择。
与旧表达式工具的向后兼容性并不重要。这是第2版:从头开始!

目前的想法:

  • RemObjects Pascal ScriptDWScript是易于绑定到TObject派生类的语言。我不知道是否可能提供操作符重载。
  • 托管.Net运行时,并加载基于C#(例如)的DLL作为插件。我很喜欢这个想法:我见过这样的做法,其中宿主程序提供了语法高亮、调试等功能。虽然我听说需要大量的编码工作,但这将使IronPython和F#也能够使用。
    • RemObjects Hydra看起来是实现这一点的有趣方法。不幸的是,它是为Delphi而非C ++ Builder设计的;我正在研究兼容性。
  • 托管像Python这样的东西,从RAD Studio中可行
  • 提供BPL接口,并让用户直接针对我们的程序进行编码,如果他们购买了RAD Studio的副本(即提供插件接口,并通过接口公开类;可能需要使用与我们IDE版本兼容的二进制兼容插件)
  • ...
感谢您的回复!即使它们不完美,我也很感激所有的答案-我可以进行研究,只是需要指引和意见(请在答案中包含原因:p)关于如何处理它或什么可能适合。每个答案,无论多么简短,都将受到赞赏。但如果您详细推荐某些内容而不仅仅是“使用语言X”,我会非常有兴趣阅读它:)
干杯,
大卫
更新:
到目前为止,已经推荐了以下内容:
  • Python: 2.6有全局锁,这听起来像是一个游戏杀手。3(显然)还没有得到有用库的广泛支持。对我来说(我知道我是Python社区的外部人员),它似乎有点分裂 - 使用它真的安全吗?

  • Lua:似乎不直接面向对象,但提供了“元机制来实现功能,而不是在语言中直接提供大量功能”。从程序员的角度来看,这听起来非常酷,但它并不针对想要玩耍的程序员。考虑到目标受众,我不确定它会运作得有多好 - 我认为提供更多内置基础的语言会更好。

  • MS脚本/ActiveScript。我们已经提供了一个外部COM接口,我们的用户通常使用VBScript自动化我们的软件。但是,我希望有一个比VBS更强大(而且,坦率地说,设计更好)的语言,我也不认为JScript适合。我也不确定在COM上可能存在哪些数据传输问题 - 我们有很多数据,通常是非常具体的类型,因此速度和保持这些类型非常重要。

  • Lisp:我甚至没有考虑过这种语言,但我知道它有很多粉丝。

  • 托管.Net插件:没有任何人提到。这不是一个好主意吗?您可以获得C#,F#,Python...是否具有与COM相同的数据传输问题?(通过COM工作的CLR托管是否有效?)

澄清一下:我所说的“矩阵”是指Matlab变量意义上的矩阵,即一个包含大量数值的巨型表格,而不是像你在3D软件中使用的4x4转换矩阵。这是随着时间收集的数据,通常每秒钟多次记录成千上万个值。我们也不需要计算机代数系统,而是需要用户能够编写完整插件并编写自己的数学公式 - 尽管如果该系统具有处理复杂数学问题的能力,如计算机代数系统,则会很有用。如果两者不能混合使用,我会选择“全语言”而不是“代数”,以允许用户代码中出现复杂分支/路径以及面向对象接口。

1
说实话,这听起来很像Matlab:http://www.mathworks.com/products/matlab/ - Stijn Sanders
@Stijn Sanders:是的...我试图一般性地描述它,而不涉及特定领域,但我猜这个特定组件可能会类似。整个产品做得更多,这只是其中的一小部分 :) 一些用户使用Matlab,如果我们提供足够的功能,他们就不必使用了。 - David
如果你需要一个迷你版的Matlab,或许wxMaxima是一个不错的选择...就像我在我的回答中所说的那样。 - Warren P
只是好奇,你倾向于哪种脚本语言? - ezpresso
@ezpresso:目前,可以选择Python或托管的.Net运行时。自从我提出这个问题以来,我还没有时间进一步调查(可能很长一段时间都不会有时间)。我倾向于使用.Net,因为用户可以使用多种语言(包括Python),并且插件最终将被编译而不仅仅是解释。它还有一个非常有用的库。这些语言也都相当普遍(特别是与Lua之类的东西相比),这将希望使新手用户更容易学习它们。 - David
显示剩余2条评论
12个回答

3

您提到您的受众群体可能已经习惯了R。建议您考虑将您的产品与R集成,可以作为R扩展或从您的产品中调用R。请参阅编写R扩展。这样您就可以利用R的强大功能和用户熟悉度。


R可能非常方便。我没有多少使用它,也不知道它在处理大量数据时的速度如何。不幸的是,它是GPL许可证,这意味着我们不能像使用LGPL那样链接到它。 - David

3

GIL在Python中不应该成为阻碍多线程的障碍,因为它的存在并不意味着您的应用程序不能进行多线程操作。确实,您不能使用系统上可用的所有CPU核心,但是这只会影响大部分代码都是用Python编写的情况。您的应用程序将托管Python代码,而这些脚本将密集调用主机应用程序中可用的数学例程。这意味着仍然有许多方法可以在应用程序中释放和保持GIL,以最小化其副作用,您会没问题的。


如果我理解你的意思正确的话,您是指GIL只在执行Python代码时保留,并在执行C库或回调代码时释放吗? - David
正确的做法是,在执行本地代码(无论是C还是Delphi)的任务之前和之后释放并持有GIL。 - Jaimy Azle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接