How to format two separate lists in columns, rather than rows in Mathematica? - formatting

This seems like it should be a piece of cake, but I haven't found the answer in Mathematica's documentation. Say I have two separate lists, for example x={1,2,3,4,5} and y={1,4,9,16,25}. I want to format these lists as a table with each list as a column, like this:
x y
1 1
2 4
3 9
4 16
5 25
But if I do TableForm[x,y], I get only the first column, like this:
1
2
3
4
5
If I do Grid[{x,y}], I get a table, but formatted as rows instead of columns, like this:
1 2 3 4 5
1 4 9 16 25
Now, if I have my values as {x,y} pairs, rather than separate lists, then I can get almost what I want,like so:
Input: Table[{n,n^2},{n,1,5}]//TableForm
Output:
1 1
2 4
3 9
4 16
5 25
I say almost, because I'd like to have the variable names at the top of each column, and I'd like the columns justified so that the ones digits are always placed vertically in the "ones place", the tens digits in the "tens place", etc.
So, back to my question: If I have two separate lists of the same length, how can I format them as a table of columns? I checked the MMA documentation for Grid and TableForm, but I couldn't find a way to do it. Did I miss something? If there's no direct way to do it, is there a way to transform two separate lists into pairs of values that could then be formatted in columns using TableForm?
Thanks for any suggestions you might have.

Personally I prefer Grid to TableForm. Maybe something like this?
Some preliminaries:
x = {1, 2, 3, 4, 5};
y = {1, 4, 9, 16, 25};
grid = Transpose#{x, y};
headings = {{Item["x", Frame -> {True, True}],
Item["y", Frame -> {True, False}]}};
The following code,
Grid[Join[headings, grid], Alignment -> Right, Dividers -> All,
Spacings -> {3, 1}, FrameStyle -> Orange]
gives this as output, for example:

Often in Mathematica, you use Transpose to switch the role of row and column.
In[6]:= x = {1,2,3,4,5}; y = {1,4,9,16,25};
In[7]:= {x,y} // Transpose // TableForm
Out[7]//TableForm= 1 1
2 4
3 9
4 16
5 25

Instead of using Transpose you can use the option TableDirection:
x={1,2,3,4,5};y={1,4,9,16,25};
TableForm[{x,y},TableDirections->Row,TableHeadings->{{"x","y"}}]

Grid[Transpose[{x, y}], Alignment -> Right]

