1
$\begingroup$

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.

$\endgroup$
4
$\begingroup$

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 :
enter image description here

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

enter image description here

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] := ...
$\endgroup$
  • $\begingroup$ 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"? $\endgroup$ – bst Oct 31 '13 at 19:07
  • $\begingroup$ 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. $\endgroup$ – andre314 Oct 31 '13 at 19:17

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.