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$

1 Answer 1

5
$\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$
2
  • $\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, 2013 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, 2013 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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