How to add ports to nodes in an Agraph_t? - graphviz

I'm trying to add ports to nodes, but apparently I'm missing something.
aginit();
Agraph_t *g = agopen("g", AGFLAG_DIRECTED);
Agsym_t *symRankdir = agraphattr(g, "rankdir", "LR");
Agsym_t *symShape = agnodeattr(g, "shape", "Mrecord");
Agsym_t *symLabel = agnodeattr(g, "label", "");
Agnode_t *n1 = agnode(g, "n1");
n1->attr[1] = "n1|<p1>p1|<p2>p2";
Agnode_t *n2 = agnode(g, "n2");
n2->attr[1] = "n2|<p1>p1|<p2>p2";
Agedge_t *e = agedge(g, n1, n2);
e->u.tail_port.defined = true;
e->u.tail_port.name = "p1";
e->u.head_port.defined = true;
e->u.head_port.name = "p2";
FILE *fp = fopen(argv[1], "w");
agwrite(g, fp);
Output:
digraph g {
graph [rankdir=LR];
node [shape=Mrecord];
n1 [label="n1|<p1>p1|<p2>p2"];
n2 [label="n2|<p1>p1|<p2>p2"];
n1 -> n2;
}
The edge in the output should be n1:p1 -> n2:p2. What needs to be set in the code to make that happen?

Replace this --
e->u.tail_port.defined = true;
e->u.tail_port.name = "p1";
e->u.head_port.defined = true;
e->u.head_port.name = "p2";
-- with this --
#define TAILX 1
#define HEADX 2
agxset(e, TAILX, "p1");
agxset(e, HEADX, "p2");
(I figured it out from looking at the Graphviz source code -- lib/graph/parser.y and lib/graph/libgraph.h.)

Related

How to implement snapping effect and collision detection between two objects using Threejs?

