Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,5 +1,6 @@
|
|||
[[image:resistor-mesh.svg]]
|
||||
|
||||
Given 10 × 10 grid nodes interconnected by 1Ω resistors as shown, find the resistance between point A and B.
|
||||
Given 10 × 10 grid nodes interconnected by 1Ω resistors as shown,
|
||||
find the resistance between point A and B.
|
||||
|
||||
See also [[http://xkcd.com/356/]]
|
||||
|
|
|
|||
3
Task/Resistor-mesh/00META.yaml
Normal file
3
Task/Resistor-mesh/00META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
category:
|
||||
- Electronics
|
||||
|
|
@ -3,42 +3,44 @@ import std.stdio, std.traits;
|
|||
enum Node.FP differenceThreshold = 1e-40;
|
||||
|
||||
struct Node {
|
||||
alias real FP;
|
||||
alias FP = real;
|
||||
enum Kind : size_t { free, A, B }
|
||||
|
||||
FP voltage = 0.0;
|
||||
private Kind kind = Kind.free;
|
||||
|
||||
@property Kind fixed() const pure nothrow { return kind; }
|
||||
/*const*/ private Kind kind = Kind.free;
|
||||
// Remove kindGet once kind is const.
|
||||
@property Kind kindGet() const pure nothrow @nogc {return kind; }
|
||||
}
|
||||
|
||||
Node.FP iter(size_t w, size_t h)(ref Node[w][h] m) pure nothrow {
|
||||
Node.FP iter(size_t w, size_t h)(ref Node[w][h] m) pure nothrow @nogc {
|
||||
static void enforceBoundaryConditions(ref Node[w][h] m)
|
||||
pure nothrow {
|
||||
pure nothrow @nogc {
|
||||
m[1][1].voltage = 1.0;
|
||||
m[6][7].voltage = -1.0;
|
||||
}
|
||||
|
||||
static Node.FP calcDifference(in ref Node[w][h] m,
|
||||
ref Node[w][h] d) pure nothrow {
|
||||
ref Node[w][h] d) pure nothrow @nogc {
|
||||
Node.FP total = 0.0;
|
||||
|
||||
foreach (i; 0 .. h)
|
||||
foreach (j; 0 .. w) {
|
||||
foreach (immutable i; 0 .. h) {
|
||||
foreach (immutable j; 0 .. w) {
|
||||
Node.FP v = 0.0;
|
||||
{
|
||||
size_t n = 0;
|
||||
if (i != 0) { v += m[i - 1][j].voltage; n++; }
|
||||
if (j != 0) { v += m[i][j - 1].voltage; n++; }
|
||||
if (i < h-1) { v += m[i + 1][j].voltage; n++; }
|
||||
if (j < w-1) { v += m[i][j + 1].voltage; n++; }
|
||||
if (i != 0) { v += m[i - 1][j].voltage; n++; }
|
||||
if (j != 0) { v += m[i][j - 1].voltage; n++; }
|
||||
if (i < h - 1) { v += m[i + 1][j].voltage; n++; }
|
||||
if (j < w - 1) { v += m[i][j + 1].voltage; n++; }
|
||||
v = m[i][j].voltage - v / n;
|
||||
}
|
||||
|
||||
d[i][j].voltage = v;
|
||||
if (m[i][j].fixed == Node.Kind.free)
|
||||
if (m[i][j].kindGet == Node.Kind.free)
|
||||
total += v ^^ 2;
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
|
@ -49,16 +51,16 @@ Node.FP iter(size_t w, size_t h)(ref Node[w][h] m) pure nothrow {
|
|||
enforceBoundaryConditions(m);
|
||||
if (calcDifference(m, difference) < differenceThreshold)
|
||||
break;
|
||||
foreach (i, const(Node[]) di; difference)
|
||||
foreach (j, ref const(Node) dij; di)
|
||||
foreach (immutable i, const di; difference)
|
||||
foreach (immutable j, const ref dij; di)
|
||||
m[i][j].voltage -= dij.voltage;
|
||||
}
|
||||
|
||||
Node.FP[EnumMembers!(Node.Kind).length] cur = 0.0;
|
||||
foreach (i, const(Node[]) di; difference)
|
||||
foreach (j, ref const(Node) dij; di)
|
||||
cur[m[i][j].fixed] += dij.voltage *
|
||||
(!!i + !!j + (i < h-1) + (j < w-1));
|
||||
foreach (immutable i, const di; difference)
|
||||
foreach (immutable j, const ref dij; di)
|
||||
cur[m[i][j].kindGet] += dij.voltage *
|
||||
(!!i + !!j + (i < h-1) + (j < w-1));
|
||||
|
||||
return (cur[Node.Kind.A] - cur[Node.Kind.B]) / 2.0;
|
||||
}
|
||||
|
|
@ -72,5 +74,5 @@ void main() {
|
|||
mesh[1][1] = Node( 1.0, Node.Kind.A);
|
||||
mesh[6][7] = Node(-1.0, Node.Kind.B);
|
||||
|
||||
writefln("R = %.19f", 2 / iter(mesh));
|
||||
writefln("R = %.19f", 2 / mesh.iter);
|
||||
}
|
||||
|
|
|
|||
40
Task/Resistor-mesh/Octave/resistor-mesh.octave
Normal file
40
Task/Resistor-mesh/Octave/resistor-mesh.octave
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
N = 10;
|
||||
NN = N*N;
|
||||
G = sparse(NN, NN);
|
||||
|
||||
node = 0;
|
||||
for row=1:N;
|
||||
for col=1:N;
|
||||
node++;
|
||||
if row > 1
|
||||
G(node, node)++;
|
||||
G(node, node - N) = -1;
|
||||
end
|
||||
if row < N;
|
||||
G(node, node)++;
|
||||
G(node, node + N) = -1;
|
||||
end
|
||||
if col > 1
|
||||
G(node, node)++;
|
||||
G(node, node - 1) = -1;
|
||||
end
|
||||
if col < N;
|
||||
G(node, node)++;
|
||||
G(node, node + 1) = -1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
current = sparse(NN, 1);
|
||||
|
||||
Ar = 2; Ac = 2; A = Ac + N*( Ar - 1 );
|
||||
Br = 7; Bc = 8; B = Bc + N*( Br - 1 );
|
||||
current( A ) = -1;
|
||||
current( B ) = +1;
|
||||
|
||||
voltage = G \ current;
|
||||
|
||||
VA = voltage( A );
|
||||
VB = voltage( B );
|
||||
|
||||
full( abs( VA - VB ) )
|
||||
71
Task/Resistor-mesh/Python/resistor-mesh-2.py
Normal file
71
Task/Resistor-mesh/Python/resistor-mesh-2.py
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import sys, copy
|
||||
from fractions import Fraction
|
||||
|
||||
def gauss(a, b):
|
||||
n, p = len(a), len(a[0])
|
||||
for i in range(n):
|
||||
t = abs(a[i][i])
|
||||
k = i
|
||||
for j in range(i + 1, n):
|
||||
if abs(a[j][i]) > t:
|
||||
t = abs(a[j][i])
|
||||
k = j
|
||||
if k != i:
|
||||
for j in range(i, n):
|
||||
a[i][j], a[k][j] = a[k][j], a[i][j]
|
||||
b[i], b[k] = b[k], b[i]
|
||||
t = 1/a[i][i]
|
||||
for j in range(i + 1, n):
|
||||
a[i][j] *= t
|
||||
b[i] *= t
|
||||
for j in range(i + 1, n):
|
||||
t = a[j][i]
|
||||
for k in range(i + 1, n):
|
||||
a[j][k] -= t*a[i][k]
|
||||
b[j] -= t * b[i]
|
||||
for i in range(n - 1, -1, -1):
|
||||
for j in range(i):
|
||||
b[j] -= a[j][i]*b[i]
|
||||
return b
|
||||
|
||||
def resistor_grid(p, q, ai, aj, bi, bj):
|
||||
n = p*q
|
||||
I = Fraction(1, 1)
|
||||
v = [0*I]*n
|
||||
a = [copy.copy(v) for i in range(n)]
|
||||
for i in range(p):
|
||||
for j in range(q):
|
||||
k = i*q + j
|
||||
if i == ai and j == aj:
|
||||
a[k][k] = I
|
||||
else:
|
||||
c = 0
|
||||
if i + 1 < p:
|
||||
c += 1
|
||||
a[k][k + q] = -1
|
||||
if i >= 1:
|
||||
c += 1
|
||||
a[k][k - q] = -1
|
||||
if j + 1 < q:
|
||||
c += 1
|
||||
a[k][k + 1] = -1
|
||||
if j >= 1:
|
||||
c += 1
|
||||
a[k][k - 1] = -1
|
||||
a[k][k] = c*I
|
||||
b = [0*I]*n
|
||||
k = bi*q + bj
|
||||
b[k] = 1
|
||||
return gauss(a, b)[k]
|
||||
|
||||
def main(arg):
|
||||
r = resistor_grid(int(arg[0]), int(arg[1]), int(arg[2]), int(arg[3]), int(arg[4]), int(arg[5]))
|
||||
print(r)
|
||||
print(float(r))
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
||||
# Output:
|
||||
# python grid.py 10 10 1 1 7 6
|
||||
# 455859137025721/283319837425200
|
||||
# 1.6089912417307297
|
||||
|
|
@ -1,36 +1,36 @@
|
|||
/*REXX pgm calculates resistance between any 2 points on a resister grid*/
|
||||
numeric digits 20 /*use moderate digits (precision)*/
|
||||
minVal=(1'e-'||(digits()*2)) / 1 /*calculate the threshold min val*/
|
||||
minVal = (1'e-' || (digits()*2)) / 1 /*calculate the threshold min val*/
|
||||
if 1=='f1'x then ohms = 'ohms' /*EBCDIC machine? Use 'ohms'. */
|
||||
else ohms = 'ea'x /* ASCII machine? Use Greek Ω.*/
|
||||
parse arg wide high Arow Acol Brow Bcol .
|
||||
say 'minVal = ' format(minVal,,,,0) ; say
|
||||
say 'resistor mesh is of size: ' wide "wide, " high 'high.' ; say
|
||||
parse arg high wide Arow Acol Brow Bcol .
|
||||
say 'minVal = ' format(minVal,,,,0) ; say
|
||||
say 'resistor mesh is of size: ' wide "wide, " high 'high.' ; say
|
||||
say 'point A is at (row,col): ' Arow","Acol
|
||||
say 'point B is at (row,col): ' Brow","Bcol
|
||||
@.=0; cell.=1
|
||||
@.=0; cell.=1
|
||||
do until $ <= minVal; $=0; v = 0
|
||||
@.Arow.Acol = +1 ; cell.Arow.Acol = 0
|
||||
@.Brow.Bcol = -1 ; cell.Brow.Bcol = 0
|
||||
|
||||
do i =1 for high; im=i-1; ip=i+1
|
||||
do j=1 for wide; jm=j-1; jp=j+1; n=0; v=0
|
||||
if i\==1 then do; v=v+@.im.j; n=n+1; end
|
||||
if j\==1 then do; v=v+@.i.jm; n=n+1; end
|
||||
if i<high then do; v=v+@.ip.j; n=n+1; end
|
||||
if j<wide then do; v=v+@.i.jp; n=n+1; end
|
||||
v=@.i.j-v/n; #.i.j=v; if cell.i.j then $=$+v*v
|
||||
end /*j*/
|
||||
end /*i*/
|
||||
do r=1 for High
|
||||
do c=1 for Wide; @.r.c=@.r.c-#.r.c
|
||||
end /*c*/
|
||||
end /*r*/
|
||||
do i=1 for high; im=i-1; ip=i+1
|
||||
do j=1 for wide; jm=j-1; jp=j+1; n=0; v=0
|
||||
if i\==1 then do; v=v+@.im.j; n=n+1; end
|
||||
if j\==1 then do; v=v+@.i.jm; n=n+1; end
|
||||
if i<high then do; v=v+@.ip.j; n=n+1; end
|
||||
if j<wide then do; v=v+@.i.jp; n=n+1; end
|
||||
v=@.i.j-v/n; #.i.j=v; if cell.i.j then $=$+v*v
|
||||
end /*j*/
|
||||
end /*i*/
|
||||
do r=1 for High
|
||||
do c=1 for Wide; @.r.c = @.r.c - #.r.c
|
||||
end /*c*/
|
||||
end /*r*/
|
||||
end /*until*/
|
||||
say
|
||||
Acur = #.Arow.Acol * sides(Arow,Acol)
|
||||
Bcur = #.Brow.Bcol * sides(Brow,Bcol)
|
||||
say 'resistance between point A and point B is: ' 4/(Acur-Bcur) ohms
|
||||
say 'resistance between point A and point B is: ' 4/(Acur-Bcur) ohms
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────sides subroutine────────────────────*/
|
||||
sides: parse arg i,j; !=0; if i\==1 & i\==high then !=!+2
|
||||
|
|
|
|||
70
Task/Resistor-mesh/Racket/resistor-mesh.rkt
Normal file
70
Task/Resistor-mesh/Racket/resistor-mesh.rkt
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#lang racket
|
||||
(require racket/flonum)
|
||||
|
||||
(define-syntax-rule (fi c t f) (if c f t))
|
||||
|
||||
(define (neighbours w h)
|
||||
(define h-1 (sub1 h))
|
||||
(define w-1 (sub1 w))
|
||||
(lambda (i j)
|
||||
(+ (fi (zero? i) 1 0)
|
||||
(fi (zero? j) 1 0)
|
||||
(if (< i h-1) 1 0)
|
||||
(if (< j w-1) 1 0))))
|
||||
|
||||
(define (mesh-R probes w h)
|
||||
(define h-1 (sub1 h))
|
||||
(define w-1 (sub1 w))
|
||||
|
||||
(define-syntax-rule (v2ref v r c) ; 2D vector ref
|
||||
(flvector-ref v (+ (* r w) c)))
|
||||
|
||||
(define w*h (* w h))
|
||||
|
||||
(define (alloc2 (v 0.))
|
||||
(make-flvector w*h v))
|
||||
|
||||
(define nghbrs (neighbours w h))
|
||||
|
||||
(match-define `((,fix+r ,fix+c) (,fix-r ,fix-c)) probes)
|
||||
(define fix+idx (+ fix+c (* fix+r w)))
|
||||
(define fix-idx (+ fix-c (* fix-r w)))
|
||||
(define fix-val
|
||||
(match-lambda**
|
||||
[((== fix+idx) _) 1.]
|
||||
[((== fix-idx) _) -1.]
|
||||
[(_ v) v]))
|
||||
|
||||
(define (calc-diff m)
|
||||
(define d
|
||||
(for*/flvector #:length w*h ((i (in-range h)) (j (in-range w)))
|
||||
(define v
|
||||
(+ (fi (zero? i) (v2ref m (- i 1) j) 0)
|
||||
(fi (zero? j) (v2ref m i (- j 1)) 0)
|
||||
(if (< i h-1) (v2ref m (+ i 1) j) 0)
|
||||
(if (< j w-1) (v2ref m i (+ j 1)) 0)))
|
||||
(- (v2ref m i j) (/ v (nghbrs i j)))))
|
||||
|
||||
(define Δ
|
||||
(for/sum ((i (in-naturals)) (d.v (in-flvector d)) #:when (= (fix-val i 0.) 0.))
|
||||
(sqr d.v)))
|
||||
|
||||
(values d Δ))
|
||||
|
||||
(define final-d
|
||||
(let loop ((m (alloc2)) (d (alloc2)))
|
||||
(define m+ ; do this first will get the boundaries on
|
||||
(for/flvector #:length w*h ((j (in-naturals)) (m.v (in-flvector m)) (d.v (in-flvector d)))
|
||||
(fix-val j (- m.v d.v))))
|
||||
|
||||
(define-values (d- Δ) (calc-diff m+))
|
||||
|
||||
(if (< Δ 1e-24) d (loop m+ d-))))
|
||||
|
||||
(/ 2
|
||||
(/ (- (* (v2ref final-d fix+r fix+c) (nghbrs fix+r fix+c))
|
||||
(* (v2ref final-d fix-r fix-c) (nghbrs fix-r fix-c)))
|
||||
2)))
|
||||
|
||||
(module+ main
|
||||
(printf "R = ~a~%" (mesh-R '((1 1) (6 7)) 10 10)))
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package require Tcl 8.6; # Or 8.5 with the TclOO package
|
||||
|
||||
# This code is structured as a class with a little trivial DSL parser so it is
|
||||
# easy to change what problem is being worked on.
|
||||
# This code is structured as a class with a little trivial DSL parser
|
||||
# so it is easy to change what problem is being worked on.
|
||||
oo::class create ResistorMesh {
|
||||
variable forcePoints V fixed w h
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue