2
$\begingroup$

I am trying to convert my Mathematica code to C since it can sometimes takes the Mathematica code quite a while to execute since the arrival times lists are hundreds of thousands of counts long, and am looking to reduce computational time, but I am a little rusty on my C. I see that there is "CForm" but I don't really understand it, or how it might be used. (For reference, I am using a Windows computer, and use MobaXterm.)

When I originally wrote my Mathematica code, I used an example data set to make sure that I could get everything running smoothly, however I used BinLists and BinCounts when writing the code, and am not entirely sure how to convert these built-in Mathematica symbols to C code.

The sample data I used to originally make the Mathematica code was:

dat = {0,1,3,9,11,13,14,15,19,20};

I wanted to have each bin be a constant width, currently set at 5, so the number of bins was found using:

numBins = (Max[dat] - Min[dat])/width

To get my intervals, I wrote:

intervals = Table[0,2*numBins];
intervals[[1]] = min;
For[i = 2, i < 2*numBins, i+=2, intervals[[i]] = intervals[[i-1]] + width; intervals[[i+1]] = intervals[[i]]] 
intervals[[2*numBins]] = intervals[[2*numBins - 1]] + width;

which gets me:

{0, 5, 5, 10, 10, 15, 15, 20}

which is exactly what I'm looking for. Now, I know that for the bins, I should get:

0-5, 5-10, 10-15, 15-20 (intervals)

0    9     11     19    (elements in bins)
1          13     20
3          14        
           15

3    1     4      2     (number of elements in each bin)

What I originally wrote, which gets me what I want, was:

intvalOG = Table[0, numBins + 1];
intvalOG[[1]] = min;
For[i = 2, i < numBins + 1, i++, intvalOG[[i]] = intvalOG[[i - 1]] + width]
intvalOG[[numBins + 1]] = intvalOG[[numBins]] + \[CapitalDelta]t;

intvalINC = Table[intvalOG[[i]] + 1, {i, 2, numBins + 1}];
intval = Prepend[intvalINC, min];

elements = BinLists[dat, {intval}]
gn = BinCounts[dat, {intval}]

This gives me a list where gn contains the values:

{3, 1, 4, 2}

Now, I have everything coded in C up to when I try to get my elements and gn arrays, and I am stumped in how to convert those over from Mathematica to C. I have a minmax function, that finds the min and max values of my data,

double minmax(const double *arr, size_t length){
size_t i;
min = arr[0];
for(i = 1; i < length; i++){
if(min > arr[i]){min = arr[i];}
if(maxOG < arr[i]){maxOG = arr[i];}}
return 0;}

and all the Tables were converted straight to for loops, and indices were changed a bit to account for starting at 0 rather than with 1:

int main(){
minmax(dat,datLength);
numBins = ceil((maxOG-min)/width);

double intervals[8];
intervals[0] = min;

for(int j = 1; j < 2*numBins; j+=2){
intervals[j] = intervals[j-1] + width;
intervals[j+1] = intervals[j];}

double tn[8];
int count = 0;
for(int j = 0; j < 2*numBins; j+=2){
tn[count] = (intervals[j]+intervals[j+1])/2;
count++;}

double intvalOG[5];
intvalOG[0] = min;
for(int j = 1; j < numBins + 1; j++){
intvalOG[j] = intvalOG[j-1] + width;}

My attempt at rewritting it looked like:

double gn[4];
int count = 0;

for(int i =0; i < datLength; i++){
for(int j = 0; j < 5; j++){
if(dat[i] <= intvalOG[j]){
count++;}
gn[j] = count;}
count = 0;}

but all this ended up printing out was:

{0.000000 0.000000 0.000000 0.000000 1.000000 }

so clearly I'm doing something wrong here, I'm guessing with the count.

tl;dr: Any advice for how to convert BinLists and BinCounts into C code would be appreciated. If there is a more appropriate stackexchange to post this to, please feel free to comment.

$\endgroup$
  • 1
    $\begingroup$ For questions regarding writing C code, Stack Overflow may work better. $\endgroup$ – user202729 Nov 20 '18 at 5:57
  • 3
    $\begingroup$ I'm voting to close this question as off-topic because it is about how to implement histogramming in C, i.e. unrelated to Mathematica. $\endgroup$ – Szabolcs Nov 20 '18 at 9:09
  • $\begingroup$ Okay! I was wondering if there was a better place to put this as stated in the original problem, so thank you for informing me. $\endgroup$ – Jomy Blue Nov 20 '18 at 14:29
  • $\begingroup$ Take a look at this, maybe you will find it helpful: web.archive.org/web/20140420075011/https://… $\endgroup$ – Szabolcs Nov 20 '18 at 16:33
  • $\begingroup$ There is also this: mathematica.stackexchange.com/a/96395/12 A BinCounts alternative implemented in C++, and usable from Mathematica. $\endgroup$ – Szabolcs Nov 20 '18 at 16:38
5
$\begingroup$

You seem to be working so hard for such a simple problem.

dat = {0, 1, 3, 9, 11, 13, 14, 15, 19, 20};

HistogramList[dat, {5}]

(* {{0, 5, 10, 15, 20, 25}, {3, 1, 3, 2, 1}} *)

$\endgroup$
  • $\begingroup$ You don't seem to address the question which is "I am looking to reduce computational time". This is less symbols to type, but is this faster? $\endgroup$ – Winther Nov 20 '18 at 8:38
  • $\begingroup$ So I looked HistogramList up, and I found a GitHub page and a Nevis at Columbia page, and both had '#include "Histogram.H"' in them, I tried modelling after them but I am not certain I understand how to implement HistogramList! Sorry to bother, but do you think you could explain that to me? $\endgroup$ – Jomy Blue Nov 20 '18 at 14:40
  • $\begingroup$ Nevermind, I figured something out. Thanks a lot for the comment. $\endgroup$ – Jomy Blue Nov 20 '18 at 15:23

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