0
$\begingroup$

I have some code that performs a calculation. I want to make a function out of it so I wont have to cut and paste to calculations with different values of a, b and f[x]


Here is my calculation:

ClearAll[a, b, f, j, k, m, n, o]
f[x_] := k x^2;
a = 0;
b = 4;
j = Solve[Integrate[f[x], {x, a, b}] == 1 && k > 0, k];
k = k /. j[[1]];
m = Integrate[f[x] x, {x, a, b}];
n = Integrate[f[x] (x - m)^2, {x, a, b}];
o = Sqrt[%];
Print["For a=", a, " and b=", b, " and f(x)=", 
 f[x], ",  the mean is ", m, ", k is ", k, ", standard deviation is \
", Sqrt[n], ", and variance is ", n, "."]
Plot[f[x], {x, If[a == Infinity, 1000, a], 
  If[b == Infinity, 1000, b]}, 
 Epilog -> {Line[{{m, 0}, {m, f[m]}}], 
   Line[{{m - o, 0}, {m - o, f[m - o]}}], 
   Line[{{m + o, 0}, {m + o, f[m + o]}}]}]

A similar question suggested that I use Module, but I don't know exactly to do. Which variables should I give in the first argument?

I tried the following but it does not work.

probabilityplot[s_, t_, fri_] := Module[{a, b, f, j, m, n, o},
  ClearAll[a, b, f, j, k, m, n, o]
    f[x_] := fri;
  a = s;
  b = t;
  j = Solve[Integrate[f[x], {x, a, b}] == 1 && k > 0, k];
  k = k /. j[[1]];
  m = Integrate[f[x] x, {x, a, b}];
  n = Integrate[f[x] (x - m)^2, {x, a, b}];
  o = Sqrt[%];
  Print["For a=", a, " and b=", b, " and f(x)=", f[x], 
    ",  the mean is ", m, ", k is ", k, ", standard deviation is ", 
    Sqrt[n], ", and variance is ", n, "."]
   Plot[f[x], {x, If[a == Infinity, 1000, a], 
     If[b == Infinity, 1000, b]}, 
    Epilog -> {Line[{{m, 0}, {m, f[m]}}], 
      Line[{{m - o, 0}, {m - o, f[m - o]}}], 
      Line[{{m + o, 0}, {m + o, f[m + o]}}]}]
  ]

probabilityplot[0, 4, k *x^2]

SetDelayed::write: Tag Times in Null f\$1252[x\$_] is Protected. >>
Part::partw: Part 1 of {} does not exist. >>
ReplaceAll::reps: {{}[[1]]} is neither a list of replacement rules nor a valid dispatch table, and so cannot be used for replacing. >>
\$RecursionLimit::reclim: Recursion depth of 1024 exceeded. >>
Integrate::ilim: Invalid integration variable or limit(s) in {Indeterminate,0,4}. >>
\$RecursionLimit::reclim: Recursion depth of 1024 exceeded. >>

output


I do not know what all the messages means. Please help.

$\endgroup$

closed as off-topic by m_goldberg, anderstood, Coolwater, Henrik Schumacher, LCarvalho Feb 19 '18 at 14: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.

  • $\begingroup$ Usually, the first error message is indicative of trying something weird or really involved; in this case, you are missing a semicolon after ClearAll (which is not needed, as a module defines its own context and localizes variables to that context); also, you need another semicolon after Print; the If statements in the Plot I think need to be wrapped with Evaluate or alternatively, move the If outside of Plot. $\endgroup$ – yosimitsu kodanuri Feb 16 '18 at 3:49
  • $\begingroup$ Lastly, replace the % inside Module with n. $\endgroup$ – yosimitsu kodanuri Feb 16 '18 at 3:52
  • 1
    $\begingroup$ Related: mathematica.stackexchange.com/questions/11982/… $\endgroup$ – Michael E2 Feb 16 '18 at 4:49
  • $\begingroup$ What "similar question" exactly? $\endgroup$ – Michael E2 Feb 16 '18 at 4:49
  • 4
    $\begingroup$ I'm voting to close this question as off-topic because it is too localized; i.e, it applies only to the local situation and needs of its poster and answers will not benefit others. $\endgroup$ – m_goldberg Feb 16 '18 at 11:28
1
$\begingroup$

There seem to be a number of minor issues with the code in the question. I address some of them in the comments.

The main issue is the attempt to define a local function, as in

probabilityplot[s_, t_, fri_] := Module[{},
  f[x_] := fri; 
  ...
 ]   

