# Here we discuss least-squares fitting of some given data.
# 
# First, lets type in our data to fit
> pts := [ [0,0.25], [1/2,2], [1,4], [5,8], [6,10] ];

              pts := [[0, .25], [1/2, 2], [1, 4], [5, 8], [6, 10]]
> plot(pts,style=point, axes=boxed);

   ** Maple V Graphics **

# We could use maple's built-in regression package to find the answer, but that wouldn't help much in explaining what's going on.  
# Let's do it anyway, though.  
# 
# Note that the least-squares package wants the x values and y values in separate lists, so we have to adjust them a bit.
> with(stats):\
fit[leastsquare[[x,y]]]([[ pts[i][1] $ i=1..5 ], [pts[i][2] $i=1..5]]);

                         y = 1.271370968 + 1.431451613 x
# 
# Let's do the same thing ourselves, "by hand". 
# 
# First, lets define the "error functional" which gives us the distance from a line (actually, its coefficients) to the data.   
> F := (m,b) -> sum(  (  (m*pts[i][1] + b)  - pts[i][2] ) ^2, \
                                    i=1..5);

                               5
                             -----
                              \                                 2
               F := (m,b) ->   )   (m pts[i][1] + b - pts[i][2])
                              /
                             -----
                             i = 1
# 
# For example, if we guessed that the line was  y= 2x + 1, we could compute its distance:
> F(2,1);

                                     19.5625
# but we see that decreasing the slope and increasing the intercept gives a better fit:
> F(1.5,1.2);

                                   3.125000000
# Now we want to minimize this quantity.  Note that maple will happily compute the partial derivatives for us.
> diff ( F(m,b), m);

                              249/2 m + 25 b - 210
# 
# So, we can ask maple to solve, setting each of the partials to 0.
> solve( { diff ( F(m,b), m)=0  , diff ( F(m,b), b) = 0},\
              {m, b} );

                       {b = 1.271370968, m = 1.431451613}
# Not surprisingly, this was the same solution we got before.   If we now want to use THIS value of m and b without retyping it, we can 
# use maple's assign command to let b and m be constants with the values given.
>  assign(");
# Maple just does the assignment, but doesn't say anything... 
#      "When I have nothing to say, my lips are sealed.  Say something once, why say it again?"
# 
# But, m and b  are now constants, with values of about 1.43 and 1.27, respectively.  
> m;

                                   1.431451613
# If we want, we can compute the distance of this line to the points...
> F(m, b);

                                   2.929334677
# 
# To get an idea of how good our fit is, we can make a plot with the data points and the line on the same graph.
# We first need to load the 'plots' package, so we can use 'display'.
> with(plots):
# 
# We can now compute both plots, and use display to show them together.  Note that we use a : to supress the output of the plot calls.
> lplot := plot(m*x+ b, x=-1..6.5, axes=boxed):\
pplot:= plot(pts, style=point):\
display({lplot, pplot});

   ** Maple V Graphics **

# 
# 
# One minor point:
#    Since we defined  'm' and 'b' to be constants, we can no longer treat them as variables.  For example,  the statement we used before 
# to compute the derivative of F with respect to m no longer works, since it is asking maple to compute the derivative of  2.929334677 
# with respect to 1.431451613.  This, of course, makes no sense.
> diff(F(m,b),m);
Error, wrong number (or type) of parameters in function diff

# Of course, we can do this by substituting in other variables
> diff(F(n,c),n);

                              249/2 n + 25 c - 210
# Alternatively, we can tell maple to "forget" the previous definitions of m and b:
> m:='m';\
b:='b';

                                     m := m

                                     b := b
> diff(F(m,b),m);

                              249/2 m + 25 b - 210