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 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.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

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] := ...
share|improve this answer
    
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 '13 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. –  andre Oct 31 '13 at 19:17

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.