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$

closed as off-topic by Szabolcs, yode, C. E., Kuba Nov 20 '18 at 12:00

  • The question does not concern the technical computing software Mathematica by Wolfram Research. Please see the help center to find out about the topics that can be asked here.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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.