We are able to detect the collision but could not implement a snapping/magnetic effect like Snap edges of objects to each other and prevent overlap
we need help with 3D objects here and we are using Vec3 for the active object's position.
With the following approach, collision detection is working perfectly for all cases, and magnetic effect is somehow working - not perfectly.
It's working well when the object is moving along x or z-axis but when the object's movement is in diagonal direction (moving along x and z-axis simultaneously) that is where the problem comes.
Though am not satisfied with the following approach that's why am looking for new approach to implement both magnetic and collision detection features.
It is not necessary to have the solution in Threejs, any general solution or algorithm of coordinates can be converted into Threejs.
let collide = this.detectCollisionCubes(activeObject, collidingObject, vec3);
let magneticEffect = new MagneticEffect(activeObject, vec3, collidingObject);
vec3 = magneticEffect.setNewPosition();
activeObject.position.copy(vec3);
detectCollisionCubes = function(a, d, vec3){
// a is active object's positon
// d is colliding object
let aHeight = Math.abs(a.getHeight());
let aWidth = Math.abs(a.getWidth());
let aDepth = Math.abs(a.getDepth());
let b1 = vec3.y - aHeight / 2;
let t1 = vec3.y + aHeight / 2;
let r1 = vec3.x + aWidth / 2;
let l1 = vec3.x - aWidth / 2;
let f1 = vec3.z - aDepth / 2;
let B1 = vec3.z + aDepth / 2;
let dHeight = Math.abs(d.getHeight());
let dWidth = Math.abs(d.getWidth());
let dDepth = Math.abs(d.getDepth());
let b2 = d.position.y - dHeight / 2;
let t2 = d.position.y + dHeight / 2;
let r2 = d.position.x + dWidth / 2;
let l2 = d.position.x - dWidth / 2;
let f2 = d.position.z - dDepth / 2;
let B2 = d.position.z + dDepth / 2;
if (t1 < b2 || r1 < l2 || b1 > t2 || l1 > r2 || f1 > B2 || B1 < f2) {
return false;
}
return true;
}
Trying to create magnetic effect via
this.currentObject = currentObject;
this.collisionObject = collisionObject;
this.collisionType = null;
this.objectType = null;
this.currentPosition = currentPosition;
this.currentObjectHeight = Math.abs(currentObject.getHeight());
this.currentObjectWidth = Math.abs(currentObject.getWidth());
this.collisionObjectHeight = Math.abs(collisionObject.getHeight());
this.collisionObjectWidth = Math.abs(collisionObject.getWidth());
this.collisionObjectDepth = Math.abs(collisionObject.getDepth());
this.objectTop = currentObject.position.y + (this.currentObjectHeight/2);
this.objectBottom = currentObject.position.y - (this.currentObjectHeight/2);
this.collideTop = collisionObject.position.y + (this.collisionObjectHeight/2);
this.collideBottom = collisionObject.position.y - (this.collisionObjectHeight/2);
this.zAxisDifference = Math.abs(Math.abs(currentPosition.z) - Math.abs(collisionObject.position.z));
this.xAxisDifference = Math.abs(Math.abs(currentPosition.x) - Math.abs(collisionObject.position.x));
// Extra code here
if (
this.objectTop < this.collideBottom
) {
this.collisionType = collisionTypes.verticalBottom;
} else if (
this.objectBottom > this.collideTop
) {
this.collisionType = collisionTypes.verticalTop;
} else if (
this.currentPosition.x > this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXLeft;
} else if (
this.currentPosition.x < this.collisionObject.position.x &&
this.zAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalXRight;
} else if (
this.currentPosition.z > this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZLeft;
} else if (
this.currentPosition.z < this.collisionObject.position.z &&
this.xAxisDifference < 2
) {
this.collisionType = collisionTypes.horizentalZRight;
}
MagneticEffect.prototype.setNewPosition = function () {
if (this.collisionType === collisionTypes.verticalBottom) {
this.currentPosition.y = this.collideBottom + 0.5;
} else if (this.collisionType === collisionTypes.verticalTop) {
this.currentPosition.y = this.collideTop - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXRight) {
this.currentPosition.x = this.collisionObject.position.x - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalXLeft) {
this.currentPosition.x = this.collisionObject.position.x + this.collisionObjectWidth + 0.5;
} else if (this.collisionType === collisionTypes.horizentalZRight) {
this.currentPosition.z = this.collisionObject.position.z - this.collisionObjectWidth - 0.5;
} else if (this.collisionType === collisionTypes.horizentalZLeft) {
this.currentPosition.z = this.collisionObject.position.z + this.collisionObjectWidth + 0.5;
}
return this.currentPosition;
};

Creating a requirement prioritization function in Python 3 program for a Salp Swarm Optimization

I want to be able to use a text file of requirements to be prioritized.
I want to male swarm_size,min_values and maximum_values inputs from text file.
SSA Function
def salp_swarm_algorithm(swarm_size = 5, min_values = [-5,-5], max_values = [5,5], iterations = 50):
count = 0
position = initial_position(swarm_size = swarm_size, min_values = min_values, max_values = max_values)
food = food_position(dimension = len(min_values))
while (count <= iterations):
print("Iteration = ", count, " Requirement = ", food.iloc[food['Fitness'].idxmin(),-1])
c1 = 2*math.exp(-(4*(count/iterations))**2)
food = update_food(position, food)
position = update_position(position, food, c1 = c1, min_values = min_values, max_values = max_values)
count = count + 1
print(food.iloc[food['Fitness'].idxmin(),:].copy(deep = True))
return food.iloc[food['Fitness'].idxmin(),:].copy(deep = True)

why I get max_weights=1 after gradient check?

