1

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.

Illari
  • 399
  • 1
  • 9
  • 1
    For questions regarding writing C code, [so] may work better. – user202729 Nov 20 '18 at 05:57
  • 3
    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. – Szabolcs Nov 20 '18 at 09:09
  • 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. – Illari Nov 20 '18 at 14:29
  • Take a look at this, maybe you will find it helpful: https://web.archive.org/web/20140420075011/https://community.wolfram.com/groups/-/m/t/237660 – Szabolcs Nov 20 '18 at 16:33
  • There is also this: https://mathematica.stackexchange.com/a/96395/12 A BinCounts alternative implemented in C++, and usable from Mathematica. – Szabolcs Nov 20 '18 at 16:38
  • Oh interesting, I'll have to give that the time to look through properly. I appreciate you linking this a lot, thanks. – Illari Nov 20 '18 at 16:41
  • Possibly, but I'm working with large lists, and I see the original poster mentioned about 500 list entries. My lists range from 1500 to 20000 entries, and what's slowing me down is BinCounts and the evaluation of the periodogram, so depending on how it scales, it could save me a bit of time, I'm thinking? I'll try seeing if I can't incorporate something similar to what you wrote. Nevertheless, I appreciate the link. – Illari Nov 20 '18 at 16:50

1 Answers1

5

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}} *)

David G. Stork
  • 41,180
  • 3
  • 34
  • 96
  • 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? – Winther Nov 20 '18 at 08:38
  • 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? – Illari Nov 20 '18 at 14:40
  • Nevermind, I figured something out. Thanks a lot for the comment. – Illari Nov 20 '18 at 15:23