Maple 代码生成:如何自动声明变量?

发布于 2024-10-20 01:19:06 字数 294 浏览 2 评论 0原文

在 Maple(版本 14,如果重要的话)中,我定义了一个在 Maple 中使用全局定义表达式的过程,但是当我进行代码生成时,它假设该变量不是我所期望的。

a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)

我期望的是一个 C 函数,并将表达式插入到代码中,但我得到了......

double p (double x, double y)
{
  return(a);
}

In Maple (version 14, if it matters), I define a procedure that uses a globally-defined expression in maple, but when I go to code generation, it assumes the variable is not what I am expecting.

a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)

What I expect is a C function with the expression inserted into the code, but instead I get...

double p (double x, double y)
{
  return(a);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欲拥i 2024-10-27 01:19:06

这是“设计”的事情之一。尽管在这种特殊情况下你可能会觉得很尴尬,但(现代)Maple 的这种词汇范围行为通常是一个优势,而且是经过深思熟虑的。有多种方法可以满足您的期望。

在这种情况下,最简单的解决方法可能就是这样:

restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

CodeGeneration:-C( subs('a'=a,eval(p)) );

  double cg (double x, double y)
  {
     return(x + y * x);
  }

上面完成的是 subs('a'=a,eval(p)) 形成 proc p 的一个新实例 其中 a 在 proc 主体中被 a 的显式值替换(即 a 的计算结果)。请注意以下输出,并与最初创建 p 时的上面输出进行比较,

subs('a'=a,eval(p));

   proc(x::float, y::float) return x + y*x end proc;

请记住,即使在这个非常简单的解决方法示例中并不明显,全局名称的给定替换将 xy 放入 p 的副本中实际上是在利用 Maple 的作用域规则玩一个棘手的游戏。在更复杂的范围界定情况下,这可能会变得疯狂。但如果您真正想要的是内联,那么您可以通过更明确和受控的方式来实现。查看在下一个示例中最初创建时 p 的回显输出,

restart:
a := proc(A,B) option inline; A+B*A: end proc;
          a := proc(A, B) option inline; A + B*A end proc;

p := proc(x::float, y::float) return a(x,y); end proc;
       p := proc(x::float, y::float) return x + y*x end proc;

CodeGeneration:-C( p );

   double p (double x, double y)
   {
     return(x + y * x);
   }

希望这两种方法足以帮助您完成任务。

让我们简单地回到原来的例子,只是为了注意一些事情。 a 值中出现的全局名称 xy 与两个形式参数的名称非常不同最初创建的过程p。它们是看似相同名称的完全不同的实例。考虑,

restart:
a:=x+y*x:

p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

p(4.0, 5.0);
                               x + y x

This is one of those 'by design' things. Even though it may seem awkward to you in this particular situation, this lexical scoping behaviour on (modern) Maple's part is more often an advantage and is quite deliberate. And there are several ways around it, to get your expectation.

The simplest workaround, in this case, might be just this:

restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

CodeGeneration:-C( subs('a'=a,eval(p)) );

  double cg (double x, double y)
  {
     return(x + y * x);
  }

What is accomplished above is that subs('a'=a,eval(p)) forms a new instance of the proc p in which a is replaced in the proc body by the explicit value of a (ie. what a evaluates to). Note the output of the following, and compare with the output above when p was initially created,

subs('a'=a,eval(p));

   proc(x::float, y::float) return x + y*x end proc;

Keep in mind that, even though it's not apparent in this very simple workaround example, the given substitution for the global names x and y into that copy of p is actually playing a tricky game with Maple's scoping rules. In more complicated scoping situations this might go amok. But if what you really want is inlining, then you can get that in more explicit and controlled ways. Look at the echoed output of p when initially created in this next example,

restart:
a := proc(A,B) option inline; A+B*A: end proc;
          a := proc(A, B) option inline; A + B*A end proc;

p := proc(x::float, y::float) return a(x,y); end proc;
       p := proc(x::float, y::float) return x + y*x end proc;

CodeGeneration:-C( p );

   double p (double x, double y)
   {
     return(x + y * x);
   }

Hopefully, those two approaches are enough to see you through.

Let's briefly return to your original example, just to notice something. The global names x and y as they appear in the value of a are very much not the same as the names of the two formal parameters of the initially created procedure p. They are quite different instances of what merely appear to be the same name. Consider,

restart:
a:=x+y*x:

p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

p(4.0, 5.0);
                               x + y x
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文