# MapAt a function at specific positions

I'm trying to solve for $p3$ in 3p3-5 = p1 + p2 at positions where p1*p2 == 0:

deltap = 10^(-2)

tabletry = Table[p1*p2, {p1, 0, 2}, {p2, 0, 2}]  // MatrixForm

tabletest = Table[{If[p1*p2 == 0, True, False  ]}, {p1, 0, 2}, {p2, 0, 2}] // MatrixForm


$$\left( \begin{array}{ccc} 0 & 0 & 0 \\ 0 & 1 & 2 \\ 0 & 2 & 4 \\ \end{array} \right)$$

$$\left( \begin{array}{ccc} {(True)}\ & (True) & (True) \\ \ (True) & (False) & (False) \\ \ (True) & (False) & (False) \\ \end{array} \right)$$

(Array[# #2 /. {(0) -> Style[Solve[3 p3 - 5 == # + #2, p3][[1, 1, -1]], Red], _ :>
0} &, {3, 3}, 0]) // MatrixForm EDIT

Now I'm trying to up the level of code, trying to evaluate the difference in p3 following at true entries. Full code:

deltap = 10^-2;

tabletry = (Table[p1*p2, {p1, 0, 2}, {p2, 0, 2}] ) // MatrixForm tst = ( Map[{# ==  0 } &, tabletry, {-1}] ) // MatrixForm eqn1 = 1/p3 - 5p3 = p1 + p2

eqn2 = 1/p3 - 5p3 + deltap = p1 + p2

diff = p3 /. FindRoot[eqn2, {p3,1}] - p3 /. FindRoot[eqn1,{p3,1}]

(Array[# #2 /. {(0) -> Style[Evaluate[diff[#, #2]][[1, 1, -1]], Red], _ :>
0} &, {3, 3}, 0]) // MatrixForm

• Solve[p3 == p1 + p2 && And @@ ((# == 0 || # == 1 || # == 2) & /@ {p1, p2}) && p1*p2 == 0, {p1, p2, p3}] – Dr. belisarius Sep 25 '14 at 10:49
• @belisarius I'm trying to solve for p3 at each entry, as p1 and p2 run from 0 to 2. So the output should be a 3x3 matrix of p3 values – user44840 Sep 25 '14 at 11:23

For your second question, you could use

(tabletry = Table[p1*p2, {p1, 0, 2}, {p2, 0, 2}]) // MatrixForm;
(* or  (tabletry = Array[# #2 &, {3, 3}, 0]) // MatrixForm; *)
(tst = Map[{# == 0} &, tabletry, {-1}]) // MatrixForm


or

(tst2 = Array[# #2 /. {0 -> {True}, _ -> {False}} &, {3, 3}, 0]) // MatrixForm Note the parantheses wrapping the definitions -- without those you would be setting the lhs to MatrixForm[rhs]

For the first part, assuming you want to leave the non-zero entries untouched, you could use

(mybestwildguessaboutexpectedoutput =
Array[# #2 /. (0) -> Style[Solve[3 p3 - 5 == # + #2, p3][[1, 1, -1]],
Red, Bold] &, {3, 3}, 0]) // MatrixForm You could also use

MapIndexed[# /. (0) -> Solve[3 p3 - 5 == Plus @@ (#2 - 1), p3][[1, 1, -1]] &, tabletry, {2}]

• That looks very good. Is there a way to set the non-relevant entries all to a number, say 0 or 1? – user44840 Sep 25 '14 at 12:30
• @user44840, you can use Array[# #2 /. {(0) -> Solve[3 p3 - 5 == # + #2, p3][[1, 1, -1]], _ :> zz} &, {3, 3}, 0] and use the number of your choice for zz. – kglr Sep 25 '14 at 12:34
• @kguler very nice and helped me understand aims of question...like your long variable name:) – ubpdqn Sep 25 '14 at 12:50
• your post has been nothing short of brilliant so far. However, I think it is limited to simple equations that allow you to explicitly write 3 p3 - 5 == # + #2 then what about more complex equations that depend on p1 and p2 implicitly? – user44840 Sep 25 '14 at 13:14
• @user44840, thank you for the kind words. I think it should work for any equation involving three variable p1,p2,p3. If, for example, you have eq = foo[p1,p2,p3]==bar[p1,p2,p3] in place of 3 p3 -5 == p1 +p2 you can use eq /. {p1 ->#, p2->#2}. – kglr Sep 25 '14 at 13:26

Your p3 definitions seem different. The following uses 3p3 -5=p1+p2.

set = Tuples[Range[0, 2], 2];
set /. {x_, y_} :> (x + y + 5)/3. /; x y == 0


yields:

{1.66667, 2., 2.33333, 2., {1, 1}, {1, 2}, 2.33333, {2, 1}, {2, 2}}


or if you wish to couple results and {p1,p2}:

set /. {{x_, y_} :>
Rule[{x, y}, (x + y + 5)/3.] /; x y == 0, {x_, y_} :>
Sequence[] /; x y != 0}


yields:

{{0, 0} -> 1.66667, {0, 1} -> 2., {0, 2} -> 2.33333, {1, 0} ->
2., {2, 0} -> 2.33333}

• you used (x + y + 5)/3 knowing the expression for p3, but I'm looking for a more general way to solve it. Also, I need to use the table of values tabletry, instead of using " set = Tuples[Range[0, 2], 2]; " – user44840 Sep 25 '14 at 11:18

I post this as another answer (using again $3p3=p1+p2-5$) if the matrices are the main aim:

sa0 = SparseArray[{i_, j_} :> (i - 1) (j - 1), {3, 3}] // MatrixForm;
sa = SparseArray[{{i_,
j_} /; ((i - 1) (j - 1) != 0) :> (i - 1) (j - 1), {i_,
j_} /; ((i - 1) ( j - 1) == 0) :> (i + j + 5)/3.}, {3, 3}] //
MatrixForm;
Row[{sa0, "\[RightArrow]", saf}] UPDATE

If you are just dealing with linear combinations, and your equations can be represented as $r p3 = m p1+ n p2+s$ then (borrowing from kguler and comments re desired output):

h[0, {a_, b_}, func_, v_] :=
Style[v /. First@Solve[func, v], Bold, Red]
h[x_?(# != 0 &), __] := "x"


then you can use MapIndexed:

Here demonstrated using random quadruplet of integers:

Column[Function[{u, v, w, t},
u p3 == {p1, p2}.{v, w} +
t -> (MapIndexed[h[#1, #2, u p3 == #2.{v, w} + t, p3] &,
SparseArray[{i_, j_} :> (i - 1) (j - 1), {3, 3}], {2}] //
MatrixForm)] @@@ RandomInteger[{1, 10}, {10, 4}], Frame -> All] • I'm trying to incorporate FindRoot or Solve into the solution, so it would work for more complex equations. In these equations, we won't know p3=(p1 + p2 + 5)/3 – user44840 Sep 25 '14 at 11:27
• It should incorporate something like ´ FindRoot[eqn, {p3,initial}] ´ – user44840 Sep 25 '14 at 12:15