chiark / gitweb /
three-resistor combinations - but not very good because too dense so too many pages
authorian <ian>
Mon, 27 Feb 2006 01:55:51 +0000 (01:55 +0000)
committerian <ian>
Mon, 27 Feb 2006 01:55:51 +0000 (01:55 +0000)
misc/divider-table.pl

index fbd6c6a33dcdd0ba18720c5f7fceb95e7d3e8672..4aa66e2dc5ca48f5e5a82b779dafee2f0fa467c1 100755 (executable)
@@ -1,11 +1,22 @@
 #!/usr/bin/perl -w
 
+# for three-resistor combinations,
+# ./divider-table.pl -t |atp >ps -p -f Courier5:0.575,0,0,0.7 -B -M 18,15,15,15
+#  and then print on >=600dpi printer, preferably better
+
 use strict;
+use POSIX;
 
 our(@e12) = qw(10 12 15 18 22 27 33 39 47 56 68 82);
 our(@ex24) = qw(11 13 16 20 24 30 36 43 51 62 75 91);
 our(@e24)= sort @e12, @ex24;
 
+our (@series,$three);
+
+"@ARGV" =~ m/^(?:\-(?:t|12|24)+)?$/ or die;
+@series = "@ARGV" =~ m/12/ ? @e12 : @e24;
+$three = "@ARGV" =~ m/t/;
+
 our ($tlin,$tlog,@byrat);
 
 sub thead ($$) {
@@ -51,32 +62,54 @@ sub fracfit ($$) {
 
 sub scan () {
     my ($row,$col,$lin,$log,$rownum);
+    my ($combe,$combo,$combw,$combwe,$den,$denp);
     @byrat = ();
     thead(\$tlin,'X/Y [*10^k]');
     thead(\$tlog,'frac(L(X/Y))');
-    for $col (@e24) {
+    for $col (@series) {
        chead(\$tlin,$col);
        chead(\$tlog,$col);
     }
     theadend(\$tlin);
     theadend(\$tlog);
     $rownum= 0;
-    for $row (@e24) {
+    for $row (@series) {
        rhead(\$tlin,$row);
        rhead(\$tlog,$row);
-       for $col (@e24) {
-           $lin= $col*1.0 / $row;
-           $log= log($lin)/log(10) + 1.0;
-
-           cell(\$tlin, mul10fit($lin,5));
-           cell(\$tlog, fracfit($log,5));
-
-           if ($col < $row) { $lin *= 10; }
-           next if $row==$col;
-           push @byrat, { Num => $col,
-                          Den => $row,
-                          Lin => $lin,
-                          Log => $log };
+       for $col (@series) {
+           for $combo (('', '|', '+')) {
+               next if length($combo) and not $three;
+               for $combw (length($combo) ? @series : ('')) {
+                   for $combe (length($combo) ? (0, 1, 2) : (0,)) {
+                       if ($combo eq '') {
+                           $den= $denp= $row;
+                       } else {
+                           $combwe= $combw * pow(10, -2 + $combe);
+                           $den= $combo eq '+' ? $row + $combwe :
+                               1.0/(1.0/$row + 1.0/$combwe);
+                           $denp= $combw;
+                           $denp =~ s/.{$combe}/$&\./;
+                           $denp= $row.$combo.$denp;
+                           next if grep {
+                               abs(fmod(abs(log($_/$den)) + 0.1,
+                                        log(10)) - 0.1) < 1e-6
+                               } @series;
+                       }
+                       $lin= $col*1.0 / $den;
+                       while ($lin < 1000) { $lin *= 10; }
+                       $log= log($lin)/log(10) + 1.0;
+
+                       cell(\$tlin, mul10fit($lin,5));
+                       cell(\$tlog, fracfit($log,5));
+
+                       next if $row==$col;
+                       push @byrat, { Num => $col,
+                                      Den => $denp,
+                                      Lin => $lin,
+                                      Log => $log };
+                   }
+               }
+           }
        }
        rend(\$tlin,$rownum);
        rend(\$tlog,$rownum);
@@ -97,10 +130,24 @@ sub ptable ($) {
 
 sub sortbyrat () {
     @byrat= sort {
-       $a->{Lin} <=> $b->{Lin}
+       $a->{Lin} <=> $b->{Lin} or
+       $a->{Num} <=> $b->{Num}
     } @byrat;
 }
 
+sub uniqbyrat () {
+    my ($last,$i,$t,@byratnew);
+    @byratnew= ();
+    $last= 'x';
+    for $i (@byrat) {
+       $t= "$i->{Num} $i->{Lin}";
+       next if $t eq $last;
+       push @byratnew, $i;
+       $last= $t;
+    }
+    @byrat= @byratnew;
+}
+
 sub byratcol ($$$) {
     my ($or,$cwr,$colnum) = @_;
     $$or .= '  ' if $colnum;
@@ -109,19 +156,21 @@ sub byratcol ($$$) {
 
 sub printbyrat () {
     use integer;
-    my ($brcols) = 8;
+    my ($brcols) = $three ? 19 : 8;
     my ($brrows) = (@byrat+$brcols-1) / $brcols;
     my ($byrat,$o,$colnum,$rownum,$cw);
     $o= ''; 
     for ($colnum=0; $colnum<$brcols; $colnum++) {
        byratcol(\$o,\$cw,$colnum);
-       $o .= sprintf("N/D %".($cw+1)."s %s",
-                     'Q*10^k','fc(Lg)');
+       $o .= sprintf("N:D%s %".($cw+1)."s",
+                     $three ? '[&X]' : '',
+                     'Q*10^k');
+       $o .= sprintf(" %s", $three ? '' : 'fc(Lg)');
     }
     $o .= "\n";
     for ($colnum=0; $colnum<$brcols; $colnum++) {
        byratcol(\$o,\$cw,$colnum);
-       $o .= '-' x (5+1+$cw+1+5);
+       $o .= '-' x (5+1+$cw+($three ? 4 : 1+5));
     }
     $o .= "\n";
     for ($rownum=0; $rownum<$brrows; $rownum++) { 
@@ -129,10 +178,10 @@ sub printbyrat () {
            $byrat= $byrat[$colnum*$brrows + $rownum];
            next unless defined $byrat;
            byratcol(\$o,\$cw,$colnum);
-           $o .= sprintf("%2s/%-2s %${cw}s %s",
+           $o .= sprintf("%2s:%-".($three ? 6 : 2)."s %${cw}s",
                          $byrat->{Num}, $byrat->{Den},
-                         mul10fit($byrat->{Lin}, $cw),
-                         fracfit($byrat->{Log}, 5));
+                         mul10fit($byrat->{Lin}, $cw));
+           $o .= sprintf(" %s", fracfit($byrat->{Log}, 5)) unless $three;
        }
        $o .= "\n";
     }
@@ -141,8 +190,11 @@ sub printbyrat () {
 
 print "\n" or die $!;
 scan();
-ptable($tlin);
-ptable($tlog);
+if (!$three) {
+    ptable($tlin);
+    ptable($tlog);
+}
 
 sortbyrat();
+uniqbyrat() if $three;
 printbyrat();