I would use:
x = {1, 2, 3, 4, 5};
y = {1, 4, 9, 16, 25};
TableForm[{{x, y}}, TableAlignments -> Right]
Here are some more convoluted examples, demonstrating the way TableForm works. It does get complicated, and I usually have to experiment a bit to get what I want.
a = {1, 2, 3};
b = {4, 5, 6};
{a, b} // TableForm
{{a}, {b}} // TableForm
{{{a}}, {{b}}} // TableForm
{{{a}, {b}}} // TableForm
{{List /# a, List /# b}} // TableForm
{{a}, b} // TableForm
{{{a}, b}} // TableForm
{{{a}}, {b}} // TableForm
{{{{a}}, {b}}} // TableForm

Related

OCTAVE: row, column index return

I want to return row, column index.
For example
a = [1 2 3; 7 8 9; 4 5 6]
In this matrix, Maximum is 9.
I want to return row 2, column 3 of 9.
This is pretty straightforward.
https://www.gnu.org/software/octave/doc/interpreter/Index-Expressions.html
a(2,3)

Understanding PsychoPy's data logging

I have a test PsychoPy Builder script that I am using to investigate some counter-intuitive behaviour. The structure is four routines:
"Init", not in a loop, the following code in "Begin Experiment":
x = 0
y = 0
z = 0
foo = [0, 0, 0]
"One", in a loop, the following code in "End Routine":
x = x + 1
foo[0] = foo[0] + 1
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
"Two", in a loop, the following code in "End Routine":
y = y + 2
foo[1] = foo[1] + 2
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("fooY", foo[1])
thisExp.addData("foo", foo)
"Three", in a loop, the following code in "End Routine":
z = z + 3
foo[2] = foo[2] + 3
thisExp.addData("x", x)
thisExp.addData("y", y)
thisExp.addData("z", z)
thisExp.addData("foo", foo)
There is no other code, no other components. The routines "One", "Two", and "Three" form a loop in that order executed five times. The relevant columns of the CSV output file are as follows:
trials.thisRepN trials.thisTrialN trials.thisN trials.thisIndex x y z foo fooY
0 0 0 0 1 2 3 [5, 10, 15] 2
1 0 1 0 2 4 6 [5, 10, 15] 4
2 0 2 0 3 6 9 [5, 10, 15] 6
3 0 3 0 4 8 12 [5, 10, 15] 8
4 0 4 0 5 10 15 [5, 10, 15] 10
Is this the expected output? If so, why? Note that the individual variables, x, y, and z, are displaying updated values each time through the loop (at the end of the loop), while the list foo shows only the final value after the loop iterates all five times, but it shows this in every line. But calling out individual elements of the list displays as individual variables do.
What is the logic and rationale behind this?
Is there a way to make the list output perform as the others do?
Is there a way to force the output to capture/display any of these variables as they are when the addData() is invoked rather than waiting until the end of the loop?
I think I know what is going wrong here. It's probably because python assigns by reference rather than copy. This is explained in detail elsewhere but briefly,
original = [1, 2]
new = original # new is simply a reference to original! It is not a copy.
new[0] = 'Oops' # original is now ['Oops', 2] as is new (which is just a reference or pointer
In your case, the TrialHandler receives the reference, which simply points to the "foo" variable which is updated throughout the experiment. Since the log is only saved in the end of the experiment, all the rows in "foo" now points to the "foo variable" which now holds the value [5, 10, 15].
This assignment-by-reference can be extremely beautiful and handy, but sometimes cause headache like in your example. It applies to all python mutables: lists, dicts, functions, and classes. But not for immutables, like numbers, tuples and strings! That's why your script works for digits but not for the list.
There are different solutions. The simplest is probably to replace the addData calls with thisExp.addData("foo", tuple(foo)) which converts the mutable list to an immutable tuple. One can also do thisExp.addData("foo", [x for x in foo]). A more all-round solution for all kinds of objects is to run import copy in the beginning of the experiment and then add data like thisExp.addData("foo", copy.copy(foo)) in the other codeblocks (if you have a complicated object, use copy.deepcopy instead).

Step through range in D

Is there a way to create a step in D ranges?
For example, in python,
range(1, 10, 2)
gives me
[1, 3, 5, 7, 9]
all odds within 1 .. 10
Is there a way to do this in D using foreach?
foreach(x; 1 .. 10) {
}
I know I can use iota(start, end, step), but I also want to add an int to the very beginning and I don't know how to convert type Result to an int.
chain([2],iota(3,16,2));
chain concatenates ranges lazily
or you can go the other way around with filter!q{a==2||a&1}(iota(2,16));

Hash function to iterate through a matrix

Given a NxN matrix and a (row,column) position, what is a method to select a different position in a random (or pseudo-random) order, trying to avoid collisions as much as possible?
For example: consider a 5x5 matrix and start from (1,2)
0 0 0 0 0
0 0 X 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
I'm looking for a method like
(x,y) hash (x,y);
to jump to a different position in the matrix, avoiding collisions as much as possible
(do not care how to return two different values, it doesn't matter, just think of an array).
Of course, I can simply use
row = rand()%N;
column = rand()%N;
but it's not that good to avoid collisions.
I thought I could apply twice a simple hash method for both row and column and use the results as new coordinates, but I'm not sure this is a good solution.
Any ideas?
Can you determine the order of the walk before you start iterating? If your matrices are large, this approach isn't space-efficient, but it is straightforward and collision-free. I would do something like:
Generate an array of all of the coordinates. Remove the starting position from the list.
Shuffle the list (there's sample code for a Fisher-Yates shuffle here)
Use the shuffled list for your walk order.
Edit 2 & 3: A modular approach: Given s array elements, choose a prime p of form 2+3*n, p>s. For i=1 to p, use cells (iii)%p when that value is in range 1...s-1. (For row-length r, cell #c subscripts are c%r, c/r.)
Effectively, this method uses H(i) = (iii) mod p as a hash function. The reference shows that as i ranges from 1 to p, H(i) takes on each of the values from 0 to p-1, exactly one time each.
For example, with s=25 and p=29 or 47, this uses cells in following order:
p=29: 1 8 6 9 13 24 19 4 14 17 22 18 11 7 12 3 15 10 5 16 20 23 2 21 0
p=47: 1 8 17 14 24 13 15 18 7 4 10 2 6 21 3 22 9 12 11 23 5 19 16 20 0
according to bc code like
s=25;p=29;for(i=1;i<=p;++i){t=(i^3)%p; if(t<s){print " ",t}}
The text above shows the suggestion I made in Edit 2 of my answer. The text below shows my first answer.
Edit 0: (This is the suggestion to which Seamus's comment applied): A simple method to go through a vector in a "random appearing" way is to repeatedly add d (d>1) to an index. This will access all elements if d and s are coprime (where s=vector length). Note, my example below is in terms of a vector; you could do the same thing independently on the other axis of your matrix, with a different delta for it, except a problem mentioned below would occur. Note, "coprime" means that gcd(d,s)=1. If s is variable, you'd need gcd() code.
Example: Say s is 10. gcd(s,x) is 1 for x in {1,3,7,9} and is not 1 for x in {2,4,5,6,8,10}. Suppose we choose d=7, and start with i=0. i will take on values 0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, which modulo 10 is 0, 7, 4, 1, 8, 5, 2, 9, 6, 3, 0.
Edit 1 & 3: Unfortunately this will have a problem in the two-axis case; for example, if you use d=7 for x axis, and e=3 for y-axis, while the first 21 hits will be distinct, it will then continue repeating the same 21 hits. To address this, treat the whole matrix as a vector, use d with gcd(d,s)=1, and convert cell numbers to subscripts as above.
If you just want to iterate through the matrix, what is wrong with row++; if (row == N) {row = 0; column++}?
If you iterate through the row and the column independently, and each cycles back to the beginning after N steps, then the (row, column) pair will interate through only N of the N^2 cells of the matrix.
If you want to iterate through all of the cells of the matrix in pseudo-random order, you could look at questions here on random permutations.
This is a companion answer to address a question about my previous answer: How to find an appropriate prime p >= s (where s = the number of matrix elements) to use in the hash function H(i) = (i*i*i) mod p.
We need to find a prime of form 3n+2, where n is any odd integer such that 3*n+2 >= s. Note that n odd gives 3n+2 = 3(2k+1)+2 = 6k+5 where k need not be odd. In the example code below, p = 5+6*(s/6); initializes p to be a number of form 6k+5, and p += 6; maintains p in this form.
The code below shows that half-a-dozen lines of code are enough for the calculation. Timings are shown after the code, which is reasonably fast: 12 us at s=half a million, 200 us at s=half a billion, where us denotes microseconds.
// timing how long to find primes of form 2+3*n by division
// jiw 20 Sep 2011
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
double ttime(double base) {
struct timeval tod;
gettimeofday(&tod, NULL);
return tod.tv_sec + tod.tv_usec/1e6 - base;
}
int main(int argc, char *argv[]) {
int d, s, p, par=0;
double t0=ttime(0);
++par; s=5000; if (argc > par) s = atoi(argv[par]);
p = 5+6*(s/6);
while (1) {
for (d=3; d*d<p; d+=2)
if (p%d==0) break;
if (d*d >= p) break;
p += 6;
}
printf ("p = %d after %.6f seconds\n", p, ttime(t0));
return 0;
}
Timing results on 2.5GHz Athlon 5200+:
qili ~/px > for i in 0 00 000 0000 00000 000000; do ./divide-timing 500$i; done
p = 5003 after 0.000008 seconds
p = 50021 after 0.000010 seconds
p = 500009 after 0.000012 seconds
p = 5000081 after 0.000031 seconds
p = 50000021 after 0.000072 seconds
p = 500000003 after 0.000200 seconds
qili ~/px > factor 5003 50021 500009 5000081 50000021 500000003
5003: 5003
50021: 50021
500009: 500009
5000081: 5000081
50000021: 50000021
500000003: 500000003
Update 1 Of course, timing is not determinate (ie, can vary substantially depending on the value of s, other processes on machine, etc); for example:
qili ~/px > time for i in 000 004 010 058 070 094 100 118 184; do ./divide-timing 500000$i; done
p = 500000003 after 0.000201 seconds
p = 500000009 after 0.000201 seconds
p = 500000057 after 0.000235 seconds
p = 500000069 after 0.000394 seconds
p = 500000093 after 0.000200 seconds
p = 500000099 after 0.000201 seconds
p = 500000117 after 0.000201 seconds
p = 500000183 after 0.000211 seconds
p = 500000201 after 0.000223 seconds
real 0m0.011s
user 0m0.002s
sys 0m0.004s
Consider using a double hash function to get a better distribution inside the matrix,
but given that you cannot avoid colisions, what I suggest is to use an array of sentinels
and mark the positions you visit, this way you are sure you get to visit a cell once.

A programming challenge with Mathematica

I am interfacing an external program with Mathematica. I am creating an input file for the external program. Its about converting geometry data from a Mathematica generated graphics into a predefined format. Here is an example Geometry.
Figure 1
The geometry can be described in many ways in Mathematica. One laborious way is the following.
dat={{1.,-1.,0.},{0.,-1.,0.5},{0.,-1.,-0.5},{1.,-0.3333,0.},{0.,-0.3333,0.5},
{0.,-0.3333,-0.5},{1.,0.3333,0.},{0.,0.3333,0.5},{0.,0.3333,-0.5},{1.,1.,0.},
{0.,1.,0.5},{0.,1.,-0.5},{10.,-1.,0.},{10.,-0.3333,0.},{10.,0.3333,0.},{10.,1.,0.}};
Show[ListPointPlot3D[dat,PlotStyle->{{Red,PointSize[Large]}}],Graphics3D[{Opacity[.8],
Cyan,GraphicsComplex[dat,Polygon[{{1,2,5,4},{1,3,6,4},{2,3,6,5},{4,5,8,7},{4,6,9,7},
{5,6,9,8},{7,8,11,10},{7,9,12,10},{8,9,12,11},{1,2,3},{10,12,11},{1,4,14,13},
{4,7,15,14},{7,10,16,15}}]]}],AspectRatio->GoldenRatio]
This generates the required 3D geometry in GraphicsComplex format of MMA.
This geometry is described as the following input file for my external program.
# GEOMETRY
# x y z [m]
NODES 16
1. -1. 0.
0. -1. 0.5
0. -1. -0.5
1. -0.3333 0.
0. -0.3333 0.50. -0.3333 -0.5
1. 0.3333 0.
0. 0.3333 0.5
0. 0.3333 -0.5
1. 1. 0.
0. 1. 0.5
0. 1. -0.5
10. -1. 0.
10. -0.3333 0.
10. 0.3333 0.
10. 1. -0.
# type node_id1 node_id2 node_id3 node_id4 elem_id1 elem_id2 elem_id3 elem_id4
PANELS 14
1 1 4 5 2 4 2 10 0
1 2 5 6 3 1 5 3 10
1 3 6 4 1 2 6 10 0
1 4 7 8 5 7 5 1 0
1 5 8 9 6 4 8 6 2
1 6 9 7 4 5 9 3 0
1 7 10 11 8 8 4 11 0
1 8 11 12 9 7 9 5 11
1 9 12 10 7 8 6 11 0
2 1 2 3 1 2 3
2 10 12 11 9 8 7
10 4 1 13 14 1 3
10 7 4 14 15 4 6
10 10 7 15 16 7 9
# end of input file
Now the description I have from the documentation of this external program is pretty short. I am quoting it here.
First keyword NODES states total number of
nodes. After this line there should be no comment or empty lines. Next lines consist of
three values x, y and z node coordinates and number of lines must be the same as number
of nodes.
Next keyword is PANEL and states how many panels we have. After that we have lines
defining each panel. First integer defines panel type
ID 1 – quadrilateral panel - is defined by four nodes and four neighboring panels.
Neighboring panels are panels that share same sides (pair of nodes) and is needed for
velocity and pressure calculation (methods 1 and 2). Missing neighbors (for example for
panels near the trailing edge) are filled with value 0 (see Figure 1).
ID 2 – triangular panel – is defined by three nodes and three neighboring panels.
ID 10 – wake panel – is quadrilateral panel defined with four nodes and with two
(neighboring) panels which are located on the trailing edge (panels to which wake panel is
applying Kutta condition).
Panel types 1 and 2 must be defined before type 10 in input file.
Important to notice is the surface normal; order of nodes defining panels should be
counter clockwise. By the right-hand rule if fingers are bended to follow numbering,
thumb will show normal vector that should point “outwards” geometry.
Challenge!!
We are given with a 3D CAD model in a file called One.obj and it is exported fine in MMA.
cd = Import["One.obj"]
The output is a MMA Graphics3D object
Now I can get easily access the geometry data as MMA internally reads them.
{ver1, pol1} = cd[[1]][[2]] /. GraphicsComplex -> List;
MyPol = pol1 // First // First;
Graphics3D[GraphicsComplex[ver1,MyPol],Axes-> True]
How we can use the vertices and polygon information contained in ver1 and pol1 and write them in a text file as described in the input file example above. In this case we will only have ID2 type (triangular) panels.
Using the Mathematica triangulation how to find the surface area of this 3D object. Is there any inbuilt function that can compute surface area in MMA?
No need to create the wake panel or ID10 type elements right now. A input file with only triangular elements will be fine.
Sorry for such a long post but its a puzzle that I am trying to solve for a long time. Hope some of you expert may have the right insight to crack it.
BR
Q1 and Q2 are easy enough that you could drop the "challenge" labels in your question. Q3 could use some clarification.
Q1
edges = cd[[1, 2, 1]];
polygons = cd[[1, 2, 2, 1, 1, 1]];
Update Q1
The main problem is to find the neighbor of each polygon. The following does this:
(* Split every triangle in 3 edges, with nodes in each edge sorted *)
triangleEdges = (Sort /# Subsets[#, {2}]) & /# polygons;
(* Generate a list of edges *)
singleEdges = Union[Flatten[triangleEdges, 1]];
(* Define a function which, given an edge (node number list), returns the bordering *)
(* triangle numbers. It's done by working through each of the triangles' edges *)
ClearAll[edgesNeighbors]
edgesNeighbors[_] = {};
MapIndexed[(
edgesNeighbors[#1[[1]]] = Flatten[{edgesNeighbors[#1[[1]]], #2[[1]]}];
edgesNeighbors[#1[[2]]] = Flatten[{edgesNeighbors[#1[[2]]], #2[[1]]}];
edgesNeighbors[#1[[3]]] = Flatten[{edgesNeighbors[#1[[3]]], #2[[1]]}];
) &, triangleEdges
];
(* Build a triangle relation table. Each '1' indicates a triangle relation *)
relations = ConstantArray[0, {triangleEdges // Length, triangleEdges // Length}];
Scan[
(n = edgesNeighbors[##];
If[Length[n] == 2,
{n1, n2} = n;
relations[[n1, n2]] = 1; relations[[n2, n1]] = 1];
) &, singleEdges
]
MatrixPlot[relations]
(* Build a neighborhood list *)
triangleNeigbours =
Table[Flatten[Position[relations[[i]], 1]], {i,triangleEdges // Length}];
(* Test: Which triangles border on triangle number 1? *)
triangleNeigbours[[1]]
(* ==> {32, 61, 83} *)
(* Check this *)
polygons[[{1, 32, 61, 83}]]
(* ==> {{1, 2, 3}, {3, 2, 52}, {1, 3, 50}, {19, 2, 1}} *)
(* Indeed, they all share an edge with #1 *)
You can use the low level output functions described here to output these. I'll leave the details to you (that's my challenge to you).
Q2
The area of the wing is the summed area of the individual polygons. The individual areas can be calculated as follows:
ClearAll[polygonArea];
polygonArea[pts_List] :=
Module[{dtpts = Append[pts, pts[[1]]]},
If[Length[pts] < 3,
0,
1/2 Sum[Det[{dtpts[[i]], dtpts[[i + 1]]}], {i, 1, Length[dtpts] - 1}]
]
]
based on this Mathworld page.
The area is signed BTW, so you may want to use Abs.
CORRECTION
The above area function is only usable for general polygons in 2D. For the area of a triangle in 3D the following can be used:
ClearAll[polygonArea];
polygonArea[pts_List?(Length[#] == 3 &)] :=
Norm[Cross[pts[[2]] - pts[[1]], pts[[3]] - pts[[1]]]]/2