# Python to Mathematica code bug

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.

• Without any example input, it will be hard to tell what exactly is going on. That being said: Position[...,x_Integer/;x==0] can be Position[...,0], List[] can be {}. I'd write your for loop using Map, or using Table (as Table[...,{pos, vpositive}] You don't need Return, the last expression will always be returned. It looks like the issue is in If[Length[AnyTrue[...]>0],...]. The result will always be If[2,...] (because Length[True>0] is 2), which will stay unevaluated because 2 is not a boolean. I'd also suggest to replace the entire condition with MemberQ[...] Commented May 5, 2021 at 11:26
• Thank you so much for the suggestions. I did correct the negativeList,[] and rewrote the condition to If[MemberQ[tpositive,vpositive[[i]][[1]]]. There is still something wrong. I am not sure how to use Map or Table, since the if statement is not a function that I can define before? Commented May 5, 2021 at 14:22

Here's my attempt at fixing your code:

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]

sigmoid[x_] := 1/(1 + Exp[-x])
posList[n_] := Flatten[M[[n]]["NonzeroPositions"]]
negList[n_] := Flatten[Position[Normal[M[[n]]], 0]]

nextChoice[v_, t_, p_, q_] :=
Module[
{vpositive, tpositive, prob},
vpositive = posList[v];
tpositive = posList[t];
prob = Table[
Which[pos == t,
1/p,
MemberQ[tpositive, pos],
1,
True,
1/q
],
{pos, vpositive}
];
RandomChoice[prob -> vpositive]
]

nextChoice[1, 3, 0.5, 0.5]
(* 2 *)


I won't go over all the changes (feel free to ask in the comments if something is unclear), but here are some of them:

• I changed posList to return a list of indices with the same format as negList
• I switched from the For loop to a Table
• Rather than appending one element to li per loop iteration, I simply use the list returned by Table
• I swapped the nested If to Which
• You don't need to normalize the weights given to RandomChoice
• If you don't specify 1 sample for RandomChoice, it will give you a single sample without a list by default
• I switched the broken condition to use MemberQ
• Thank you very much for your help, I really appreciate it! I understand all the changes that you have made, it looks very neat. Commented May 7, 2021 at 7:22
• @chris I have to do a lot of other parts for this assignment, but I needed an extra push towards the right direction. I hope you didn't mean it in a sarcastic way :) Commented May 7, 2021 at 7:24
• @mandella Good luck with your assignment! One other thing to note: Take a look at Echo, it's an amazing tool to help you debug functions, since you can easily monitor steps of a calculation Commented May 7, 2021 at 7:33
• Thank you very much! :) Great I will check Echo I think I will need that tool a lot in order to finish this task successfully :) Thank you also for this note! Commented May 7, 2021 at 8:26