How to define a function with different types of arguments by setting conditions on function's domain?

I need help in order to properly define a function of $4$ variables.

Given that:

    beta[k_Integer /; k == 1] := {0.088, -0.029, -0.010, -0.029, 0.019, 0.012};
beta[k_Integer /; k >= 2] := {0.227, -0.098, -0.024, -0.060, 0.027, 0.000};
size = {"low", "medium", "high"};
type = {"a", "b", "c"};


The "incomplete" definition for my function f looks like this:

    f[k_Integer, x_, y_, z_] :=
Total[beta[k]*{1, Log[x], DiscreteIndicator[y, "medium", size],
DiscreteIndicator[y, "low", size],
DiscreteIndicator[z, "b", type], DiscreteIndicator[z, "a", type]}]


I'm using Table to iterate values of function's arguments:

    Table[f[k, x, y, z], {k, 1, 2}, {z, Reverse[type]}, {y, size}] // MatrixForm


The output result is:

   (* {{{0.059 - 0.029 Log[x], 0.078 - 0.029 Log[x],
0.088 - 0.029 Log[x]}, {0.078 - 0.029 Log[x], 0.097 - 0.029 Log[x],
0.107 - 0.029 Log[x]}, {0.071 - 0.029 Log[x], 0.09 - 0.029 Log[x],
0.1 - 0.029 Log[x]}}, {{0.167 - 0.098 Log[x],
0.203 - 0.098 Log[x], 0.227 - 0.098 Log[x]}, {0.194 - 0.098 Log[x],
0.23 - 0.098 Log[x], 0.254 - 0.098 Log[x]}, {0.167 - 0.098 Log[x],
0.203 - 0.098 Log[x], 0.227 - 0.098 Log[x]}}} *)


The problem is that the function f should not be defined for a specific combination of argument values:

    k=1  &&  y="low"    && z="b"
k=1  &&  y="high"   && z="b"
k=1  &&  y="medium" && z="a"
k=1  &&  y="high"   && z="a"
k>=2 &&  y="high"   && z="b"
k>=2 &&  y="medium" && z="a"
k>=2 &&  y="high"   && z="a"


The first condition is actualy saying that there are no "low" objects (or whatever) in the category "b", for k==1.

How can I define the function f exactly, so that f would not be defined for the conditions listed above?

I think that the solution is to restrict the domain of function f, by setting conditions on its arguments, but I have no idea how to do this.

This is what I ended up with (worst code ever):

    {{{f[1, x, "low", "c"], f[1, x, "medium", "c"],
f[1, x, "high", "c"]}, {"not defined", f[1, x, "medium", "b"],
"not defined"}, {f[1, x, "low", "a"], "not defined",
"not defined"}}, {{f[2, x, "low", "c"], f[2, x, "medium", "c"],
f[2, x, "high", "c"]}, {f[2, x, "low", "b"],
f[2, x, "medium", "b"], "not defined"}, {f[2, x, "low", "a"],
"not defined", "not defined"}}}


Output:

    {{{0.059 - 0.029 Log[x], 0.078 - 0.029 Log[x],
0.088 - 0.029 Log[x]}, {"not defined", 0.097 - 0.029 Log[x],
"not defined"}, {0.071 - 0.029 Log[x], "not defined",
"not defined"}}, {{0.167 - 0.098 Log[x], 0.203 - 0.098 Log[x],
0.227 - 0.098 Log[x]}, {0.194 - 0.098 Log[x], 0.23 - 0.098 Log[x],
"not defined"}, {0.167 - 0.098 Log[x], "not defined",
"not defined"}}}


I appreciate any suggestion.

Here is a solution :

 acceptableQ[k_, y_, z_] := Not[Or[
k == 1 && y == "low"    && z == "b",
k == 1 && y == "high"   && z == "b",
k == 1 && y == "medium" && z == "a",
k == 1 && y == "high"   && z == "a",
k >= 2 && y == "high"   && z == "b",
k >= 2 && y == "medium" && z == "a",
k >= 2 && y == "high"   && z == "a"]]

f1[k_Integer, x_, y_, z_] := "Undefined" /; Not[acceptableQ[k, y, z]]

f1[k_Integer, x_, y_, z_] :=
Total[beta[k]*{1, Log[x],
DiscreteIndicator[y, "medium", size],
DiscreteIndicator[y, "low"   , size],
DiscreteIndicator[z, "b"     , type],
DiscreteIndicator[z, "a"     , type]}
] /; acceptableQ[k, y, z]


Verification :

  Table[f1[k, x, y, z], {k, 1, 2}, {z, Reverse[type]}, {y, size}] //
Map[Column, #, {2}] & // Grid


gives :

Here are the corresponding inputs (just to help the reading) :

Note : You can also put the condition /; ... before the := :

f2[k_Integer, x_, y_, z_] /; Not[acceptableQ[k, y, z]] := "Undefined"
f2[k_Integer, x_, y_, z_] /; acceptableQ[k, y, z] := ...

• I feel stupid, cause your answer is simple. Is there a way to use negation of Exists so that the function returns some kind of a built-in output, instead of string character "Undefined"?
– bst
Oct 31, 2013 at 19:07
• I don't understand what you mean by "negation of Exists". In Mathematica Exists, like ForAll are special expressions (mathematical quantifier that goes with predicates) that are not usable here. Oct 31, 2013 at 19:17