home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
449a.lha
/
Plotter
/
src
/
Ableitung.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-02
|
22KB
|
860 lines
/********************************************************************/
/**** ****/
/**** ****/
/**** Program : Ableitung.c ****/
/**** ****/
/**** Version : 03.70 ****/
/**** ****/
/**** Erstversion : 09.03.1990 ****/
/**** ****/
/**** Letzte Änderung : 03.08.1990 ****/
/**** ****/
/**** Compiliert mit : siehe MAKEFILE ****/
/**** ****/
/**** Gelinkt mit : siehe MAKEFILE ****/
/**** ****/
/********************************************************************/
/**** ****/
/**** ****/
/**** Copyright by Rüdiger Dreier ****/
/**** ****/
/**** ****/
/********************************************************************/
#ifdef DEBUG
#include "Plotter.h"
#include <proto/tool.h>
#endif
#include <string.h>
#include <exec/memory.h>
#include <proto/exec.h>
#ifndef LAENGE
#define LAENGE 500
#endif
char * __asm Ableiten(register __a0 char *string)
{
char Ergebnis[MAXCHARS];
char *EString;
StartBlock=Init_Mem(string);
MatheFehler=Init_Block(StartBlock);
MatheFehler|=PreCalc(StartBlock,Konstantenstart);
EString=Ableitung(StartBlock);
strcpy(Ergebnis,EString);
Free_Block(StartBlock);
FreeMem(EString,LAENGE);
return(Ergebnis);
}
VOID __asm Umklammern(register __a0 char *string)
{
char *HILFE;
HILFE=AllocMem(LAENGE,MEMF_CLEAR);
if(HILFE==NULL)return;
if(check('+','-',0L,(LONG)strlen(string),string)!=-1L)
{
HILFE[0]='(';
strcat(HILFE,string);
strcat(HILFE,")");
strcpy(string,HILFE);
}
FreeMem(HILFE,LAENGE);
}
VOID __asm Umklammern_2(register __a0 char *string)
{
char *HILFE;
Umklammern(string);
HILFE=AllocMem(LAENGE,MEMF_CLEAR);
if(HILFE==NULL)return;
if(check('*','/',0L,(LONG)strlen(string),string)!=-1L)
{
HILFE[0]='(';
strcat(HILFE,string);
strcat(HILFE,")");
strcpy(string,HILFE);
}
FreeMem(HILFE,LAENGE);
}
VOID Zusammensetzen(char *string,LONG Anzahl,char *ABL,struct Block *Start)
{
char *abgeleitet;
SHORT *a;
LONG Anz;
abgeleitet=Ableitung(Start->Right);
strcpy(string,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(string);
a=(SHORT *)string;
/* if(strcmp(string,"0")) */
if((0x3000!=*a))
{
/* if(strcmp(string,"1")==NULL) */
if(0x3100==*a)
{
string[0]=0;
}
else
{
strcat(string,"*");
}
strcat(string,ABL);
Anz=Start->Rechts-Start->Links-Anzahl;
mid(&string[strlen(string)],Start->String,Start->Links+Anzahl+1,Anz);
}
}
LONG __asm Mit_X(register __a0 struct Block *block)
{
LONG i,Flag=0;
i=block->Links;
while(i<=block->Rechts)
{
if(block->String[i]=='x')Flag++;
i++;
}
return(Flag);
}
char * __asm Ableitung(register __a0 struct Block *Start)
{
LONG Anz;
char *links,*rechts,*abgeleitet,*HILFE;
/* Speicher reservieren */
rechts=AllocMem(LAENGE,MEMF_CLEAR);
if(!rechts)return(0);
HILFE=AllocMem(LAENGE,MEMF_CLEAR);
if(!HILFE)return(0);
switch(Start->RechenArt)
{
case ADDI:
{
SHORT *a;
/* u+v --> u' + v' */
/* Speicher reservieren */
links=AllocMem(LAENGE,MEMF_CLEAR);
if(!links)return(0);
/* Ableitung von links */
abgeleitet=Ableitung(Start->Left);
strcpy(links ,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(links);
/* Ableitung von rechts */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
/* Zusammenfügen */
/* 0+ wird nicht gebraucht */
a=(SHORT *)links;
/*if(strcmp(links,"0"))*/
if(0x3000!=*a)
{
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
/* +0 wird auch nicht gebraucht */
strcat(links,"+");
strcat(links,rechts);
}
}
else
{
/* Nur rechts nehmen */
strcpy(links,rechts);
}
strcpy(rechts,links);
/* Wenn links und rechts 0 sind ... */
if(rechts[0]==0)
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3000;
/* rechts[0]='0';rechts[1]=0; */
}
FreeMem(links,LAENGE);
break;
}
case SUBT:
{
SHORT *a;
/* u-v --> u' - v' */
/* Speicher reservieren */
links=AllocMem(LAENGE,MEMF_CLEAR);
if(!links)return(0);
abgeleitet=Ableitung(Start->Left);
strcpy(links ,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(links);
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
/*if(strcmp(links,"0"))*/
a=(SHORT *)links;
if(0x3000!=*a)
{
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(links,"-");
strcat(links,rechts);
}
}
else
{
SHORT *a;
a=(SHORT *)links;
*a=0x2d00;
/* links[0]='-';
links[1]=0; */
strcat(links,rechts);
}
strcpy(rechts,links);
/*if(!strcmp(rechts,""))*/
if(0==rechts[0])
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3000;
/* rechts[0]='0';rechts[1]=0; */
}
FreeMem(links,LAENGE);
break;
}
case MULT:
{
SHORT *a;
/* u*v --> u*v' + u'*v */
/* Speicher reservieren */
links=AllocMem(LAENGE,MEMF_CLEAR);
if(!links)return(0);
abgeleitet=Ableitung(Start->Left);
strcpy(links ,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(links);
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(HILFE,Start->String,Start->Left->Links,Anz);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"1"))*/
if(0x3100!=*a)
{
Umklammern(HILFE);
if(Vereinfachung(rechts,HILFE))
{
rechts[0]=0;
}
else
{
strcat(rechts,"*");
}
}
else
{
rechts[0]=0;
}
strcat(rechts,HILFE);
}
a=(SHORT *)links;
/*if(strcmp(links,"0"))*/
if(0x3000!=*a)
{
SHORT *a,*b;
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
a=(SHORT *)links;
/*if(strcmp(links,"1"))*/
if(0x3100!=*a)
{
Umklammern(HILFE);
if(Vereinfachung(links,HILFE))
{
links[0]=0;
}
else
{
strcat(links,"*");
}
}
else
{
links[0]=0;
}
strcat(links,HILFE);
a=(SHORT *)links;
b=(SHORT *)rechts;
/*if(strcmp(links,"0") && strcmp(rechts,"0")) */
if((0x3000!=*a) && (0x3000!=*b))
{
strcat(links,"+");
strcat(links,rechts);
}
strcpy(rechts,links);
}
FreeMem(links,LAENGE);
break;
}
case DIVI:
{
SHORT *a;
/* u/v --> (u'*v - u*v')/v^2 */
/* Speicher reservieren */
links=AllocMem(LAENGE,MEMF_CLEAR);
if(!links)return(0);
abgeleitet=Ableitung(Start->Left);
strcpy(links ,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(links);
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(HILFE,Start->String,Start->Left->Links,Anz);
/*if(strcmp(rechts,"1"))*/
if(0x3100!=*a)
{
Umklammern(HILFE);
strcat(rechts,"*");
}
else
{
rechts[0]=0;
}
strcat(rechts,HILFE);
}
a=(SHORT *)links;
/*if(strcmp(links,"0"))*/
if(0x3000!=*a)
{
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
/*if(strcmp(links,"1"))*/
if(0x3100!=*a)
{
Umklammern(HILFE);
strcat(links,"*");
}
else
{
links[0]=0;
}
strcat(links,HILFE);
}
if(strcmp(links,rechts))
{
SHORT *a;
Umklammern(rechts);
a=(SHORT *)links;
/*if(strcmp(links,"0"))*/
if(0x3000!=*a)
{
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(links,"-");
strcat(links,rechts);
}
}
else
{
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
SHORT *a;
a=(SHORT *)links;
*a=0x2d00;
/* links[0]='-';
links[1]=0; */
strcat(links,rechts);
}
}
strcpy(rechts,links);
}
else
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3000;
/* rechts[0]='0';rechts[1]=0; */
}
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
Umklammern(rechts);
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern(HILFE);
strcat(HILFE,"^2");
strcat(rechts,"/");
strcat(rechts,HILFE);
}
FreeMem(links,LAENGE);
break;
}
case POWE:
{
/* Speicher reservieren */
links=AllocMem(LAENGE,MEMF_CLEAR);
if(!links)return(0);
Anz=0;
if(Mit_X(Start->Right))Anz=1;
if(Mit_X(Start->Left ))Anz+=2;
switch(Anz)
{
case 0:
{
/* Von X nicht abhängig */
/* rechts[0]='0';rechts[1]=0; */
SHORT *a;
a=(SHORT *)rechts;
*a=0x3000;
break;
}
case 2:
{
SHORT *a;
/* Basis von X abhängig */
/* x^a --> a*x^(a-1) */
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern(HILFE);
abgeleitet=Ableitung(Start->Left);
strcat(links ,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(links);
a=(SHORT *)links;
/*if(strcmp(links,"1"))*/
if(0x3100!=*a)
{
strcat(links,"*");
}
else
{
links[0]=0;
}
strcat(links,HILFE);
strcat(links,"*");
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(HILFE,Start->String,Start->Left->Links,Anz);
Umklammern_2(HILFE);
strcat(links,HILFE);
strcat(links,"^(");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(rechts,Start->String,Start->Right->Links,Anz);
strcat(rechts,"-1)");
strcat(links,rechts);
strcpy(rechts,links);
break;
}
case 1:
{
SHORT *a;
/* a^x --> a^x*ln(a) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"1"))*/
if(0x3100!=*a)
{
strcat(rechts,"*");
}
else
{
rechts[0]=0;
}
/* Die Originalfunktion wieder zusammenstellen */
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(links,Start->String,Start->Left->Links,Anz);
Umklammern_2(links);
strcat(rechts,links);
strcat(rechts,"^");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern_2(HILFE);
strcat(rechts,HILFE);
strcat(rechts,"*ln(");
strcat(rechts,links);
strcat(rechts,")");
break;
}
case 3:
{
struct Block *New_START;
char *NewFunc;
/* 15.07.90: Fehler beseitigt. f(x) und g(x) waren vertauscht */
/* f(x)^g(x) <=> e^(ln(f(x)^g(x))) */
/* <=> e^g(x)*ln(f(x)) */
/* Abgeleitet => */
/* (g(x)*ln(f(x)))'*e^g(x)*ln(f(x)) */
/* <=> (g(x)*ln(f(x)))'*f(x)^g(x) */
/* Die Ableitung wird rekur. gebildet */
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern_2(HILFE);
strcpy(links,HILFE);
strcat(links,"*ln(");
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(HILFE,Start->String,Start->Left->Links,Anz);
strcat(links,HILFE);
strcat(links,")");
New_START=Init_Mem(links);
if(!New_START)return(0);
Anz=Init_Block(New_START);
NewFunc=Ableitung(New_START);
strcpy(rechts,NewFunc);
FreeMem(NewFunc,LAENGE);
Free_Block(New_START);
Umklammern(rechts);
strcat(rechts,"*");
/* Die Originalfunktion wieder zusammenstellen */
Anz=Start->Left->Rechts-Start->Left->Links+1;
mid(links,Start->String,Start->Left->Links,Anz);
Umklammern_2(links);
strcat(rechts,links);
strcat(rechts,"^");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern_2(HILFE);
strcat(rechts,HILFE);
}
}
FreeMem(links,LAENGE);
break;
}
case SINU:
{
/* sin(x) --> cos(x) */
Zusammensetzen(rechts,3,"cos(",Start);
break;
}
case COSI:
{
SHORT *a;
/* cos(x) --> -sin(x) */
Zusammensetzen(rechts,3,"sin(",Start);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
SHORT *a;
a=(SHORT *)HILFE; /* Hilfe = '-'; */
*a=0x2d00;
strcat(HILFE,rechts);
strcpy(rechts,HILFE);
}
break;
}
case TANG:
{
SHORT *a;
/* tan(x) --> 1/cos^2(x) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(rechts,"/cos(");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(&rechts[strlen(rechts)],Start->String,Start->Right->Links,Anz);
strcat(rechts,")^2");
}
break;
}
case ASIN:
{
SHORT *a;
/* asin --> 1/sqr(1-x^2) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(rechts,"/sqr(1-");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(&rechts[strlen(rechts)],Start->String,Start->Right->Links,Anz);
strcat(rechts,"^2)");
}
break;
}
case ACOS:
{
SHORT *a;
/* acos(x) --> -1/sqr(1-x^2) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(rechts,"/sqr(1-");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(&rechts[strlen(rechts)],Start->String,Start->Right->Links,Anz);
strcat(rechts,"^2)");
}
if(0x3000!=*a)
/*if(strcmp(rechts,"0"))*/
{
/*strcpy(HILFE,"-");*/
SHORT *a;
a=(SHORT *)HILFE;
*a=0x2d00;
strcat(HILFE,rechts);
strcpy(rechts,HILFE);
}
break;
}
case ATAN:
{
SHORT *a;
/* atan(x) --> 1/(1+x^2) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
strcat(rechts,"/(1+");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(&rechts[strlen(rechts)],Start->String,Start->Right->Links,Anz);
strcat(rechts,"^2)");
}
break;
}
case LOG1:
{
SHORT *a;
/* log(x) --> 1/(x*ln10) */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x300!=*a)
{
strcat(rechts,"/(");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(&rechts[strlen(rechts)],Start->String,Start->Right->Links,Anz);
strcat(rechts,"*");
strcat(rechts,"ln(10))");
}
break;
}
case LNAT:
{
SHORT *a;
/* ln(x) --> 1/x */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
strcat(rechts,"/");
Umklammern_2(HILFE);
strcat(rechts,HILFE);
}
break;
}
case ABSO:
{
/* Kann man drüber diskutieren.... */
/* abs(x) --> sgn(x) */
Zusammensetzen(rechts,3,"sgn(",Start);
break;
}
case SQRT:
{
SHORT *a;
/* sqr(x) --> 1/2*x^-1/2 */
abgeleitet=Ableitung(Start->Right);
strcpy(rechts,abgeleitet);
FreeMem(abgeleitet,LAENGE);
Umklammern(rechts);
a=(SHORT *)rechts;
/*if(strcmp(rechts,"0"))*/
if(0x3000!=*a)
{
/*if(!strcmp(rechts,"1"))*/
if(0x3100==*a)
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3100;
/* rechts[0]='1';rechts[1]=0; */
}
strcat(rechts,"/2*");
Anz=Start->Right->Rechts-Start->Right->Links+1;
mid(HILFE,Start->String,Start->Right->Links,Anz);
Umklammern_2(HILFE);
strcat(rechts,HILFE);
strcat(rechts,"^(-1/2)");
}
break;
}
case FLOO:
case ZIFF:
case UKON:
case MKON:
case SIGU:
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3000;
/* rechts[0]='0';rechts[1]=0; */
break;
}
case X:
{
SHORT *a;
a=(SHORT *)rechts;
*a=0x3100;
/* rechts[0]='1';rechts[1]=0; */
break;
}
default:
{
/* FEHLER, es sollten alle Fälle abgedeckt sein */
}
}
FreeMem(HILFE,LAENGE);
return(rechts);
}
/* Funktion, die den Term a/b*b auf a vereinfacht */
/* Wenn b von x abhängig ist, dann stimmt das so eigentlich nur für b<>0 */
LONG __asm Vereinfachung(register __a0 char *a,
register __a1 char *b)
{
char *HILFE;
LONG Pos,Flag=0;
Umklammern(a);
Umklammern(b);
HILFE=AllocMem(LAENGE,MEMF_CLEAR);
if(!HILFE)return(0);
if(Pos=check('/','/',0L,(LONG)strlen(a),a)!=-1L)
{
strcpy(HILFE,&a[Pos+1]);
if(!strcmp(HILFE,b))
{
left(HILFE,a,Pos);
Flag=1;
}
}
if(Pos=check('/','/',0L,(LONG)strlen(b),b)!=-1L)
{
strcpy(HILFE,&b[Pos+1]);
if(!strcmp(HILFE,a))
{
left(HILFE,b,Pos);
Flag=1;
}
}
if(Flag)strcpy(b,HILFE);
FreeMem(HILFE,LAENGE);
return(Flag);
}