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.

I have two sets of functions which I want to implement them in a single function with an option indicating which set of functions should be used.

Suppose that I have two lists like:(updated example)

b = {-1, 1, 0, 2}}
u = {{1, 1, 1, 1}, {1, 0, 0, 1}, {1, 0, 1, 1}, {0, 1, 1, 0}, {1, 0, 1,
1}, {0, 1, 0, 1}, {1, 0, 1, 0}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 1,
0, 0}}

and I have this function:

 AbEst[b0_, u0_, method_] := 
 Module[{t, b = b0, u = u0, l, a, pos, theta, dif, se},
  t = Table[i, {i, -4, 4, .01}];
  L[b_, t_, u_] := 
   Product[p[b[[i]], t]^u[[i]]*(1 - p[b[[i]], t])^(1 - u[[i]]), {i, 
     1, Length[u]}];
  p[b_, t_] := 1/(1 + Exp[-1.7*(t - b)]);
  l = L[b, t, #] & /@ u;
  a = PDF[NormalDistribution[0, 1], t];
  pos = Table[a, {Dimensions[u][[1]]}]*l;
  Which[method == "ML",
   theta = 
    t[[Position[l[[#]], Max[l[[#]]]][[1, 1]] & /@ 
      Range[Dimensions[u][[1]]]]],
   method == "MAP",
   theta = 
    t[[Position[pos[[#]], Max[pos[[#]]]][[1, 1]] & /@ 
      Range[Dimensions[u][[1]]]]],
   method == "EAP",
   theta = pos.t/Total[Transpose[pos]]];
  dif = (Table[t, {Dimensions[u][[1]]}] - 
      Partition[Flatten[Table[theta, {Length[t]}]], Length[t]])^2;
  Which[method == "ML",
   se = Sqrt[Total[Transpose[l*dif]]/Total[Transpose[l]]],
   method == "MAP",
   se = Sqrt[Total[Transpose[pos*dif]]/Total[Transpose[pos]]],
   method == "EAP",
   se = Sqrt[Total[Transpose[pos*dif]]/Total[Transpose[pos]]]];
  Return[Transpose[{theta, se}]]]

Now it returns {theta,se} for given method. I want to change it such that it returns theta by default (i.e. without computing se) and computes and returns {theta,se} if it was requested.

1) How can I do that?

2) How can I re-write more efficient function in which fits my purpose?

share|improve this question
    
I deleted my previous post because is not appropriate after your update. –  Kuba Jul 16 '13 at 6:17
    
Amin, your code example seems excessively long and only obfuscates the real issue under discussion. Please consider giving a shorter example. –  Mr.Wizard Aug 3 '13 at 6:49
    
@Mr.Wizard I chose the right solution and I'm done with this problem.I posted the whole code just to make it clear what I mean. –  Amin Aug 3 '13 at 14:34
add comment

1 Answer

up vote 4 down vote accepted

One possible way is using Switch as follows:

f[a_,b_,opts___?OptionQ]:=
    With[{t=method/.{opts}/.{method->1}},
        Switch[t,
        1,{a+b,a-b},
        2,{a*b,a/b}]]

In this definition, the default option is 1. Is this what you want?

In[7]:= f[a,b,method->2]

Out[7]={{10,30,60,100,150},{1/10,2/15,3/20,4/25,1/6}}

Updated:

You can combine the two Whichs together and add If condition to control whether the output includes se or not. For your case of different behaviors at different methods, I prefer Switch to Which in this case. The following is the outline of the code:

myAbEst[b0_, u0_, method_, opts___?OptionQ] :=
  Module[{t, b = b0, u = u0, l, a, pos, theta, dif, se, L, p, 
         op = Se /. {opts} /. {Se -> False}}, 
(*op is the option that can control whether se should be output.The default is not.*)
  ...(*Your code about the assignments and definitions*)
  Switch[method,
   "ML", theta=(*your code*);If[op,dif=(*your code*);se=(*your code*)],
   "MAP", theta=(*your code*);If[op,dif=(*your code*);se=(*your code*)],
   "EAP", theta=(*your code*);If[op,dif=(*your code*);se=(*your code*)]];
  If[op,Transpose[{theta, se}], theta]]

By the way, functional program always returns the value of the last expression. You don't need to use Return to return values.

myAbEst[b,u,"ML"](*This is the default case, which won't return se.*)
myAbEst[b,u,"ML",Se->True](*This is the case that returns se.*)
share|improve this answer
    
I think this might work. Please take a look at updated example.It's more clear. –  Amin Jul 16 '13 at 1:20
    
@Amin Please see the updates. –  Z-Y.L Jul 16 '13 at 5:17
    
that's wonderful!it works well except that in default mode it returns theta's with a Null` attached to them but it's solved by adding ; after Swich –  Amin Jul 16 '13 at 16:45
    
I also saved the whole function as a package but the option for Se doesn't work there, why?? –  Amin Jul 16 '13 at 16:47
    
@Amin You're right! I forgot to add ; at the end. I have corrected it. By the way ,can I have a look at how you wrote your package? You can't just save as Mathematica package. You have to create a new package document by File->New->Package.Or if the format style of the code that you want to write to a package in your notebook is Code(the shortcut is Alt+8), then you can save as a Mathematica package. –  Z-Y.L Jul 17 '13 at 9:56
show 3 more comments

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.