4
$\begingroup$

I have been using the built-in function Table for some computations. (The following is not an actual representation of the equations I am using).

$$\text{Table}[f[k]=g[k],\{k,1,10\}]$$

However, the assignment $f[k]=g[k]$ is not true for one $k$ value, say $k=6$. That is, say, $g[k]=k^2+1$ for $k\neq 6$ and $g[6]=1$ (when $k=6$).

I can then break the table into two parts: $\{k,1,5\}$ and $\{k,7,10\}$.

Is there any other (more efficient) way of doing this?

$\endgroup$
1
  • 1
    $\begingroup$ Please do not use LaTeX to format code. It makes it impossible to copy and paste it. Use a proper code box. $\endgroup$
    – Szabolcs
    Aug 10, 2014 at 15:05

3 Answers 3

7
$\begingroup$

You can do this without Table:

g[k_] := k^2 + 1

Map[If[# != 6, f[#] = g[#], f[#] = 1] &, Range[10]]

{2, 5, 10, 17, 26, 1, 50, 65, 82, 101}

You can also use Scan in place of Map (it may be slightly faster for large lists). Note that no result will be displayed, but f will still retain the values stored in it.

Scan[If[# != 6, f[#] = g[#], f[#] = 1] &, Range[10]]

You can retrieve the values as follows:

f /@ Range[10]

{2, 5, 10, 17, 26, 1, 50, 65, 82, 101}

$\endgroup$
2
  • $\begingroup$ Dear @RunnyKine, Thanks for your help. $\endgroup$
    – Radz
    Aug 10, 2014 at 5:26
  • $\begingroup$ @Radz You're welcome. Glad I could help. $\endgroup$
    – RunnyKine
    Aug 10, 2014 at 5:27
4
$\begingroup$

In addition to RunnyKine's recommendation of If here are two other methods to consider.

1: Unset or restore the value

Simply Unset f[6] afterward:

Do[f[k] = g[k], {k, 10}];
f[6] =.

Array[f, 10]
{g[1], g[2], g[3], g[4], g[5], f[6], g[7], g[8], g[9], g[10]}

Note f[6] is returned as it is undefined.

Or if f[6] already has a value save and restore it:

f[k_] := 9 k

k6 = f[6];
Do[f[k] = g[k], {k, 10}];
f[6] = k6;

Array[f, 10]
 {g[1], g[2], g[3], g[4], g[5], 54, g[7], g[8], g[9], g[10]}

2: Delete the value from your iterator range

Do[f[k] = g[k], {k, Range[10] ~Delete~ 6}];

Array[f, 10]
{g[1], g[2], g[3], g[4], g[5], f[6], g[7], g[8], g[9], g[10]}

Again note f[6] is returned in the output.

$\endgroup$
1
  • $\begingroup$ Dear @Mr.Wizard, Thank you for you help. $\endgroup$
    – Radz
    Aug 11, 2014 at 2:03
4
$\begingroup$

Of course you can use the If also inside the table:

Table[If[k != 6, f[k] = g[k], f[k] = 1], {k, 10}]

You can also use the If on the right hand side of the assignment:

Table[f[k] = If[k != 6, g[k], 1], {k, 10}]

If the whole purpose of the table is the assignment, that is you are not really interested in the list it outputs, you can replace Table with Do (I imagine that would also be faster, but I haven't measured it):

Do[If[k != 6, f[k] = g[k], f[k] = 1], {k, 10}]

Another option (which especially is useful if the two ranges are far apart and you don't need to assign to intermediate values of f) is to build the iterator from the two subranges explicitly:

Do[f[k] = g[k], {k, Range[5] ~Join~ Range[7,10]}]

Yet another option would be to use Piecewise:

Table[f[k]=Piecewise[{{g[k], k!=6}}, 1], {k, 10}]
$\endgroup$
2
  • $\begingroup$ Dear @celtschk, Thank you for you help. $\endgroup$
    – Radz
    Aug 11, 2014 at 2:04
  • $\begingroup$ @Radz: You're welcome. $\endgroup$
    – celtschk
    Aug 13, 2014 at 8:08

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.