I have an assignment in Mathematica, which I've already solved using Python and it's a bit hard to convert the code. Here's what I have done so far:
def sigmoid(x): # define the sigmoid function
return 1/(1+np.exp(-x))
def pos_list(node): # returns the neighborhood of node, A is a matrix of adjacency
return np.nonzero(A[node])[1]
def neg_list(node): # returns nodes that are not neighbors
return np.where(A[node]==0)[1]
I have these in Mathematica:
sigmoid[x_] := 1 / (1 + Exp[-x])
M := AdjacencyMatrix[undirectedEdges] (* this is A from above*)
posList[n_] := M[[n]]["NonzeroPositions"]
negList[n_] := Flatten[Position[Normal[M[[n]]], x_Integer /; x = 0]]
Now there is a longer function:
def next_choice(v,t,p,q):
positive = pos_list(v)
li = np.array([])
for pos in positive:
if pos==t:
li = np.append(li,1/p)
elif pos in pos_list(t):
li = np.append(li,1)
else :
li = np.append(li,1/q)
prob = li/li.sum()
return np.random.choice(positive,1,p=prob)[0]
So I am stuck here. This is what I've written:
nextChoice[v_, t_, p_, q_] :=
Module[{li, vpositive, tpositive, len, i, prob},
li = List[];
vpositive = posList[v];
tpositive = posList[t];
len = Length[vpositive];
For[i = 1, i <= len, i++,
If[vpositive[[i]][[1]] == t, AppendTo[li, 1/p],
If[Length[AnyTrue[tpositive, # == vpositive[[i]][[1]] &] > 0],
AppendTo[li, 1], AppendTo[li, 1/q]]];
];
prob = li/Total[li];
Return[RandomChoice[prob -> vpositive, 1][[1]]]
]
This list li
only has one element and I cannot figure out why it doesn't go through all the if statements. any ideas?
Edit: an example
mat = {{0, 1, 0, 0, 0}, {1, 0, 1, 0, 0}, {0, 1, 0, 1, 1}, {0, 0, 1, 0, 0} , {0, 0, 1, 0, 0}};
M = SparseArray[mat]
If we call nextChoice[1, 3, 0.5, 0.5], it should return a random node from the positive list.
Position[...,x_Integer/;x==0]
can bePosition[...,0]
,List[]
can be{}
. I'd write your for loop usingMap
, or usingTable
(asTable[...,{pos, vpositive}]
You don't needReturn
, the last expression will always be returned. It looks like the issue is inIf[Length[AnyTrue[...]>0],...]
. The result will always beIf[2,...]
(becauseLength[True>0]
is2
), which will stay unevaluated because2
is not a boolean. I'd also suggest to replace the entire condition withMemberQ[...]
$\endgroup$negativeList
,[]
and rewrote the condition toIf[MemberQ[tpositive,vpositive[[i]][[1]]]
. There is still something wrong. I am not sure how to useMap
orTable
, since the if statement is not a function that I can define before? $\endgroup$