Skip to content

Please help me in Converting this from C# to R

4 messages · rajivv, Barry Rowlingson, Simon Knapp +1 more

#
Random r = new Random();
                DirectedGraph<SimpleNode> graph = GetGraph();
                decimal B = 0.1m;
                decimal D = 0.05m;
                int nodes = graph.NodesCount;
                decimal[] E = new decimal[nodes];
                decimal[] P = new decimal[nodes];

                for (int i = 7; i <= 10; ++i)
                    P[i] = (decimal)r.NextDouble();

                
                for (int t = 0; t < 100; ++t)
                {
                  //  Writed(E, "E");
                    Writed(P, "P");

                    foreach (SimpleNode n in graph.Nodes)
                    {
                        int id = graph.index[n];

                        decimal product = 1;
                        foreach (var item in graph.GetAdjacentNodes(n))
                        {
                            int j = graph.index[item];
                            product *= (1 - B * P[j]);
                        }

                        E[id] = product;
                    }

                    foreach (SimpleNode n in graph.Nodes)
                    {
                        int i = graph.index[n];

                        P[i] = 1 - ((1 - P[i]) * E[i] + D * (1 - P[i]) *
E[i] + 0.5m * D * P[i] * (1 - E[i]));
                        
                        if (P[i] < 0)
                            P[i] = 0;
                    }
                }

            }
#
2008/9/14 rajivv <rajiv_das at rediffmail.com>:
[ deletia ]
If you convert it into English first, then more people will be able
to help. It's much easier to convert English to any programming
language than from programming language A to programming language B.
Given that this code must have derived from a specification written in
a human language (such as English) just supply us with that. Sometimes
you don't need the original spec if the code is well-commented. But
this code is null-commented.

 At a guess, it seems to get a graph from out of nowhere
(graph=GetGraph()) and then do 100 iterations of some calculation
based on the graph adjacency. This should not be too difficult to
convert to R, but with any conversion problem there are always hidden
traps to beware of. Here's one in your code:

 You have:

  for (int i = 7; i <= 10; ++i)

 in one loop, and:

  for (int t = 0; t < 100; ++t)

 Now, much as C style loop specifications are concise and elegant,
they can cause confusion. The subtle differences here (using < instead
of <=, and the 'preincrement' ++i) confuse me as to what values the
loop variable takes in the loop.

 The way to get by all these issues in any conversion problem is to
have a good set of test cases. You run the test cases in language A
and get a set of answers. You then run the test cases using the
converted code in language B and if you don't get the same answers
then the conversion has failed.

 If you can describe what the code does, add some meaningful comments,
and produce a set of sample data test cases and results then perhaps
you'll get more help than just pasting the code in and asking nicely
(you did say 'please', which is more than some people do on this
list!).

Barry
#
# bit hard to provide a simple conversion without definitions of the
class 'Node', the template 'DirectedGraph' and the function 'Writed'!
# I've used the package 'igraph' as a drop in - hope it is still clear.
#
# by the way:
# - your curly braces don't match,
# - not all elements of P are initialised before they are used.

#------------------------------------
# original code (cleaned to make comparison easier).
#------------------------------------
#Random r = new Random();
#DirectedGraph<SimpleNode> graph = GetGraph();
#decimal B = 0.1m;
#decimal D = 0.05m;
#int nodes = graph.NodesCount;
#decimal[] E = new decimal[nodes];
#decimal[] P = new decimal[nodes];
#
#for (int i = 7; i <= 10; ++i) P[i] = (decimal)r.NextDouble();
#
#for (int t = 0; t < 100; ++t){
#    Writed(P, "P");
#
#    foreach (SimpleNode n in graph.Nodes) {
#        int id = graph.index[n];
#
#        decimal product = 1;
#        foreach (var item in graph.GetAdjacentNodes(n)){
#            int j = graph.index[item];
#            product *= (1 - B * P[j]);
#        }
#
#        E[id] = product;
#    }
#
#    foreach (SimpleNode n in graph.Nodes){
#        int i = graph.index[n];
#        P[i] = 1 - ((1 - P[i]) * E[i] + D * (1 - P[i]) * E[i] + 0.5m
* D * P[i] * (1 - E[i]));
#        if (P[i] < 0) P[i] = 0;
#    }
#}
#
#}


#------------------------------------
# drop-in for your method getGraph (produces a 10 'random' node
directed graph). I only assign to temporary so I can use the same
'grph' and 'P' in both implementations.
#------------------------------------
library(igraph)
GetGraph <- function() graph.adjacency(matrix(sample(0:1, size=100,
replace=T), nrow=10))
grph.t <- GetGraph()
P.t <- runif(nodes) # assume you meant to initialise all elements of P

#------------------------------------
# IMPLEMENTATON 1.
# A 'mirror' implementation. Some of the code relies
# on the specifics of package igraph, but I've tried to
# be as similar as possible. Hope it still makes sense!
#------------------------------------
B <- 0.1
D <- 0.05
grph <- grph.t
nodes <- vcount(grph)
E <- numeric(nodes)
P <- P.t

for(t in 0:99){
    cat('P:', P, '\n')# is this equivalent to 'Writed(P, "P")' ???
    graph.Nodes <- get.adjlist(grph) # returns a list of vectors,
where each vector is the nodes a node is connected to.
    id <- 0 # we loop over the vectors and so must index separately
    for(n in graph.Nodes){ # n is a vector containing the verticies
the vertex at index id+1 is connected to.
        id <- id+1
        product <- 1;
        for(item in n){
            product <- product * (1 - B * P[item+1]); # verticies are
indexed from 0. no operator*= in R.
        }
        E[id] <- product;
    }

    at <- 0
    for(i in 1:nodes){
        P[i] <- 1 - ((1 - P[i]) * E[i] + D * (1 - P[i]) * E[i] + 0.5 *
D * P[i] * (1 - E[i])); # we are accessing nodes in order so the
indexes are also ordered.
        if (P[i] < 0) P[i] <- 0;
    }
}

P # print the result

#------------------------------------
# IMPLEMENTATION 2.
# a more 'R-ish' implementation.
#------------------------------------
B <- 0.1
D <- 0.05
P <- P.t
grph <- grph.t

for(t in 0:99){
    E <- sapply(get.adjlist(grph), function(node) prod(1-B*P[node+1]))
    P <- 1 - ((1 - P) * E + D * (1 - P) * E + 0.5 * D * P * (1 - E))
}

P # print the result
#
2008/9/14 lesj_stather at hotmail.co.uk


I ran your example

Speed <- cars$speed
Distance <- cars$dist
[1]  4  4  7  7  8  9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 
15
[26] 15 16 16 17 17 17 18 18 18 18 19 19 19 20 20 20 20 20 22 23 24 24 24 24 
25
[1]   2  10   4  22  16  10  18  26  34  17  28  14  20  24  28  26  34  34 
46
[20]  26  36  60  80  20  26  54  32  40  32  40  50  42  56  76  84  36  46 
68
[39]  32  48  52  56  64  66  54  70  92  93 120  85

plot(Speed, Distance, panel.first = grid(8,8),
     pch = 0, cex = 1.2, col = "blue")
plot(Speed, Distance,
     panel.first = lines(stats::lowess(Speed, Distance), lty = "dashed"),
     pch = 0, cex = 1.2, col = "blue")

And got the following

Error in axis(side = side, at = at, labels = labels, ...) :
  too few arguments


I got a graph of the points with a dashed lined line through them but did 
not get any axes

I am runing R 2.7.2 under windowa XP Service Pack 2 on an Acer Extensa 5200


Les Stather
____________________________________________