Skip to content

Instantly share code, notes, and snippets.

@bmander
Last active February 12, 2016 20:07
Show Gist options
  • Save bmander/5d1dd8a835f7c3941f0d to your computer and use it in GitHub Desktop.
Save bmander/5d1dd8a835f7c3941f0d to your computer and use it in GitHub Desktop.
How to find negative currents between two fully connected layers
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Set conductances of connections, sum currents at each node"
]
},
{
"cell_type": "code",
"execution_count": 290,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"conductance from ith layer-1 node to jth layer-2 node\n",
"[[2 1]\n",
" [1 2]]\n",
"\n",
"concatenated currents into layer-1 nodes and layer-2 nodes\n",
"[4 6 9 1]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"G = np.array([[2,1],\n",
" [1,2]])\n",
"\n",
"i_in = [4, 6]\n",
"i_out = [ 9, 1]\n",
"\n",
"assert sum(i_in)==sum(i_out)\n",
"\n",
"i = np.hstack((i_in,i_out))\n",
"\n",
"print \"conductance from ith layer-1 node to jth layer-2 node\"\n",
"print G\n",
"print\n",
"\n",
"print \"concatenated currents into layer-1 nodes and layer-2 nodes\"\n",
"print i"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Find useful matrix"
]
},
{
"cell_type": "code",
"execution_count": 291,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 3. 0. -2. -1.]\n",
" [ 0. 3. -1. -2.]\n",
" [ 2. 1. -3. -0.]\n",
" [ 1. 2. -0. -3.]]\n",
"[[4]\n",
" [6]\n",
" [9]\n",
" [1]]\n"
]
}
],
"source": [
"def gen_matrix(G):\n",
" ul = np.identity(G.shape[0])*np.sum(G,1)\n",
" ur = -G\n",
" ll = G.T\n",
" lr = -np.identity(G.shape[0])*np.sum(G,0)\n",
" \n",
" A = np.vstack((np.hstack((ul,ur)),np.hstack((ll,lr))))\n",
" return A\n",
"\n",
"A = gen_matrix(G)\n",
"i = np.array([i]).T #convert to nx1 column vector\n",
"\n",
"print A\n",
"print i"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Use the useful matrix to find voltages at each node"
]
},
{
"cell_type": "code",
"execution_count": 292,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-0.04166667 1.70833333 -2.45833333 0.79166667]\n"
]
}
],
"source": [
"v = np.dot(np.linalg.pinv(A),i)\n",
"print v.T[0] #convert from 4x1 matrix to array"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Find voltage across every resistor-connection"
]
},
{
"cell_type": "code",
"execution_count": 293,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"v_in:\n",
"[[-0.04166667]\n",
" [ 1.70833333]]\n",
"\n",
"v_out:\n",
"[[-2.45833333 0.79166667]]\n",
"\n",
"v_ij:\n",
"[[ 2.41666667 -0.83333333]\n",
" [ 4.16666667 0.91666667]]\n"
]
}
],
"source": [
"v_in = v[:2]\n",
"v_out = v[2:].T\n",
"\n",
"print \"v_in:\"\n",
"print v_in\n",
"print\n",
"print \"v_out:\"\n",
"print v_out\n",
"print\n",
"\n",
"v_ij = v_in-v_out\n",
"\n",
"print \"v_ij:\"\n",
"print v_ij"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Find current across each connection"
]
},
{
"cell_type": "code",
"execution_count": 294,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"current i_ij, from input_i to output_j:\n",
"[[ 4.83333333 -0.83333333]\n",
" [ 4.16666667 1.83333333]]\n"
]
}
],
"source": [
"i_ij = v_ij*G\n",
"\n",
"print \"current i_ij, from input_i to output_j:\"\n",
"print i_ij"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##Check connection current sums agree with defined node currents"
]
},
{
"cell_type": "code",
"execution_count": 295,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"row-wise current sum; outgoing from input nodes:\n",
"[ 4. 6.]\n",
"\n",
"column-wise current sum; incoming into output nodes:\n",
"[ 9. 1.]\n"
]
}
],
"source": [
"print \"row-wise current sum; outgoing from input nodes:\"\n",
"print np.sum(i_ij,1)\n",
"\n",
"print\n",
"\n",
"print \"column-wise current sum; incoming into output nodes:\"\n",
"print np.sum(i_ij,0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Package the whole process up for easy re-use"
]
},
{
"cell_type": "code",
"execution_count": 296,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def find_currents(i_in,i_out,G):\n",
" i = np.hstack((i_in, i_out))\n",
" A = gen_matrix(np.array(G))\n",
" \n",
" v = np.dot(np.linalg.pinv(A),i)\n",
" \n",
" v_in = v[:v.size/2]\n",
" v_out = v[v.size/2:]\n",
" \n",
" v_in = np.array([v_in]).T\n",
" v_out = np.array([v_out])\n",
" \n",
" v_ij = v_in-v_out\n",
" i_ij = v_ij*G\n",
" \n",
" return v, i_ij"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But what if the currents aren't allowed to be negative? Set the conductance of the negative-current connection to zero!"
]
},
{
"cell_type": "code",
"execution_count": 297,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-0.875 2.125 -2.875 1.625]\n",
"[[ 4. -0.]\n",
" [ 5. 1.]]\n"
]
}
],
"source": [
"v, i_ij = find_currents([4,6],[9,1], [[2,0],[1,2]])\n",
"print v\n",
"print i_ij"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The question is: is this the _same_ as the same circuit with an ideal diode in serial with every resistor?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Appendix: random search for parameters resulting in negative current."
]
},
{
"cell_type": "code",
"execution_count": 298,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8\n",
"[ 0.35861801 0.64138199] [ 0.88645638 0.11354362]\n",
"[[ 0.98315345 0.44135492]\n",
" [ 0.50400044 0.32354132]]\n",
"[[ 0.39829282 -0.03967481]\n",
" [ 0.48816356 0.15321842]]\n"
]
}
],
"source": [
"np.random.seed(2)\n",
"for i in range(10):\n",
" i_in = np.random.uniform(size=2)\n",
" i_out = np.random.uniform(size=2)\n",
" i_in = i_in/np.sum(i_in)\n",
" i_out = i_out/np.sum(i_out)\n",
" \n",
" G = np.random.uniform(size=(2,2))\n",
" \n",
" v, i_ij = find_currents(i_in,i_out,G)\n",
" if np.any( i_ij < 0 ):\n",
" print i\n",
" print i_in,i_out\n",
" print G\n",
" print i_ij\n",
" break\n",
" \n",
"# i_in = np.array([ 4, 6])\n",
"# i_out = np.array([ 9, 1])\n",
"# G = [[ 2, 0],\n",
"# [ 1, 2]]\n",
"\n",
"# v,i= find_currents(i_in,i_out,G)\n",
"# print i\n",
"# print v\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment