Stephen Forrest

Mr. Stephen Forrest

451 Reputation

13 Badges

18 years, 7 days
Maplesoft
Software Architect

Social Networks and Content at Maplesoft.com

Maple Application Center

MaplePrimes Activity


These are answers submitted by Stephen Forrest

I haven't encountered this particular message before. Can you be more specific about the circumstances in which you saw it? What was the Maple command or Maplet that you ran?
Unfortunately what you'd like to see isn't easily possible, because Maple (like most programming languages) ignores comments when interpreting the source:
> p := proc(b)
   2*b;
   # or not to be, that is the question
end proc:
> eval(p);
                     proc(b) 2*b end proc
Joe's post offers the easiest solution, using a function called 'comment' which you can embed in the source. Joe, Print:-Comment merely takes a string and returns a string formatted in the appropriate way for comments in the given languages: in the case of C, it prepends the '#' and does linebreaking. Here's your example rewritten to use Print:-Comment:
use CodeGeneration in
    LanguageDefinition:-Define(
        "C_with_comments_2"
        ,extend = "C"
        ,AddFunction("comment", anything::anything
                     ,proc(s)
                          Printer:-Print(Printer:-Comment(s))
                      end proc));
    Translate(fn, language = "C_with_comments_2");
end use;
Note this by itself does not succeed in getting rid of the semicolon, because the you're still printing a function call, which is inside a statement, which in general ends in a semicolon. If one really wanted to get around it, one could override Names:-Statement for this new language to handle the special case when the statement body was a Function with the name "comment", but that would probably be overkill.
If Maple were capable of generating C code that could perform calls to evalf/Int successfully, I expect it would be done in one of three ways:
  1. Maple would generate specific C code for evaluating this particular problem numerically
  2. Maple would generate C code with a call into some external C library
  3. Maple would generate C code with a callback to itself (probably via OpenMaple)
In order to do task 1) and faithfully mirror Maple's behaviour, Maple would probably have to perform some sort of partial evaluation of its routines for numerical integration. Implementing such a thing would be a challenging problem. At the least, the C code one is generating would (in general) require access to a C library for infinite-precision floating-point arithmetic, and any divergences between this library's implementation and Maple's (say, in the base of the representation) might lead to differences between Maple's behaviour and that of the generated code. Either of the solutions 2) or 3) introduces a dependency on an external library, either on Maple or some other library capable of doing numerical integration. The existing CodeGeneration translators are designed to generate code that can be executed independently of Maple and its libraries. In any case, it sounds like what you would like is C code that could be executed independently of Maple, just using normal C double-precision floats. In that case, the simplest solution is probably, as others have suggested, to find a stable approximation to your integral in terms of functions expressible in C (e.g. polynomials, trig functions), generate an evaluation procedure from that using unapply, and then apply CodeGeneration:-C to that.
Hello Amanda, The problem is this: the information from your very first assumption on x, assume(mylist[1]);, is getting written into newlist. This means that what is happening when you proceed through the list the second time is that you're testing against the first assumption (x<3) rather than second (x>0). The solution for this is simple: just after building the table anode, and before assigning to newlist, add the line.
x := 'x';
to remove the assumption on x. The technical reason for your problem is that, whenever you make an assumption in Maple, what Maple really does is to introduce a new variable (an “escaped local”, for those who know what that is) which contains the assumption information, and causes the variable to point at this new variable. When you make a new assumption with 'assume', a new escaped local is created, and the variable is reset to point at that. In the above example, because 'x' still pointed at the variable corresponding to the first assumption, the list newlist was being filled with that information. Once the assumption is removed, newlist will only contain references to 'x', which means that when a new assumption is added, references to newlist use that new assumption. By the way, you don't need to write
if is(mylist[i]) then
    anode[i]:=true;
else
    anode[i]:=false;
end if;
since the result of is(mylist[i]) is a boolean, you can just write:
anode[i] := is(mylist[i]);
Here's your program again, with the assumption removal added and a few minor simplifications.
mylist:=[x < 3, x < 9, x > 0, x > 1/2, x < 2, x > -4];
N := nops(mylist);
interface(showassumed=0):
printlevel:=4:

assume(mylist[1]);
for i from 2 to N do
    anode[i] := is(mylist[i]);
end do;
x := 'x'; # remove assumption on x
newlist := [mylist[1]];
newlist := [op(newlist), seq(`if`(anode[i]=false, mylist[i], NULL), i=2..N)];
mylist := newlist;

assume(mylist[2]);
for i from 3 to N do
    anode[i] := is(mylist[i]);
end do;
x := 'x'; # remove assumption on x
newlist := [mylist[1], mylist[2]];
newlist := [op(newlist), seq(`if`(anode[i]=false, mylist[i], NULL), i=3..N)];
mylist := newlist;
I edited the post by Amanda (as a moderator, I have permissions to do this) to change the posting mode, because the original version was posted as HTML and the use of < and > signs had mangled the display. Somehow, this caused me to be marked as the author of the post. I would consider that to be a bug.
1 2 3 Page 3 of 3