1
$\begingroup$

I've been struggling to make the Which command more efficient. Below is my original code:

fitmodel[set_, k1_, k2_, k3_, k4_, k5_, m_, n_][t_] := 
 Which[set == 1, Evaluate@model[1][k1, m, n][t], set == 2, 
  Evaluate@model[2][k2, m, n][t], set == 3, 
  Evaluate@model[3][k3, m, n][t], set == 4, 
  Evaluate@model[4][k4, m, n][t], set == 5, 
  Evaluate@model[5][k5, m, n][t]]

I Prepend the set number in front of my data and use this fitmodel to assign different model to different data. Since it's very inconvenient to change this fitmodel whenever I have different numbers of kinetic constants(k1,k2,...kn), I'm trying to make the code easier to handle. I tried the following:

args = Append[
   Append[Prepend[
     Table[ToExpression["k" <> ToString[i] <> "_"], {i, 1, 
       Length@allNames}], ToExpression["set_"]], ToExpression["m_"]], 
   ToExpression["n_"]];

k = Flatten[{set == #, 
      Evaluate@model[#][ToExpression["k" <> ToString[#]], m, n][t]}&/@Range@5, 2];

fitmodel[args][t_] := Which[Sequence@@k]

But it failed and the error message is:

Which::argctu: Which called with 1 argument. >>

I checked the output of "k" and it's exactly the same as my original code inside Which command. Then I used "Sequence@@k" to get rid of the curly bracket. So I thought it should work. Obviously I'm wrong and I couldn't come up with a solution to this issue. Hope someone could guide me forward. Thank you!!

$\endgroup$
6
$\begingroup$

It seems that set is the index you need for your $k_i$ in your model. If this is the case then you don't need Which.

ClearAll[fitmodel];
fitmodel[set_, k_List, m_, n_][t_] := model[set][k[[set]], m, n][t]

fitmodel could then be called with as many $k_i$ as needed as they are contained in a list. You just need to add additional $k_i$ to the list.

kVars = {k1, k2, k3, k4, k5};
fitmodel[s, kVars, m, n][t]

Hope this helps.

$\endgroup$
  • $\begingroup$ Thank you @Edmund ! It's indeed a much better way to deal with the problem. But I'm getting the following error Part::pkspec1: The expression set cannot be used as a part specification Could you please help me a bit more on this issue? Thanks again! $\endgroup$ – DavidC Aug 3 '16 at 6:03
  • 1
    $\begingroup$ @DavidC It is due to the Evaluate that you have in the function. I don't think you need that as you are forcing it to resolve before it has any values. $\endgroup$ – Edmund Aug 3 '16 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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