Create mutable Digraph from an existing non-mutable subgraph_view - networkx

I do the following. But when I try to modify a node in new_graph I get a TypeError: 'AtlasView' object does not support item assignment
def get_my_nodes(source=None, distance=0):
pre = [n for n in nx.dfs_preorder_nodes(G, source=source, depth_limit=distance)]
post = [n for n in nx.dfs_preorder_nodes(G.reverse(), source=source, depth_limit=distance)]
return set(pre + post)
my_nodes = get_my_nodes(n, distance=dist)
def filter_node(n):
if n in my_nodes:
return True
return False
subgraph_view = nx.subgraph_view(G, filter_node=filter_node)
new_graph = nx.DiGraph(subgraph_view.copy())
new_graph['my_node']['weight'] = 25 # <- this raises a TypeError: 'AtlasView' object does not support item assignment

You are accessing the AtlasView, which is read only on the inner level (see the docs...).
The easiest solution imo is to use nx.set_node_attributes:
def get_my_nodes(source=None, distance=0):
pre = [n for n in nx.dfs_preorder_nodes(G, source=source, depth_limit=distance)]
post = [n for n in nx.dfs_preorder_nodes(G.reverse(), source=source, depth_limit=distance)]
return set(pre + post)
my_nodes = get_my_nodes(n, distance=dist)
def filter_node(n):
if n in my_nodes:
return True
return False
subgraph_view = nx.subgraph_view(G, filter_node=filter_node)
new_graph = nx.DiGraph(subgraph_view.copy())
#new_graph['my_node'] is an AtlasView object (read only)
nx.set_node_attributes(new_graph, {'my_node': 25}, name='weight')

Related

How do I use numba's "guvectorize" decorator to change two arrays in the same function?

I'm using numba's #guvectorize to change two different arrays. The code is:
#guvectorize([(int64[:], int64[:], int64[:], int64[:])], '(n),(n)->(n),(n)', target= 'parallel')
def g(x, y, res, res_two):
res = x
for i in range(x.shape[0]-1):
var = np.random.poisson((2),1)[0]
res_two[i] = var
res[i+1] = res[i] + res_two[i]
print("res[i+1] is", res[i+1], "for x[i] is", x[i])
q = (np.arange(5)) * 0
q[0] = 5
r = (np.arange(5)) * 0
g(q,r)
print("q is", q)
print("r is", r)
And the results printed out are:
As one can see, q is changing, but r isn't.
What must I do to use guvectorize to input two arrays and change those two arrays?

SSP Algorithm minimal subset of length k

Suppose S is a set with t elements modulo n. There are indeed, 2^t subsets of any length. Illustrate a PARI/GP program which finds the smallest subset U (in terms of length) of distinct elements such that the sum of all elements in U is 0 modulo n. It is easy to write a program which searches via brute force, but brute force is infeasible as t and n get larger, so would appreciate help writing a program which doesn't use brute force to solve this instance of the subset sum problem.
Dynamic Approach:
def isSubsetSum(st, n, sm) :
# The value of subset[i][j] will be
# true if there is a subset of
# set[0..j-1] with sum equal to i
subset=[[True] * (sm+1)] * (n+1)
# If sum is 0, then answer is true
for i in range(0, n+1) :
subset[i][0] = True
# If sum is not 0 and set is empty,
# then answer is false
for i in range(1, sm + 1) :
subset[0][i] = False
# Fill the subset table in botton
# up manner
for i in range(1, n+1) :
for j in range(1, sm+1) :
if(j < st[i-1]) :
subset[i][j] = subset[i-1][j]
if (j >= st[i-1]) :
subset[i][j] = subset[i-1][j] or subset[i - 1][j-st[i-1]]
"""uncomment this code to print table
for i in range(0,n+1) :
for j in range(0,sm+1) :
print(subset[i][j],end="")
print(" ")"""
return subset[n][sm];
I got this code from here I don't know weather it seems to work.
function getSummingItems(a,t){
return a.reduce((h,n) => Object.keys(h)
.reduceRight((m,k) => +k+n <= t ? (m[+k+n] = m[+k+n] ? m[+k+n].concat(m[k].map(sa => sa.concat(n)))
: m[k].map(sa => sa.concat(n)),m)
: m, h), {0:[[]]})[t];
}
var arr = Array(20).fill().map((_,i) => i+1), // [1,2,..,20]
tgt = 42,
res = [];
console.time("test");
res = getSummingItems(arr,tgt);
console.timeEnd("test");
console.log("found",res.length,"subsequences summing to",tgt);
console.log(JSON.stringify(res));

