3
$\begingroup$

The first part below is already answered, but I've got another question which I think is closely related to this one, so I edited my question.

First part: I started compiling in Mathematica a few weeks ago. In the code below, I want to put the integer value 0 into the list "Pre". If I "Print" the list, it will look like {0,0,....,0}. But the output of the code is {0.,0.,0.,....,0.}. So, my question is, how can I manage it, that the output looks like the "Print", i.e. I want the list to have integer values and not real numbers.

In[1]:= CInit = Compile[{{v0, _Integer, 0}, {s0, _Integer, 0}},
          Module[{s = s0, v = v0, d, Pre},
          d = Table[$MaxMachineNumber, {v}];
          Pre = Table[0, {v}];
          Print[Pre];
          d[[s]] = 0.;
          {d, Pre}
          ], CompilationTarget -> "C"];
        CInit[5, 1]

 During evaluation of In[1]:= {0,0,0,0,0}

 Out[2]= {{0., 1.79769*10^308, 1.79769*10^308, 1.79769*10^308, 
         1.79769*10^308}, {0., 0., 0., 0., 0.}}

Second part:

If I have an empty list and I want to put Integers into it, how can I let Mathematica know that it is a list of Integers and not Reals? I tried to manage this with the third argument in Compile, but that didn't work. For example:

In[22]:= CTest = Compile[{{s, _Integer}}, Module[{Perm = {s}},
         Perm = {};
         Append[Perm, 1]
         ], {{Perm, _Integer, 1}}, CompilationTarget -> "C"]

Compile::cset: Variable Perm of type {_Integer,1} encountered in assignment of type >{_Real,1}. >>

Compile::cset: Variable Perm of type {_Integer,1} encountered in assignment of type >{_Real,1}. >>

I can avoid this error by doing this rather unnecessary thing below:

In[25]:= CTest = Compile[{{s, _Integer}}, Module[{Perm = {s}},
         Perm = Delete[Perm, 1];
         Append[Perm, 1]
         ], CompilationTarget -> "C"]

So, is there another way to tell Mathematica that Perm is a list of Integers without doing it like in the last example?

Thanks in advance!

$\endgroup$
8
  • 3
    $\begingroup$ Using Compile, you can't return a list where sublists are of different type, so integers are converted into reals. This is one of the limitations of Compile. To some extent, you can alleviate this by some kind of post-processing of the result, e.g. MapAt[Round, CInit[5, 1], 2]. $\endgroup$ Commented Apr 3, 2013 at 10:16
  • 1
    $\begingroup$ In short: since $MaxMachineNumber is not an integer, a conversion of your list to have entirely real entries is performed. To compare, try replacing $MaxMachineNumber with some other integer. $\endgroup$ Commented Apr 3, 2013 at 10:32
  • $\begingroup$ It seems when the compiled function returns an array it is always made homogeneous. One float and the whole thing is cast as float. Makes sense, but really how hard would it be for the good folks at wolfram to just say that in the docs..? $\endgroup$
    – george2079
    Commented Apr 3, 2013 at 14:01
  • $\begingroup$ Thanks for your help @Leonid Shifrin. The "MapAt"-function helped me a lot. $\endgroup$
    – Carolin
    Commented Apr 6, 2013 at 18:14
  • 4
    $\begingroup$ You can use Perm = Most@{0} to create an empty list of integer type. $\endgroup$ Commented Jun 18, 2013 at 20:02

1 Answer 1

4
$\begingroup$

Regarding the second part of the question, you can use Most@{0} to create an empty list of integer type:

CTest = Compile[{{s, _Integer}},
  Module[{Perm = Most@{0}}, Append[Perm, 1]],
  CompilationTarget -> "C"]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.