#!g:\mtapps\perl\bin
#use GD::Graph;
#############################
#Author = David Daycock
#Date = May, 2004
#############################
&INTRO;
&CHOICE;
sub INTRO
{
print <<EOF
******************************************************
* *
* *
* Bath Temperature Calculation Utility *
* ver. 1.0.0 *
* *
* by: *
* David Daycock *
* *
* *
* *
******************************************************
EOF
;
}
sub CHOICE
{
print("\n1. Predict Temperature for a given etch rate");
print("\n2. Predict Etch Rate for a given temperature");
print("\n3. Statistics on my data");
print("\n4. Information and assumptions");
print("\n5. Quit");
print("\n\nSelection: ");
$pick = <STDIN>;
if ($pick == 1)
{
&TtoER;
}
elsif ($pick == 2)
{
&ERtoT;
}
elsif ($pick == 3)
{
&STAT;
}
elsif ($pick == 4)
{
&INFO;
}
elsif ($pick == 5)
{
&QUIT;
}
else
{
print("I need a numerical answer!\n");
&CHOICE;
};
}
sub BASICS
{
print("\nYou need to input our data in x,y pairs. Press ENTER to
+finish.\n");
print("If using this for Temperature and Etch Rate calcs, X should
+ be Temp\n");
print("and Y should be the etch rate.\n");
for ($i = 0; 1; $i++)
{
$numdis = $i+1;
print("\nX$numdis = ");
$x[$i] = <STDIN>;
chomp $x[$i];
if ($x[$i] !~ m/\d/)
{
pop @x;
last;
}; #if a digit is not entered, leave the loop.
print("\nY$numdis = ");
$y[$i] = <STDIN>;
chomp $y[$i];
}
@xstore = @x;
@ystore = @y;
$xref = \@x; #this is a reference for later putting into r squared
+ functions and slope functions, etc...
$yref = \@y; #remember, "perldoc perlreftut" for information on re
+ferences....
}
sub STAT
{
&BASICS;
&LINorARH;
my $avgX = average(@x);
my $avgY = average(@y);
my ($slope, $intercept, $rsquared) = linearfit($xref, $yref);
if ($LINorARH == 1)
{
print("\n\nAVERAGE of Xs:\t\t\t$avgX\n");
print("AVERAGE of Ys:\t\t\t$avgY\n");
print("Slope of best fit line:\t\t$slope\n");
print("Intercept of best fit line:\t$intercept\n");
print("R-squared of fit:\t\t$rsquared\n");
}
elsif ($LINorARH == 2)
{
$expA = exp($intercept);
$k = -1 * $slope;
print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n")
+;
print("A:\t\t\t$expA\n");
print("k:\t\t\t$k\n");
print("R-squared of fit:\t$rsquared\n");
}
elsif ($LINorARH == 3)
{
$expA = exp($intercept);
$k = 1 * $slope;
print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\
+n");
print("A:\t\t\t$expA\n");
print("k:\t\t\t$k\n");
print("R-squared of fit:\t$rsquared\n");
}
&ASK;
}
sub LINorARH
{
print("Is your data:\n");
print("1. Linear\n");
print("2. Fit to Arrhenius Equation\n");
print("3. Exponential\n");
print("Choice: ");
$LINorARH = <STDIN>;
chomp $LINorARH;
if ($LINorARH == 2)
{
@x = map { 1 / $x[$_]} 0..$#x;
@y = map {log $y[$_]} 0..$#y;
$xref = \@x;
$yref = \@y;
}
elsif ($LINorARH == 1)
{
@x = @x;
@y = @y;
}
elsif ($LINorARH == 3)
{
@x = @x;
@y = map {log $y[$_]} 0..$#y;
$xref = \@x;
$yref = \@y;
}
else
{
print("You did not enter a number!");
&LINorARH;
}
}
sub ERtoT
{
&BASICS;
&LINorARH;
print("What is the desired etch rate: ");
$er = <STDIN>;
chomp($er);
my ($m, $b, $rsquared) = linearfit($xref, $yref);
if ($LINorARH == 1)
{
$temp = ($er - $b) / $m;
print("\nEtch Rate at $temp deg\.C = $er\n");
}
elsif ($LINorARH == 2)
{
$A = exp($b);
$k = -1 * $m;
$temp = $k / (log($A) - log($er));
print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n")
+;
print("Etch Rate at $temp deg\.C = $er\n");
}
elsif ($LINorARH == 3)
{
$A = exp($b);
$k = 1 * $m;
$temp = (log($er) - log($A)) / $k;
print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\
+n");
print("Etch Rate at $temp deg\.C = $er\n");
}
&ASK;
}
sub TtoER
{
&BASICS;
&LINorARH;
print("At what temperature would you like to predict the etch rate
+: ");
$temp = <STDIN>;
chomp($temp);
my ($m, $b, $rsquared) = linearfit($xref, $yref);
if ($LINorARH == 1)
{
$er = ($m * $temp) + $b;
print("\nEtch Rate at $temp deg\.C = $er\n");
}
elsif ($LINorARH == 2)
{
$A = exp($b);
$k = -1 * $m;
$er = $A * exp(-$k/$temp);
print("\n\nArrhenius Equation of type y \= A\*exp\(-k\/x\)\n")
+;
print("Etch Rate at $temp deg\.C = $er\n");
}
elsif ($LINorARH == 3)
{
$A = exp($b);
$k = 1 * $m;
$er = $A*exp($k * $temp);
print("\n\nExponential Equation of type y \= A\*exp\(k \* x\)\
+n");
print("Etch Rate at $temp deg\.C = $er\n");
}
&ASK;
}
sub ASK
{
print("\nWould you like to save your data table to a file (y): ");
$savedata = <STDIN>;
chomp($savedata);
if ($savedata eq "y" || $savedata eq "Y")
{
print("\nFile name: ");
$fname = <STDIN>;
chomp($fname);
print("\nFile $fname\.xls saved to desktop.\n");
$path = "$ENV{'HOMEDRIVE'}"."$ENV{'HOMEPATH'}"."\\"."Desktop".
+"\\";
open(AFILE, ">$path"."$fname\.xls");
print AFILE ("X \(Temp\)\tY\(Etch Rate\)\n");
for ($i = 0; $i <= $#xstore; $i++)
{
print AFILE ("$xstore[$i] \t $ystore[$i] \n");
}
close AFILE;
}
print("\nAre you finished (y or n): ");
$quitornot = <STDIN>;
chomp($quitornot);
undef ($temp);
undef ($A);
undef ($b);
undef ($m);
undef ($k);
undef ($LINroARH);
undef ($rsquared);
if ($quitornot eq "y" || $quitornot eq "Y")
{
&QUIT;
}
elsif ($quitornot eq "n" || $quitornot eq "N")
{
&CHOICE;
}
else
{
print ("\nThat is not an option...try again.\n");
&ASK;
};
}
sub INFO
{
print("\nAssumptions include but are not limited to:\n");
print("\nR-squared value is non-weighted.\n");
print("I can't really think of any others right now.\n\n");
&CHOICE;
}
sub QUIT
{print("\nHope this helped! See you next time...\n");}
######################################################################
+#################
#Below here are function subroutines
######################################################################
+#################
sub average
{
#this subroutine averages the results of an array passed to it. R
+eturns a single value.
my $sum = 0;
foreach $_ (@_)
{
$sum += $_;
}
my $avg = $sum / ($#_ + 1);
return $avg;
}
sub linearfit
{
#this subroutine takes as arguments two array references containin
+g linear x and y
#it returns the linear best fit regression and r-squared correlati
+on.
#Usage is @foo = linearfit($xref, $yref) where $xref is a referenc
+e to an array holding all values of
#x and $yref is a reference to an array holding all values of y.
+The index of x and y must be equal
#in order for this to work correctly. The function returns an arr
+ay in the following order:
# @results = (slope of line, intercept of line, rsquared correlati
+on)
# in order fo this function to work, you need the sum, average and
+ sqr functions in the file.
my @xs = @{@_[0]}; #turns a reference into an array!
my @ys = @{@_[1]};
my @xsqrd = sqr(@xs);
my @xy = map {$xs[$_] * $ys[$_]} 0..$#xs;
my $sumX = sum(@xs);
my $sumY = sum(@ys);
my $sumXY = sum(@xy);
my $sumXsqr = sum(@xsqrd);
my $n = $#xs;
my $b = (($sumY * $sumXsqr) - ($sumX * $sumXY)) / ((($n+1) * $sumX
+sqr) - ($sumX * $sumX));
my $m = ((($n+1) * $sumXY) - ($sumX * $sumY)) / ((($n+1) * $sumXsq
+r) - ($sumX * $sumX));
my $w;
my @predY;
for ($w = 0; $w <= $#xs; $w++)
{
$predY[$w] = ($xs[$w] * $m ) + $b;
}
my $yAvg = average(@ys);
my $k;
my @predYErr;
for ($k = 0; $k <= $#predY; $k++)
{
$predYErr[$k] = $predY[$k] - $yAvg;
}
my @ssPred = sqr(@predYErr);
my $l;
my @Err;
for ($l = 0; $l <= $#xs; $l++)
{
$Err[$l] = $ys[$l] - $yAvg;
}
my @ssTotal = sqr(@Err);
my $sumSSpred = sum(@ssPred);
my $sumSStotal = sum(@ssTotal);
my $rsqrd;
if ($sumSStotal == 0)
{
$rsqrd = 0;
}
else
{
$rsqrd = $sumSSpred / $sumSStotal;
$rsqrd = $rsqrd * 10000;
$rsqrd = int ($rsqrd);
$rsqrd = $rsqrd / 10000; #this block of code gives a four sig
+ fig rsquared value.
}
my @ans = ($m, $b, $rsqrd);
# @data = (@x, @predY);
# my $graph = GD::Graph::points->new(400, 300);
#
# $graph->set
# (
# x_label => 'Temperature',
# y_label => 'Etch Rate',
# title => 'Some simple graph',
# y_max_value => 100,
# y_tick_number => 100,
# y_label_skip => 2
# ) or die $my_graph->error;
#
# my $gd = $my_graph->plot(\@data) or die $my_graph->error;
#
return @ans;
}
sub sum
{
#this subroutine sums the numbers passed to it. Returns a single
+value.
my $sum = 0;
foreach my $line (@_)
{
$sum += $line;
}
return $sum;
}
sub sqr
{
#Calculates the square of any array passed to it, returns an array
+ with the squares.
my @xs = @_;
my @result = map {$xs[$_] * $xs[$_]} 0..$#xs; #multiply each line
+of an array together.
return @result;
}
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
| |
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.