I set a 3 layers neural network,it has 2 hidden layers,But when I try to implement gradient check ,I got my max_weigh=1 ,which means I have some error in my backprop.here are my backprop function,I really need some help
is there something wrong with my codes?
thanks!
def loss(self,X,y,reg = 0.0):
#forward prop
W1, b1 = self.params['W1'], self.params['b1']
W2, b2 = self.params['W2'], self.params['b2']
W3, b3 = self.params['W3'], self.params['b3']
N,D = X.shape
H1out = np.maximum(0,X.dot(W1)+b1) #H1out (N,H1)
H2out = np.maximum(0,H1out.dot(W2)+b2) #H2out (N,H2)
scores = None
scores = H2out.dot(W3)+b3
scores_shift = scores-np.max(scores,axis = 1).reshape(-1,1)
softmaxout = np.exp(scores_shift)/np.sum(np.exp(scores_shift),axis=1).reshape(-1,1)
loss_main = None
loss = None
loss_main = -np.sum(np.log(softmaxout[range(N),list(y)]))
loss = loss_main/N + reg*np.sum(W1*W1)*np.sum(
W2*W2)+np.sum(W3*W3)
#backward prop
dscores = softmaxout.copy() #dscores (N,C)
dscores[range(N),list(y)] -= 1
dscores /= N
dW3 = H2out.T.dot(dscores)
db3 = np.sum(dscores,axis = 0)
dh2 = dscores.dot(W3.T) #dh2 (N,H2)
dh_Relu2 = (H2out > 0) * dh2 #dh_ReLu2 (N,H2)
dW2 = H1out.T.dot(dh_Relu2)
db2 = np.sum(dh_Relu2,axis = 0)
dh1 = dh_Relu2.dot(W2.T) #dh1 (N,H1)
dh_Relu1 = (H1out>0) * dh1
dW1 = X.T.dot(dh_Relu1)
db1 = np.sum(dh_Relu1,axis = 0)
grad = {}
grad['W1'] = dW1
grad['b1'] = db1
grad['W2'] = dW2
grad['b2'] = db2
grad['W3'] = dW3
grad['b3'] = db3
return loss,grad

Debuging all the code computing and sorting equivalence classes

I have this function compute an equivalence class
let eq_class m i =
let column = m.(i)
and set = ref [] in
Array.iteri begin fun j l ->
if j = i || column.(j) && m.(j).(i) then
set := j :: !set else ignore l
end column;
!set;;
and this function to collect all the classes are equivalence
let eq_classes m =
let classes = ref [] in
Array.iteri begin fun e _ ->
if not (List.exists (List.mem e) !classes) then
classes := eq_class m e :: !classes
end m;
!classes;;
I have this function to compare two equivalence classes:
let cmp_classes m c c' = if c = c' then 0 else
match c, c' with
| i :: _, j :: _ -> if m.(i).(j) then 1 else -1
| _ -> assert false
After I used this function to sort it by using List.sort
let sort_eq_classes m = List.sort (cmp_classes m);;
My matrix is an boolean matrix, and I computed it with transitive closure.
let transClosure m =
let n = Array.length m in
for k = 0 to n - 1 do
let mk = m.(k) in
for i = 0 to n - 1 do
let mi = m.(i) in
for j = 0 to n - 1 do
mi.(j) <- max mi.(j) (min mi.(k) mk.(j))
done;
done;
done;
m;;
let tc = transClosure matrix
let eq = eq_classes tc
let sort_eq = sort_eq_classes tc eq
I tested with many counter example to test all these functions, for example with the graph (matrix)
EDIT
matrix:
a <-> b c <-> d
|
v
e
matrix_2:
a <-> b -> e -> f
| |
v v
h <------- g
| |
v v
u k
I input the boolean matrix:
let matrix =
[|
[|false; true; false; false; false|];
[|true; false; false; false; false|];
[|false; false; false; true; false|];
[|false; false; true; false; false|];
[|false; false; false; false; false|];
|];;
let matrix_2 =
[|
[| false; false; false; false; false; false; false; false |];
[| false; false; false; false; false; false; false; false |];
[| false; false; false; true; false; false; true; false |];
[| false; false; true; false; true; false; false; false |];
[| true; false; false; false; false; true; false; false |];
[| false; true; false; false; false; false; true; false |];
[| false; false; false; false; false; false; false; true |];
[| false; false; false; false; false; false; false; false |];
|]
output of matrix 1:
equivalence classes: e d c b a
sort equivalence classes: e d c b a
output of matrix 2:
equivalence classes: u h g e b a k f
sort equivalence classes : u h k g f e b a
And the result is correct order like I expected. But when I test it with my data, which is an xsds data, more complicated depended relations. It output for me a wrong order. I had test with function transform to boolean matrix from xsds, and tested transitive closure, it is correct. So I think may be their is some bugs in my functions, (eq_class) or (cmp_classes).
Could you please help me to see what wrong in these code?
The problem is in cmp_classes function.
From your source code:
(* We check that if two elements are in the same equivalence class they are
equal (0); if they have a path from i to j then i < j (-1)
otherwise i > j (1). We assumes that: each equivalence class only
appears once and each equivalence class contains at least one
element. *)
let cmp_classes m c c' = if c = c' then 0 else
match c, c' with
| i :: _, j :: _ -> if m.(i).(j) then 1 else -1
| _ -> assert false
Obviously, your code doesn't fulfill your requirement. Several errors could be mentioned:
If m.(i).(j) = true, you don't compare between i and j at all.
If m.(i).(j) = false, you suppose to compare other combinations than i and j, but here you wrongly returns -1.
You only compare using the heads of c and c' and ignore other elements while you suppose to use any pair of elements in two lists before reaching a conclusion.
In your small examples, you got correct results because equivalence classes often have one element. Since they are collected in the order that there is no path from former ones to later ones, your returning of -1 is fortunately correct. It's no longer the case with arbitrary input from xsd trees.
It's not difficult to fix the function if you can define it clearly. Now I still don't know the order of two equivalence classes without any path connecting them together ({a,b} and {c, d} classes in matrix).
In order that you can test your fix more easily, this is a small example which will produce a wrong order:
a <-> b c <-> d
^ ^ ^ ^
| | | |
e e e e

