Order boxes left to right in dot graphviz - dot

I have this gv code,
I want to have the horizontal order :
12 13 14 15 23 24
but I get:
23 13 12 24 14 15
graph "tree" {
node [shape=plaintext];
1 [label = "1"]
2 [label = "2"]
3 [label = "3"]
4 [label = "4"]
5 [label = "5"]
12 [label = "12"]
13 [label = "13"]
14 [label = "14"]
15 [label = "15"]
23 [label = "23"]
24 [label = "24"]
1 -- 12;
2 -- 12;
1 -- 13;
3 -- 13;
1 -- 14;
4 -- 14;
1 -- 15;
5 -- 15;
2 -- 23;
3 -- 23;
2 -- 24;
4 -- 24;}
the solution : Force the left to right order of nodes in graphviz? did not work for this case (ordering nodes not edges).
If I add :
{rank = same; 12 13 14 15 23 24; rankdir=LR;}
We get the same unordered nodes:
png file made with:
dot -T png test.gv > test.png

Or more simply:
graph "tree" {
node[shape=plaintext]
1 -- {12 13 14 15}
2 -- {12 23 24}
3 -- {13 23}
4 -- {14 24}
5 -- 15;
{
rank = same;
12 -- 13 -- 14 -- 15 -- 23 -- 24 [color=invis]
}
}

Simplest is to add 'invisible' (white on white, no arrows) edges.
This will encourage dot to align the nodes in order.
graph "tree" {
node [shape=plaintext];
1 [label = "1"]
2 [label = "2"]
3 [label = "3"]
4 [label = "4"]
5 [label = "5"]
12 [label = "12"]
13 [label = "13"]
14 [label = "14"]
15 [label = "15"]
23 [label = "23"]
24 [label = "24"]
1 -- 12;
2 -- 12;
1 -- 13;
3 -- 13;
1 -- 14;
4 -- 14;
1 -- 15;
5 -- 15;
2 -- 23;
3 -- 23;
2 -- 24;
4 -- 24;
// 'white' (invisible on white background) edges, weight to encourage order
// results in tidiest graph with horizontal nodes in desired order.
edge [color=white,weight=4,arrowhead=none,arrowtail=none];
12 -- 13 -- 14 -- 15 -- 23 -- 24 -- 25 -- 34 -- 35 -- 45;
{rank = same; 12 13 14 15 23 24 25 34 35 45; rankdir=LR;}
}

Related

How to go from multidimensional array to one dimension maintaining the groups

I have an array of 4 dimensions: location(3) x species(3) x Season(6) x Depth (2). Like this matrix 12 times.
Season = 1, depth = 1
[A] [B] [C]
[a] 12 52 55
[b] 13 14 235
[c] 13 76 355
I would like to merge everything in one big matrix like:
Season = 1, depth = 1
[A] [B] [C]
[a11] 12 52 55
[b11] 13 14 235
[c11] 13 76 355
[a12] 12 52 55
[b12] 13 14 235
[c12] 13 76 355
[a21] 12 52 55
[b21] 13 14 235
[c21] 13 76 355
...
and so on. The first number would refer to one extra dimension, and the second for the other one. Does it make sense? Any idea?
Thanks a lot!! :)
This transposes the array with aperm and then makes a matrix.
location = 3
species = 3
Season = 6
Depth = 2
set.seed(1)
myArr <- array(sample(1000, location * species * Season * Depth), dim = c(location, species, Season, Depth))
myArrPerm <- aperm(myArr, perm = c(1,3,4,2))
matrix(myArrPerm, ncol = species)

sum hours and minutes in 2 tables and display results in HH:MM

i have 2 tables, First table is master table having columns in left in HH:MM format taking info from columns in right which are in hh and mm formats
ACType A B C Ahr Amin Bhr Bmin Chr Cmin
A320 12:34 85:45 07:23 12 34 85 45 7 23
B777 20:00 30:00 10:00 20 0 30 0 10 0
Second table has columns in hh and mm format
ACType Bhr Bmin Chr Cmin
A320 10 20 46 31
How can I get final result:
ACType A B C Ahr Amin Bhr Bmin Chr Cmin
A320 12:34 96:05 53:54 12 34 95 65 53 54
B777 20:00 30:00 10:00 20 0 30 0 10 0
SELECT
first.ACType,
first.A,
(
x.Bhr + x.Bmin / 60
)
|| ':' || printf(" % 02d", x.Bmin % 60) AS B,
(
x.Chr + x.Cmin / 60
)
|| ':' || printf(" % 02d", x.Cmin % 60) AS C,
first.Ahr,
first.Amin,
x.Bhr,
x.Bmin,
x.Chr,
x.Cmin
FROM
first
LEFT JOIN
(
SELECT
ACType,
SUM(Bhr) AS Bhr,
SUM(Bmin)AS Bmin,
SUM(Chr) AS Chr,
SUM(Cmin) AS Cmin
FROM
(
SELECT
ACType,
Bhr,
Bmin,
Chr,
Cmin
FROM
first
UNION ALL
SELECT
ACType,
Bhr,
Bmin,
Chr,
Cmin
FROM
SECOND
)
GROUP BY
ACType
)
AS x
WHERE
first.ACType = x.ACType
select null as A, *
from second_table

