kinematische Mess-Auswertungen
mit Maxima

Dieses Maximablatt - geschrieben mit wxMaxima Version 5.20.1 stellt einige
Routinen für die Auswertung einer Messreihe - insbesonders aus dem Bereich
der Kinematik als Zeit-Ort-Messungen - zur Verfügung, i.e. Einlesen und Aufbereiten von Daten,
quadratische Interpolation, erste und zweite Ableitung, graphische Darstellungen,
Auswertungen, Gleichungen uam.
Der didaktische Sinn liegt wohl darin, dass eine konkrete Messung von Maxima analysiert wird.
Damit können dann einschlägige Fragen zum Experiment sehr ökonomisch beantwortet werden.
Beispiele werden folgen ....

1 Vorgeplänkel

1.1 Speicher leeren, Module laden, Setzungen

(%i1) kill(all);
Result

(%i1) load(draw)$
load(descriptive)$
load(interpol)$

Result

(%i4) fpprintprec:4$ratprint:false$

1.2 nützliche Routinen

(%i6) block(
find_range(p,i,d) := block([m],
  m : col(apply(matrix, p), i),
    append(mini(m)-d, maxi(m)+d)),

first_coeff(p,q,r) := block(
append(
    solve([
        p[1]^2 * a1 + p[1] * b1+ c1 = p[2],
        q[1]^2 * a1+ q[1] * b1 + c1 = q[2],
        r[1]^2 * a1 + r[1] * b1 + c1 = r[2]], [a1,b1,c1])[1],
    [ t0=p[1], t1=r[1] ])),

next_coeff(prev, r, s) := block( [aa,bb],
    aa : ev(a1,prev),
    bb : ev(b1,prev),
    solve(
    [ev(a1*t^2 + b1*t + c1 = x, [t=r[1], x=r[2]]),
        ev(a1*t^2 + b1*t + c1 = x, [t=s[1], x=s[2]]),
        ev(2*a1*t+ b1 = 2*aa*t + bb, [t=r[1]])
    ],
[a1,b1,c1]))[1],

qparts(p) := block( [collector, iterator],
    collector : [],
    collector :
        cons(
          append( first_coeff(p[1], p[2], p[3]),
                  [ t0 = p[1][1], t1 = p[3][1] ] ),
          collector),
    iterator :
        lambda([i,t],
            collector :
                cons(
                  append( next_coeff(collector[1], p[i-1], p[i]),
                             [t0 = p[i-1][1], t1 = p[i][1] ]),
                  collector)),
    for i: 4 thru length(p) do (iterator(i,t)),
    collector
),

findMinMax(function,aa,ee,n):=block([delta,y,y_min,y_max],min,max,
delta:(ee-aa)/n,
y:map(function,makelist(aa+i*delta,i,0,n+1)),
y_min:y[1],y_max:y[1],
for i:1 thru n do (
if y[i+1]>y_max then y_max:y[i+1] elseif
y[i+1]=y[i] then 0=0 elseif
y[i+1] ),
min:y_min,max:y_max,
[min,max]
),

Trimm(a,b):=block(trim:a,Trim:b,
if a<0 then trim:a*1.1
elseif a=0 then trim:-0.1
elseif a>0 then trim:(-1*a *1.2),

if b<0 then Trim:-1*b*1.2
elseif b=0 then Trim:0.1
elseif b>0 then Trim:b*1.2,

if a=b then do(trim:-abs(a)*1.2,Trim:abs(b)*1.2),

Trim:Trim*1.2,

[trim,Trim]
),

findsolutions(eqn,t) :=
map(
  lambda([konst], forget(facts()),
    block([solutions,s,c],
      numer:true,keepfloat:true,
      supcontext(c),
      forget(facts()),
      ev(assume(t0<=t and t       solutions:[facts()],
      for s in float(solve([eqn], [t])) do(
        if ev(is(t0<=t and t<=t1), cons(s,konst)) then solutions:cons(s,solutions)
      ),
      killcontext(c),
      solutions
    )
  ), qparts(mp)
)
)$


2 Daten einlesen

2.1 Daten aus einer Textdatei

(%i7) Liste:read_list ("C:/LKFbahn_V5_Ort_I.txt",semicolon);
mp:makelist([Liste[2*i-1],Liste[2*i]],i,1,length(Liste)/2);
A:mp[1][1] ;
E:mp[length(mp)][1];

Result

2.2 Dateneingabe von Hand

Diese Daten gehen von einer äquidistanten Liste aus. Eingeben werden nur Ordinaten.
Falls die Daten aus einer Datei eingelesen werden sollen, bitte 'false;*/' und '*false
aus den obigen Zeilen entfernen und die folgenden Zeilen deaktivieren!

(%i11) false;/*messpunkte(x) := makelist([i-1, x[i]], i, 1, length(x))$
mp:messpunkte([2,-3,-6,-1,1,-2]);
A:mp[1][1] ; E:mp[length(mp)][1]*/false;

Result

2.3 Graph und lineare Interpolation

lineare Interpolation

(%i13) define(Messkurve(t),linearinterpol(mp,varname='t));
Result

Graph

(%i14) findMinMax(Messkurve,A,E,10)$

(%i15) Trimm(min,max)$Min:trim$Max:Trim$Trimm(A,E)$a:trim$e:Trim$

(%i21) wxdraw2d(
xaxis=true,yaxis=true,
xrange=[a,e], yrange=[Min,Max],
color=red, point_type = filled_square, point_size = 1,
        points(mp),
explicit(Messkurve(t),t,A,E*0.99))$

Result

2.4 quadratische Interpolation und graph. Darstellung

Die folgende Routine verdanken wir S. Schmiedl. Sie interpoliert die Messpunkte quadratisch.
Das konnte Maxima bisher nicht.

(%i22) first_coeff(mp[1], mp[2], mp[3]);
f1 : lambda([t],
    ev(a1*t^2 + b1*t + c1, first_coeff(mp[1], mp[2], mp[3]))
)$

Result

(%i24) next_coeff(first_coeff(mp[1], mp[2], mp[3]), mp[3], mp[4]);
f2 : lambda([t],
    ev(a1*t^2 + b1*t + c1, next_coeff(first_coeff(mp[1], mp[2], mp[3]), mp[3], mp[4]))
)$

Result

(%i26) qspline(t,p) :=
apply("+",
        maplist(
            lambda([co],
                ev((a1*t^2+b1*t+c1) * charfun(t0 <= t and t < t1), co)),
        qparts(p)))$
Messkurve(t) := qspline(t, mp)$
Messkurve(t);

Result

Dies ist also die quadr. Interpolation zu den gegebenen Daten. Dabei beseitigt charfun das, was
aktuell nicht interessant ist.

Die Darstellung an die Messpunkte anpassen und die Messkurve plotten

(%i29) findMinMax(Messkurve,A,E,10)$
Trimm(min,max)$Min:trim$Max:Trim$Trimm(A,E)$a:trim$e:Trim$
wxdraw2d(
xaxis=true,yaxis=true,
xrange=[a,e], yrange=[Min,Max],
color=red, point_type = filled_square, point_size = 1,
        points(mp),
explicit(Messkurve(t),t,A,E*0.99))$

Result

3 Ableitungsfunktionen

Bei zusammengesetzten Funktionen hat Maxima kleine Probleme. 'tellsinpafter' behebt diese und
stellt die Ableitungen sehr gut dar.

(%i37) matchdeclare( [aa,bb],true, xx,atom)$
tellsimpafter('diff(charfun(aa<=xx and xx define(FirstDiff(T),diff(Messkurve(T),T,1));
define(SecDiff(T),diff(Messkurve(T),T,2));

Result

4 Graphische Darstellungen

Drei Funktionsgraphen passen nicht automatisch in ein einziges Bild. FindMinMax und Trimm stellt
das passende Koordinatensystem bereit.

(%i41) N:10$
findMinMax(Messkurve,A,E,N)$Trimm(min,max)$X_min[0]:min$X_max[0]:xmax$
findMinMax(FirstDiff,A,E,N)$Trimm(x_min,x_max)$X_min[1]:min$X_max[1]:max$
findMinMax(SecDiff,A,E,N)$Trimm(x_min,x_max)$X_min[2]:min$X_max[2]:max$
X_Min:min(X_min[0],X_min[1],X_min[2])$X_Max:max(X_max[0],X_max[1],X_max[2])$
Trimm(min,max)$Min:trim$Max:Trim$Trimm(A,E)$a:trim$e:Trim$

(%i62) Trimm(min,max)$Min:trim$Max:Trim$Trimm(A,E)$a:trim$e:Trim$
wxdraw2d(
xaxis=true,yaxis=true,
xrange=[a,e],yrange=[Min,Max],
color=red, point_type = filled_square, point_size = 1, points(mp),
key = "Messkurve", explicit(Messkurve(t),t,A,E*0.99),
key = "erste Ableitung",color = blue, explicit(FirstDiff(t),t,A,E*0.99),
key = "zweite Ableitung",color = green, line_type = dots,
explicit(SecDiff(t),t,A,E*0.99)
)$

Result

5 Rechnerische Auswertungen

Auch hier hat Maxima gewisse Problem. Doch mithilfe einiger Tricks fand S. Schmiedl die Lösungen.

(%i105) Ort:0.04$
findsolutions(Messkurve(t)=Ort,t);
forget(facts())$
V:0.085$
findsolutions(FirstDiff(t)=VauIstNull,t);

Result

Da muss man die 'Lösungen' nur mehr rausschreiben: v = 0 für t = 4.8 und für ...

(%i110) Trimm(min,max)$Min:trim$Max:Trim$Trimm(A,E)$a:trim$e:Trim$
wxdraw2d(
xaxis=true,yaxis=true,
xrange=[a,e], yrange=[Min,Max],
color=red, point_type = filled_square, point_size = 1, points(mp),
key = "x(t)", explicit(Messkurve(t),t,A,E*0.99),
key = "",explicit(Ort,t,A,E*0.99),
key = "v(t)",color = blue, explicit(FirstDiff(t),t,A,E*0.99),
key = "",explicit(V,t,A,E*0.99),
key = "a(t)",color = green,
explicit(SecDiff(t),t,A,E*0.99)
)$

Result

Damit hat man nun das Experiment ziemlich gut im Griff und kann Fragen der Art: Wie lange vorwärts
oder rückwärts, wann wendet 'er' sich, kann 'er' noch rechtzeitig bremsen, wann wird 'er' wo mit
welcher Geschwindigkeit an 'ihr' vorbeikommen, zum Beispiel. Konkrete Aufgabenstelleungen folgen.


Created with wxMaxima.