4
$\begingroup$

I want to compute a multidimensional table in Mathematica and write it to an external file. Here is a simple example. I have three lists x, y, z and the output include all possible combinations of sums.

In the output file, I want 27 = 3x3x3 rows. Each row should have four values: x, y, z and x+y+z. Here is my code.

x = {1, 2, 3};
y = {4, 5, 6};
z = {7, 8, 9};
output = Table[x[[i]] + y[[j]] + z[[k]], {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
sfile = OpenWrite["C:\\Temp\\test.txt"]
For[i = 1, i <= 3, i++,
 {For[j = 1, j <= 3, j++,
   {For[k = 1, k <= 3, k++,
     Write[sfile, x[[i]], y[[j]], z[[k]], output[[i, j, k]]]]}]}]
Close[sfile]

The problem is there is no space in the output file. So I get something like

14712
14813
14914
15713
15814

but I actually want

1 4 7 12
1 4 8 13
1 4 9 14
1 5 7 13
1 5 8 14

I need help to get the format above. I am quite new to Mathematica and don't know much about other functions. I am OK with any functions as long as they can generate the output I want. Thank you.

$\endgroup$
3
  • 1
    $\begingroup$ Any reason for not using Export? Do you need sequential file operations? $\endgroup$
    – Yves Klett
    Mar 25, 2013 at 17:02
  • $\begingroup$ @YvesKlett I am new to Mathematica and this Write function is the one I found on google. I am ok with any functions. I don't have sequential operations. $\endgroup$
    – JACKY88
    Mar 25, 2013 at 17:06
  • $\begingroup$ This seems like a strange behavior of Write. Mathematica does not put a space between expressions. $\endgroup$
    – RunnyKine
    Mar 25, 2013 at 17:37

3 Answers 3

8
$\begingroup$

As suggested by many (@YvesKlett, @acl) you can use Export :

output2 =  Flatten[Table[{x[[i]], y[[ j]], z[[k]], x[[i]] + y[[j]] + z[[k]]}, 
  {i, 1, 3}, {j, 1, 3}, {k, 1, 3}], 2] ;

Export["test.tsv", output2]
$\endgroup$
6
  • $\begingroup$ that's the way to do it $\endgroup$
    – acl
    Mar 25, 2013 at 18:16
  • $\begingroup$ I feel picky: Patrick wanted spaces and you flooded him with tabs! :D $\endgroup$
    – Federico
    Mar 25, 2013 at 18:18
  • $\begingroup$ I was just joking. Of course you can do the tab->space conversion in a thousand ways. Maybe in 2013 even Microsoft Notepad can do that! $\endgroup$
    – Federico
    Mar 25, 2013 at 18:22
  • $\begingroup$ As a curiosity, Export["test.dat", output2, "FieldSeparators" -> " "] fulfills all the requirements. $\endgroup$
    – Federico
    Mar 25, 2013 at 18:26
  • $\begingroup$ @b.gatessucks -- Done. Given your name, I think you appreciated the pun about Notepad... $\endgroup$
    – Federico
    Mar 25, 2013 at 18:41
4
$\begingroup$
sfile = OpenWrite["~/Desktop/test.txt", FormatType -> StandardForm]
For[i = 1, i <= 3, i++, 
 For[j = 1, j <= 3, j++, 
  For[k = 1, k <= 3, k++, 
   Write[sfile, x[[i]], " ", y[[j]], " ", z[[k]], " ", 
    output[[i, j, k]]]]]]
Close[sfile]

seems to work. I used FormatType -> StandardForm and added the spaces by hand. I'm sure there are better ways (eg with Export).

$\endgroup$
5
  • $\begingroup$ I think (if I understood the question right) is that he wants a specific output format, likely for use in some other program. $\endgroup$
    – s0rce
    Mar 25, 2013 at 17:17
  • $\begingroup$ that is possible, looks like I misunderstood the question $\endgroup$
    – acl
    Mar 25, 2013 at 17:20
  • $\begingroup$ @s0rce fixed. not elegant though $\endgroup$
    – acl
    Mar 25, 2013 at 17:57
  • $\begingroup$ You could use Write[sfile, Sequence @@ Riffle[{x[[i]], y[[j]], z[[k]], output[[i, j, k]]}, " "]] to automatically intersperse whitespaces. $\endgroup$
    – Federico
    Mar 25, 2013 at 18:11
  • $\begingroup$ @Federico thanks; not sure it's worth the effort here though. $\endgroup$
    – acl
    Mar 25, 2013 at 18:13
4
$\begingroup$

Why not this?

x = {1, 2, 3};
y = {4, 5, 6};
z = {7, 8, 9};
output = Table[x[[i]] + y[[j]] + z[[k]], {i, 1, 3}, {j, 1, 3}, {k, 1, 3}]
sfile = OpenWrite["test.txt"]
For[i = 1, i <= 3, i++, For[j = 1, j <= 3, j++, For[k = 1, k <= 3, k++,
   str = ToString[{x[[i]], y[[j]], z[[k]], output[[i, j, k]]}];
   WriteString[sfile, StringReplace[str, "{" | "}" | "," -> ""] <> "\n"]
]]]
Close[sfile]

Or this?

...
sfile = OpenWrite["test.txt", FormatType -> StandardForm]
...
For[..., For[..., For[...,
   Write[sfile, Sequence @@ Riffle[{x[[i]], y[[j]], z[[k]], output[[i, j, k]]}, " "]]
]]]
...

After all this fun with streams, here is a one line solution (read comments after @b.gatessucks's solution, you need his output2):

output2 = Flatten[Table[{x[[i]], y[[j]], z[[k]], x[[i]] + y[[j]] + z[[k]]}, {i, 1, 3}, {j, 1, 3}, {k, 1, 3}], 2];
Export["test.dat", output2, "FieldSeparators" -> " "]

If you look at CSV, TSV and Table you'll find a lot of useful information.

Note that you don't need to put braces inside For like you would do i C.

$\endgroup$
0

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.