Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Given a simple Gaussian kernel

UnscaledKernel[a_, b_, sigma_] := 
 Exp[-(((a - b)/sigma).((a - b)/sigma))/2]

and un-normalized smoothing function

Smooth[valCountLst_, val_, sigma_] := 
  Sum[valCountLst[[i]][[2]]*
    UnscaledKernel[{valCountLst[[i]][[1]]}, {val}, sigma], {i, 1, 
    Length[valCountLst]}];

and a normalization constant so that the integral on the defined domain is 1:

ScalingFactor[valCountLst_, sigma_, lower_, upper_] := 
 Integrate[
  Smooth[valCountLst, everyVal, sigma], {everyVal, lower, upper}]

From this unsmoothed data (that is, 1000 items at value 0 and 10 items at value 1):

testList = {{0, 1000}, {1, 10}};

I'm plotting smoothed (un-normalized) data takes 0.024 seconds:

Plot[N[Log[Smooth[testList, x, 0.2]]], {x, 0, 1.0}] // Timing

(output is {0.024, THEFIGURE}).

When plotting the smoothed, normalized data, it takes much longer, 13.09 seconds:

Plot[N[Log[
    Smooth[testList, x, 0.2]/ScalingFactor[testList, 0.2]]], {x, 0, 
   1.0}] // Timing

This seems strange since the scaling factor takes only 0.044 seconds to compute.

My conclusion is that Mathematica is computing the scaling factor for every point, even though it does not depend on the point value x.

Is there a way to help Mathematica compute this expression once and factor it out (or memoize it)?

Thanks a lot.

share|improve this question
add comment

2 Answers 2

up vote 5 down vote accepted

You could also use the Evaluated -> True undocumented option:

Plot[N[Log[Smooth[testList, x, 0.2]/ScalingFactor[testList, 0.2]]], 
      {x, 0, 1.0}, Evaluated -> True] 

Please note that I had modified your definition of ScalingFactor to

ScalingFactor[valCountLst_, sigma_] := Integrate[ Smooth[valCountLst, x, sigma], {x, 0, 1}]

because you're calling it with the wrong number of parameters in your question

share|improve this answer
add comment

Is there a way to help Mathematica compute this expression once and factor it out (or memoize it)?

I'd use With[], like so:

With[{sc = ScalingFactor[testList, 0.2]},
     Plot[Log[Smooth[testList, x, 0.2]/sc], {x, 0, 1}]
share|improve this answer
    
+1 Thanks, I used that elsewhere. –  Oliver Oct 9 '12 at 8:20
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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