2
$\begingroup$

So I have a matrix (technically a table)

     points = Table[{x, f[x]}, {x, Range[0, 2, .1]}];

Which gives something like this in matrixform

\begin{array}{cc} 0. & 1. \\ 0.1 & 0.99 \\ 0.2 & 0.960013 \\ 0.3 & 0.910219 \\ 0.4 & 0.841638 \\ \end{array}

Lets call values in the first column $v$ and values in the second column $w$ Now I want to define a function $g(x)$ that checks the value every row in the second column (the $w's$ (1,.99,.960013...)) to see if $.5x \leq w \leq .5(x+1)$ and when this is true I want it to define a third function $h$ with $h(v) = .5(x+1)$ and leave $h$ undefined everywhere else. (note that v should be from the row whose second column satisfied the inequality: i.e. v and w should be from the same row)

Any ideas on how to do this (perhaps I can figure out how to define $h$, but I don't know how to have $g$ check EVERY row of the second column for EVERY $x$ that $g(x)$ is evaluated at).

I imagine g will be something like

    g[x_]:= If[.5x<=(check all values of second column here)<=.5(x+1), 
    h(corresponding v) = .5*(x+1), Undefined] /;  Element[x, Reals]

Where I have Element[x,Reals] because I want to restrict x (although I will likely restrict it to something like {0,1,2,3,4,5....,100}

$\endgroup$
3
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Commented Oct 7, 2015 at 2:11
  • $\begingroup$ I'm confused on some points. First, g should have no output? I.e. it's sole purpose is to set the values for h? Secondly, it seems like in the general case, h for a particular v could be set to different values, since you scan over possible x's. Either the list is such that this doesn't happen, or you want to define an h for every x. I'm not sure which it is. (Or some third option based on my misunderstanding of the problem.) $\endgroup$
    – march
    Commented Oct 7, 2015 at 2:57
  • $\begingroup$ For your first question: yes, I guess g would have no output (I've tried having g be h, if that makes sense, but I couldn't find a way to make that work). Secondly, I think you may be correct. However, if I make the $\leq$ be $<$ then no $h(v)$ (h for no v) can be set to two different values (although different v's could give the same h(v) which I am okay with). It is also very possible that I incorrectly articulated my idea. Thirdly, thank you for your comment. $\endgroup$
    – majmun
    Commented Oct 7, 2015 at 4:58

3 Answers 3

2
$\begingroup$

If my interpretation of your question is right (and that is quite uncertain), then the following definition of g should work for you. If my interpretation is wrong, perhaps this will help you to revise your question, so that a correct interpretation might more obvious. Note that I had to generate my own array for points since you did not provide one.

With[{points = Table[{x, 1./(1. + .5 x)}, {x, 0, 2, .1}]}, 
  g[x_Real, h_Symbol] :=
    (If[0. <= 2. #[[2]] - x <= 1., h[#[[1]]] = .5 x + .5] & /@ points;)]

With this, evaluating g for various values of x gives

Clear[a]; g[0., a]; DownValues[a]
{HoldPattern[a[2.]] :> 0.5}
Clear[b]; g[.5, b]; DownValues[b]
{HoldPattern[b[0.7]] :> 0.75, HoldPattern[b[0.8]] :> 0.75, 
 HoldPattern[b[0.9]] :> 0.75, HoldPattern[b[1.]] :> 0.75, 
 HoldPattern[b[1.1]] :> 0.75, HoldPattern[b[1.2]] :> 0.75, 
 ...
 HoldPattern[b[1.9]] :> 0.75, HoldPattern[b[2.]] :> 0.75}
Clear[c]; g[1., c]; DownValues[c]
{HoldPattern[c[0.]] :> 1., HoldPattern[c[0.1]] :> 1., 
 HoldPattern[c[0.2]] :> 1., HoldPattern[c[0.3]] :> 1., 
 HoldPattern[c[0.4]] :> 1., HoldPattern[c[0.5]] :> 1., 
 ...
 HoldPattern[c[1.9]] :> 1., HoldPattern[c[2.]] :> 1.}
Clear[d]; g[1.5, d]; DownValues[d]
{HoldPattern[d[0.]] :> 1.25, HoldPattern[d[0.1]] :> 1.25, 
 HoldPattern[d[0.2]] :> 1.25, HoldPattern[d[0.3]] :> 1.25, 
 ...
 HoldPattern[d[0.5]] :> 1.25, HoldPattern[d[0.6]] :> 1.25}
Clear[e]; g[2., e]; DownValues[e]
{HoldPattern[e[0.]] :> 1.5}

The discrete functions a, b, c, d, e all have the value of 5{x + 1) for each value of points[[i, 1]] where points[[i, 2]] satisfies your inequality for the given x.

Update

I write this to address an issue raised in a comment below. It appears that my use of concise operator notation is confusing. I will rewrite g, spelling out all the non-arithmetic operators appearing in its body. This will make it easy for anyone working out how g operates to look up its constituent functions in the docs to get more info.

With[{points = Table[{x, 1./(1. + .5 x)}, {x, 0, 2, .1}]},
  g[x_Real, h_Symbol] :=
    Map[
      Function[{pt}, 
        If[LessEqual[0., 2. Part[pt, 2] - x, 1.], h[Part[pt, 1]] = 0.5 + 0.5 x]],
      points];]

Map takes two arguments (ignoring level specs for now), the 1st a being a function of one variable (here a pure function) and the 2nd being a list (here points). It calls the function once for each element in the list, binding the formal argument pt to the list element. Hence, for each call pt is bound to one of the pairs {v, w} from the list. Therefore, Part[pt, 1] is v and Part[pt, 2] is w.

$\endgroup$
1
  • $\begingroup$ I think this is exactly what I want. However, I am confused about something (pardon me if this is an obvious question): how are the values in the table (specifically columns) being referenced? It seems that this is being done, but I don't see how? Is the table being referenced by #[[1]], #[[2]]? If so, why are these referencing the table and not x_real, h_Symbol. Is it because the double brackets? Also, I don't have access to Mathematica right now, but I will try this out in the next few days and mark this as an answer if it works (I believe it will). Thank you very much. $\endgroup$
    – majmun
    Commented Oct 7, 2015 at 5:30
1
$\begingroup$

I was going to do something similar to m_goldberg, but since he has already done that, I'll add a version that uses an Association instead of assigning DownValues, which could be a problem if there are many assignments.

Our sample list:

points = Transpose@{Range[0, 1, 0.1], RandomReal[{0, 1}, 11]}

enter image description here

Then, we define the function g that assigns the values to h, which takes the form of an Association:

Clear[h, g]
h = Association[];
g[x_] := Module[{}
  , AppendTo[h, x -> Association[]]
  ; Scan[
   If[
     0.5 x <= Last@# <= 0.5 (x + 1)
     , AppendTo[h[x], First@# -> 0.5 (x + 1)]
     ] &
   , points]
  ]

Then, for instance if we run g[0.5] and then g[0.3], we get:

enter image description here

h can act as a normal function despite being an Association. That is, let's suppose we're looking at the case where x = 0.5, and we're interested in a couple of values of v. Then

h[0.5, 0.2]
h[0.5, 0.1]
(* 0.75 *)
(* Missing["KeyAbsent", 0.1] *)

If you don't like the Missing behavior, we could always overload the function h in a clever way, or perhaps we could define a new function. We can even plot it:

DiscretePlot[h[0.5, v], {v, 0, 1, 0.1}]

enter image description here

$\endgroup$
2
  • $\begingroup$ I have not taken a look at this yet as I've been looking over m_goldberg's answer, which I believe is exactly what I want. I will look over your answer too sometime, though. If your answer works yet I do not mark it as the answer, I apologize (I believe I can only have one answer). Also, many thanks for your effort. $\endgroup$
    – majmun
    Commented Oct 7, 2015 at 5:33
  • $\begingroup$ @user265678. No need to apologize for accepting a superior answer. Actually, no need to apologize for accepting another answer in general. You should accept the one that you think is best or works best for you. $\endgroup$
    – march
    Commented Oct 8, 2015 at 22:49
0
$\begingroup$

I think that you want your h to be a function of both v and x as shown in March's answer using associations.

A small modification to m_golderber's answer enables this to happen.

points = Table[{x, 1./(1. + .5 x)}, {x, 0, 2, .1}]

Add x to the argument for h.

g[x_Real,h_Symbol] := (If[0. <= 2. #[[2]] - x <= 1.,
    h[#[[1]], x] = .5 x + .5] & /@ points;)

Now applying this

g[0., h]; DownValues[h]
(* {HoldPattern[h[2.]] :> 0.5} *)

and continuing

g[.5, h]; DownValues[h]
(* {HoldPattern[h[0.7]] :> 0.75, HoldPattern[h[0.8]] :> 0.75, 
 HoldPattern[h[0.9]] :> 0.75, HoldPattern[h[1.]] :> 0.75, 
 HoldPattern[h[1.1]] :> 0.75, HoldPattern[h[1.2]] :> 0.75, 
 HoldPattern[h[1.3]] :> 0.75, HoldPattern[h[1.4]] :> 0.75, 
 HoldPattern[h[1.5]] :> 0.75, HoldPattern[h[1.6]] :> 0.75, 
 HoldPattern[h[1.7]] :> 0.75, HoldPattern[h[1.8]] :> 0.75, 
 HoldPattern[h[1.9]] :> 0.75, HoldPattern[h[2.]] :> 0.75} *)

Finishing the sample of x values.

g[1.0, h]; g[1.5, h]; g[2.0, h];

Summary of DownValues

Mathematica graphics

$\endgroup$

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.