This does not work, as expected. I'm not sure how to make it work as it should, but I managed to repair the code nevertheless

(* added Block to localize k - I understand it's awkward *)
Block[{k},
 probabilityplot[s_, t_, fri_] := Module[{a=s, b=t, f, j, m, n, o},
   (* ClearAll[a,b,f,j,k,m,n,o] - not necessary *) 

   f[x_] := fri;

   (* following two assignments not necessary *)
   (* a = s; *)
   (* b = t; *)

   (* Integrate works when fri is a function of x *)
   j = Solve[Integrate[f[x], {x, a, b}] == 1 && k > 0, k];

   (* k is a parameter of fri *)
   k = k /. j[[1]] // N;

   (* k is now equal to a value - again Integrate works when fri is a function of x *)
   m = Integrate[f[x] x, {x, a, b}] // N;
   n = Integrate[f[x] (x - m)^2, {x, a, b}] // N;
   o = Sqrt[n];

   Print["For a=", a, " and b=", b, " and f(x)=", f[x], ",  the mean is ", m, ", k is ", k, ", standard deviation is ", o, ", and variance is ", n, "."] ;

   (* If's don't seem to be a problem *)
   Plot[f[x], {x, If[a == Infinity, 1000, a], If[b == Infinity, 1000, b]},
    (* replaced calls to f with rule replacement; f[x] does not evaluate to what one would expect *)
    Epilog -> {
      Line[{{m, 0}, {m, f[x] /. x -> m}}],
      Line[{{m - o, 0}, {m - o, f[x] /. x -> m - o}}],
      Line[{{m + o, 0}, {m + o, f[x] /. x -> m + o}}]
      }
    ]
   ]
 ]

Evaluating

(* need to clear k every time otherwise Solve complains *)
Clear[k]
probabilityplot[0, 4, k*x^2]

produces

For a=0 and b=4 and f(x)=0.046875 x^2, the mean is 3., k is 0.046875, standard deviation is 0.774597, and variance is 0.6. enter image description here


how I'd have done it

(* performs integration*)
integrate[f_, arg_, argMin_, argMax_] := 
  integrate[f, arg, argMin, argMax] = Integrate[f, {arg, argMin, argMax}]

(* solves for *the* parameter - it can handle a single parameter *)
solve[f_, param_, arg_, argMin_, argMax_] := 
  solve[f, param, arg, argMin, argMax] = 
    Solve[1. == integrate[f, arg, argMin, argMax] && param > 0, param]

(* output plot *)
probabilityPlot[f_, param_, arg_, argMin_, argMax_] := 
  Module[{paramSol, paramVal, fVal, mean, var, stdev, text, vals, lowerBound, upperBound, lines},

    paramSol = solve[f, param, arg, argMin, argMax][[-1]];
    paramVal = param /. paramSol;
    fVal = f /. paramSol;

    mean = integrate[fVal arg, arg, argMin, argMax];
    var = integrate[fVal (arg - mean)^2, arg, argMin, argMax];
    stdev = Sqrt[var];

    {lowerBound, upperBound} = Which[# == Infinity, 1000, True, #] & /@ {argMin, argMax};

    text = {"For a=", " and b=", " and f(x)=", ",  the mean is ", ", k is ", ", standard deviation is ", ", and variance is ", "."};
    vals = {argMin, argMax, f, mean, paramVal, stdev, var};

    lines = Line[{{arg, 0.}, {arg, fVal}}] /. {
       {arg -> mean},
       {arg -> mean - stdev},
       {arg -> mean + stdev}
     };

    Print[Row[Riffle[text, vals]]];

    Plot[
     fVal,
     {arg, lowerBound, upperBound},
     Epilog -> lines
    ]

 ]

Evaluating

probabilityPlot[k s^2, k, s, 0, 4]

produces

For a=0 and b=4 and f(x)=k s^2, the mean is 3., k is 0.046875, standard deviation is 0.774597, and variance is 0.6. enter image description here

$\endgroup$
  • $\begingroup$ Much appreciated. Its my first time using Module and I think I will be using it a lot, and I now have something to refer to. It's much easier to learn if you understand what is being achieved in a code. I'll also try to incorporate your style of doing the process. $\endgroup$ – tighten Feb 17 '18 at 1:36
  • $\begingroup$ Much appreciated. Its my first time using Module and I think I will be using it a lot, and I now have something to refer to. It's much easier to learn if you understand what is being achieved in a code. I'll also try to incorporate your style of doing the process. $\endgroup$ – tighten Feb 17 '18 at 1:36

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