MS CAPI PRIVATEKEYBLOB to RSA*

I implemented this and am getting error:0407B07B:rsa routines:RSA_check_key:d e not congruent to 1
BitLen 1024, ModLen 128, Prime1,Prime2,Exponent1,Exponent2,Coefficient lengths =64
PrivateExponent Len = 128
RSA* blobtorsa()
{
BN_set_word(rsa->e, prsahdr->pubexp);
lend_tobn(rsa->n, pbmod, cbmod);
lend_tobn(rsa->p, pbprime1, cbprimes);
lend_tobn(rsa->q, pbprime2, cbprimes);
lend_tobn(rsa->d, pbprivexp, cbprivexp);
// d mod ( p - 1 )
BN_mod_sub(rsa->dmp1, rsa->d, BN_value_one(), rsa->p, ctx);
// d mod (q-1)
BN_mod_sub(rsa->dmq1, rsa->d, BN_value_one(), rsa->q, ctx);
BIGNUM* negone = BN_new();
BN_set_word(negone, -1);
// q^-1 mod p
BN_mod_exp(rsa->iqmp, rsa->q, negone, rsa->p, ctx);
if ( RSA_check_key(rsa) == 0 )
{
print error
error:0407B07B:rsa routines:RSA_check_key:d e not congruent to 1
}
}
For anyone else wondering - once you get the pointers and size to the separate
items in the structure:
{
BIGNUM* temp = BN_new();
rsa->e = BN_new();
BN_set_word(rsa->e, prsapk->pubexp);
// set n, p, q and d from structures
rsa->n = BN_new();
lend_tobn(rsa->n, pbMod, cbMod);
rsa->p = BN_new();
lend_tobn(rsa->p, pbPrime1, cbPrime1);
rsa->q = BN_new();
lend_tobn(rsa->q, pbPrime2, cbPrime2);
rsa->d = BN_new();
lend_tobn(rsa->d, pbPrivateExponent, cbPrivateExponent);
// calculate the remainder of properties
// d mod (p-1)
rsa->dmp1 = BN_new();
BN_copy(temp, rsa->p);
BN_sub_word(temp, 1);
BN_mod(rsa->dmp1, rsa->d, temp, ctx);
// d mod (q-1)
rsa->dmq1 = BN_new();
BN_copy(temp, rsa->q);
BN_sub_word(temp, 1);
BN_mod(rsa->dmq1, rsa->d, temp, ctx);
// q^-1 mod p
rsa->iqmp = BN_new();
BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);
BN_free(temp);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
ERR_clear_error();
if ( RSA_check_key(rsa) == 1 )
{
}
}

Resources