How to compare function value with a constant

I'm working with Python Scipy I have the next code:
...
t = np.linspace(0, simtime, points)
def Vbooster90(t):
return np.sin(t * 2 * np.pi*F_booster + 0.5 * np.pi)
def beam(t):
return np.sign(Vrfq(t) - Vrfq(bunchwidth)) * 0.5 + 0.5
def criteria(t):
return np.sign(Vbooster90(t))
def kicker(t):
if criteria(t) > 0:
k(t)=beam(t)
else:
k(t)=0
return k(t)
I have a problem with the last function kicker(t). I want to compare the function criteria(t) with zero at each value of t, and in case if criteria(t) is higher than zero, I want to assign kicker(t) to the value of function beam(t) at the same t value. I'm new to Python and don't know syntax well.
Modify the kicker function like following.
def kicker(t):
k = 0
if criteria(t) > 0:
k = beam(t)
return k
Thanks for answers, instead of defining a function I solved it next way:
kicker = np.empty(points)
i = np.arange(points)
time = np.empty(points)
time[i] = i*simtime/points
for i in range(points):
if criteria(time[i]) > 0:
kicker[i] = beam(time[i])
else:
kicker[i] = 0

class Matrix: AttributeError: Matrix instance has no attribute '__getitem__' in max(self, other) method

class Matrix:
def __init__(self, nr, nc):
self.NRows = nr
self.NCols = nc
self.data = [ [0]*self.NCols for r in range(self.NRows) ]
def max(self, other):
""" return: a matrix with as many rows as the shorter of self and other and as many columns as the narrower of self and other.
Each entry of the returned matrix should be the larger (the max) of the corresponding entries in self and other.
"""
minrows = min(other.NRows, self.NRows)
mincols = min(other.NCols, self.NCols)
M = Matrix(minrows, mincols)
for i in range(minrows):
for j in range(mincols):
M.data[i][j] = max(self.data[i][j], other[i][j])
return M
This code give Traceback in max when tested and output said:
...in max
M.data[i][j] = max(self.data[i][j], other[i][j])
AttributeError: Matrix instance has no attribute '__getitem__'
How to get rid of this error? Where I made mistake?. Please help someone.
You should use this :
M.data[i][j] = max(self.data[i][j], other.data[i][j])
instead of
M.data[i][j] = max(self.data[i][j], other[i][j])

How to find the Intersection of n arrays

I have n arrays or variable length
arr1 = [1,2,3]
arr2 = [1,3,5,8]
....
How can I compute the intersection of those n arrays ?
Consider checking out underscore.js library. It provides function for what you need and a bunch of other usefull functions.
Example from docs:
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2]
Simple plain JS implementation can be found here. Same idea in CoffeeScript:
intersect_all = (lists) ->
if lists.length is 0
return []
else return lists[0] if lists.length is 1
partialInt = lists[0]
i = 1
while i < lists.length
partialInt = intersection(partialInt, lists[i])
i++
partialInt
The most efficient way is to use hashsets:
function hashset (elements) {
var i, set = {};
if (!Array.isArray(elements)) return elements;
for (i = 0; i < elements.length; i++) {
set[elements[i]] = true;
}
return set;
};
function intersect (a, b) {
var k
, s1 = hashset(a)
, s2 = hashset(b)
, s3 = {}
for (k in s1) {
if (s2[k]) s3[k] = true;
}
return s3;
};
Object.keys(intersect(arr1,arr2));
// ["1", "3"]
You will find CoffeeScript source of this code, benchmarks for it and some additional information in this question.
If you're going to to intersect huge arrays then I strongly recommend you to use this approach.
Either just use something like _.intersection or study the source of that implementation and rewrite it if you like.