formula to map between two sequences

Given the 3 sequences below, I would like to be able to map seqN to seq0. seq1 maps to seq0 and seq2 to seq1 by:
seqN(i) = (seqN-1(i)*7)%27
For example,
seq1(i) = (seq0(i)*7)%27
seq0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
seq1 0 7 14 21 1 8 15 22 2 9 16 23 3 10 17 24 4 11 18 25 5 12 19 26 6 13 20 27
seq2 0 22 17 12 7 2 24 19 14 9 4 26 21 16 11 6 1 23 18 13 8 3 25 20 15 10 5 27
Now, one way to do this will be to apply the function recursively. But that is not an option for me (this needs to be implemented in hardware). Nor can I save the values of the last sequence to calculate the value of the current sequence - I don't have space for it.
Is there a way to map seqN to seq0 using a mathematical equation (not recursive functions)?
Apart from what #Nitpick pointed out (27 % 27 = 0, so you have either to stop at 26 or use 28 instead), you should simply use a power:
seqN(i) = ( seq0(i) * 7N ) % 27
Or:
seqN(i) = ( seqN-1(i) * 7 ) % 27 = ( seqN-2(i) * 72 ) % 27 = ... = ( seqN-N(i) * 7N ) % 27
Not sure if this helps, but the transition of some seq_N(i) -> seq_/{N+/-1}(i) is completely determined by the following set of cycles:
List(0)
List(1, 7, 22, 19, 25, 13, 10, 16, 4)
List(2, 14, 17, 11, 23, 26, 20, 5, 8)
List(3, 21, 12)
List(6, 15, 24)
List(9)
List(18)
such that 0 -> 0, 1 -> 7 -> 22 -> 19 -> 25 -> ..., etc.
Based on these cycles you could take a number's position and translate it by N % length_of_cycle (just handling cycle wrapping) and get the original number.
I found these cycles with the following code(written in Scala) :
val m = (0 to 26).map(x => (x, x * 7 % 27)).toMap
var cycles = (0 to 26).map(x => {
var x_i = x
val oot = scala.collection.mutable.ArrayBuffer(x)
while (m(x_i) != x)
{
x_i = m(x_i)
oot.append(x_i)
}
oot.toList
})
var filteredCycles = cycles.toArray
for (i <- (1 to 26))
{
val cycle = filteredCycles(i)
for (j <- (1 until cycle.size))
{
filteredCycles(cycle(j)) = List[Int]()
}
}
val uniqueCycles = filteredCycles.filter(_.size != 0)

how to optimize away common subexpressions?

select x+y as z,
case
when "x"+"y" < 0 then "Less Than Zero"
when "x"+"y" > 0 then "Non Zero"
else "Zero"
end
from sometable;
Returns expected result, but the addition is done with each row of data multiple times.
I am trying to optimize the query as follows but not working..
select x+y as z,
case
when "z" < 0 then "Less Than Zero"
when "z" > 0 then "Non Zero"
else "Zero"
end
from sometable;
Always returns "Less Than Zero".
What am I doing wrong on this query? How can I avoid adding A and B multiple times while the query is being executed?
Column aliases in the SELECT clause are not available in other expressions in the same SELECT clause. (What should happen with SELECT x AS y, y AS x ...?)
You can make such an alias available by moving it into a subquery:
SELECT z,
CASE WHEN z < 0 THEN 'Less Than Zero'
WHEN z > 0 THEN 'Non Zero'
ELSE 'Zero'
END
FROM (SELECT x + y AS z
FROM sometable);
However, this only saves typing; it does not actually optimize away the duplicate computation:
sqlite> explain select z, z from (select x+y as z from sometable);
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 11 0 00 Start at 11
1 OpenRead 1 2 0 2 00 root=2 iDb=0; sometable
2 Rewind 1 9 0 00
3 Column 1 0 3 00 r[3]=sometable.x
4 Column 1 1 4 00 r[4]=sometable.y
5 Add 4 3 1 00 r[1]=r[4]+r[3]
6 Add 4 3 2 00 r[2]=r[4]+r[3]
7 ResultRow 1 2 0 00 output=r[1..2]
8 Next 1 3 0 01
9 Close 1 0 0 00
10 Halt 0 0 0 00
11 Transaction 0 0 1 0 01 usesStmtJournal=0
12 TableLock 0 2 0 sometable 00 iDb=0 root=2 write=0
13 Goto 0 1 0 00

convert 4-dimensional array to 2-dimensional data set in R

I would like to convert a 4-dimensional array into a 2-dimensional data set. I present code for two approaches that do that: one approach using a brute force method involving cbind and rbind and a second approach using nested for-loops. Nevertheless, I am thinking there is likely a better way. Thank you for any suggestions.
R <- 3 # regions
M <- 5 # sites
J <- 2 # samples
T <- 4 # years
# 4-dim example array
y <- array(NA, dim = c(M, J, T, R))
# region 1
y[,1,1,1] = 1; y[,2,1,1] = 2;
y[,1,2,1] = 3; y[,2,2,1] = 4;
y[,1,3,1] = 5; y[,2,3,1] = 6;
y[,1,4,1] = 7; y[,2,4,1] = 8;
# region 2
y[,1,1,2] = 9; y[,2,1,2] = 10;
y[,1,2,2] = 11; y[,2,2,2] = 12;
y[,1,3,2] = 13; y[,2,3,2] = 14;
y[,1,4,2] = 15; y[,2,4,2] = 16;
# region 3
y[,1,1,3] = 17; y[,2,1,3] = 18;
y[,1,2,3] = 19; y[,2,2,3] = 20;
y[,1,3,3] = 21; y[,2,3,3] = 22;
y[,1,4,3] = 23; y[,2,4,3] = 24;
# desired two-dimensional data set
z = read.table(text = "
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
17 18 19 20 21 22 23 24
17 18 19 20 21 22 23 24
17 18 19 20 21 22 23 24
17 18 19 20 21 22 23 24
", sep = "", header = FALSE)
# using cbind and rbind to convert 4-dimensional array to 2-dimensional data set
r1 <- cbind(y[,,1,1], y[,,2,1], y[,,3,1], y[,,4,1])
r2 <- cbind(y[,,1,2], y[,,2,2], y[,,3,2], y[,,4,2])
r3 <- cbind(y[,,1,3], y[,,2,3], y[,,3,3], y[,,4,3])
my.data <- rbind(r1,r2,r3)
my.data
# using nested for-loops to convert 4-dimensional array to 2-dimensional data set
m2 <- matrix(NA, nrow = M*R, ncol= J*T)
for(i in 1:R) {
for(j in 1:T) {
m2[(M*(i-1) + (1:M)), (J*(j-1) + (1:J))] = y[,,j,i]
}
}
m2
# basis for nested for-loops above
m3 <- matrix(NA, nrow = M*R, ncol= J*T)
m3[(M*0 + (1:M)), (J*0 + (1:J))] = y[,,1,1]
m3[(M*0 + (1:M)), (J*1 + (1:J))] = y[,,2,1]
m3[(M*0 + (1:M)), (J*2 + (1:J))] = y[,,3,1]
m3[(M*0 + (1:M)), (J*3 + (1:J))] = y[,,4,1]
m3[(M*1 + (1:M)), (J*0 + (1:J))] = y[,,1,2]
m3[(M*1 + (1:M)), (J*1 + (1:J))] = y[,,2,2]
m3[(M*1 + (1:M)), (J*2 + (1:J))] = y[,,3,2]
m3[(M*1 + (1:M)), (J*3 + (1:J))] = y[,,4,2]
m3[(M*2 + (1:M)), (J*0 + (1:J))] = y[,,1,3]
m3[(M*2 + (1:M)), (J*1 + (1:J))] = y[,,2,3]
m3[(M*2 + (1:M)), (J*2 + (1:J))] = y[,,3,3]
m3[(M*2 + (1:M)), (J*3 + (1:J))] = y[,,4,3]
m3
It took a couple of tries, but:
matrix(aperm(y,c(1,4,2,3)),15)
or more generally
matrix(aperm(y,c(1,4,2,3)),prod(dim(y)[c(1,4)]))
In case someone comes here looking for a similar question about collapsing to an array, but to one that is greater than dimension=2, use array() instead of matrix(), with the dim() argument to specify what dimensions you want. Code that will also work for the problem above is:
array(aperm(y,c(1,4,2,3)), dim=c(15,8))
This can easily be modified if you wanted the output to be, say, a 3d array by putting in an additional value to dim(). The aperm() bit may not be necessary for your particular case, but you should always check that the collapsed array is in the order you want and use aperm() accordingly.

Resources