Post by tsh73 on Feb 18, 2019 20:18:06 GMT
Here is some polynomial calculator, started as "let's input polynomial string and gather similar terms".
It actually stores "2*x^2-1" as "-1 0 2" - and if you enter it with similar terms it will be gathered on input.
Also, reading it in is oldest part. It allows "3x" instead of "3*x" but not "x3", and "1e-3" goes all wrong.
Here what it can do, on my son's algebra examples (but really these examples supposed to be solved by hand - and he does them that way):
I'll probably work on it more, but so far code is here
It actually stores "2*x^2-1" as "-1 0 2" - and if you enter it with similar terms it will be gathered on input.
Also, reading it in is oldest part. It allows "3x" instead of "3*x" but not "x3", and "1e-3" goes all wrong.
Here what it can do, on my son's algebra examples (but really these examples supposed to be solved by hand - and he does them that way):
Welcome to polynomial Thing
type Help to get help
>#present as a polynomial
>#(x-6)^2
>p=x-6
p=x-6
>p*p
Ans=x^2-12*x+36
>edit
>#present as a polynomial
>#(5-x)(5+x)
>p=5-x
p=-x+5
>p2=5+x
p2=x+5
>p*p2
Ans=-x^2+25
>#simplify
>#(x-2)(x+2)-(x-5)^2
>p=x-2
p=x-2
>p2=x+2
p2=x+2
>p3=x-5
p3=x-5
>z=p*p2
Ans=x^2-4
z=x^2-4
>p3*p3
Ans=x^2-10*x+25
>z-ans
Ans=10*x-29
>#simplyfy and evaluate for x=.5
>#(3-x)(3+x)(9+x^2)+(4+x^2)^2
>p1=3-x
p1=-x+3
>p2=3+x
p2=x+3
>p3=9+x^2
p3=x^2+9
>p4=4+x^2
p4=x^2+4
>z=p1*p2
Ans=-x^2+9
z=-x^2+9
>z=z*p3
Ans=-x^4+81
z=-x^4+81
>z2=p4*p4
Ans=x^4+8*x^2+16
z2=x^4+8*x^2+16
>z-z2
Ans=-2*x^4-8*x^2+65
>eval ans 0.5
ans(0.5)=62.875
>list
- Defined polynomials -
ans=-2*x^4-8*x^2+65
p=x-2
p2=x+3
p3=x^2+9
z=-x^4+81
p1=-x+3
p4=x^2+4
z2=x^4+8*x^2+16
--------------------
>
I'll probably work on it more, but so far code is here
'Polynomial thing
'tsh73 Febr 2019
'evolves to polynomial library + console interface
'v.02 - initial things done
'known BUG: polinRead$ does not read scientific notation, so p=1e-3 results in -2
'polynomials stored as space delimited strings of coeffts, 0-th first
'prefix "polin"
'-------------------------------
global maxPow
maxPow=100
dim polinCoefft(maxPow) 'global in JB/LB
'global polinN ' polynomial power, internal for current array
global polinTimesSign$
polinTimesSign$="*" 'it will skip (*) like in 3x^2 if not defined
' polinTimesSign$=""
' polinTimesSign$="×"
' polinTimesSign$="·"
'--------------------------------
global maxPol, nPols, editRet$
maxPol=100
dim poliName$(maxPol) 'name
dim polynomial$(maxPol) 'body (string of coeffts)
nPols=0
'let Ans be polynomial$(0)
poliName$(0)="ans"
polynomial$(0)="0"
print "Welcome to polynomial Thing"
print "type Help to get help"
'main loop
while 1
if editRet$="" then
input ">";cmd$
else
cmd$=editRet$
editRet$=""
print ">";cmd$
end if
cmd$=trim$(lower$(cmd$))
select case
case instr(cmd$,"#")=1
'ignore line (for comments)
case cmd$="help"
call showHelp
case cmd$="quit" or cmd$="exit"
print "-=* Bye then +=-"
end
case cmd$="list"
call showpolynomials
case instr(cmd$,"del ")=1
call delpolynomial cmd$
case cmd$="list"
call showpolynomials
case instr(cmd$, "=")<>0
call doAssign cmd$
case instr(cmd$,"eval ")=1 'above (-) or 'eval p -1' will not work
call doEval cmd$
case instr(cmd$, "+")<>0
call doAdd cmd$
case instr(cmd$, "-")<>0
call doSub cmd$
case instr(cmd$, "*")<>0
call doMul cmd$
case instr(cmd$,"edit")=1 'with or without var_name
call doEdit cmd$
case else
print "??? Command not recognised"
end select
if res$<>"" then print res$
wend
end
'==================================
'interface things
sub showHelp
print "This is a Polynomial Thing"
print "kind of calculator for polynomials of single variable (x)"
print "like 2*x^2-3*x+1"
print " Supports: "
print "assignment (=), like p=3*x^3-1"
print "+ - *"
print "You can do stuff like z=p1+p2"
print "Only single operation on a line - likely silently ignore the rest (!)"
print "Case not significant so 'p12' and 'P12' is the same"
print "Last result stored in special variable 'Ans'"
print "'List' shows variables"
print "'Del var_name' erases variable 'var_name'"
print "'Eval var_name number' evatuates polynomial 'var_name' at x=number"
print "'Edit' or 'Edit var_name' to get paste-able prompt window"
print "--TBD section--"
print "/ (possibly with reminder)"
print "^ (integer power)"
print "Save/Load vars from file"
print "Get root(s) of polynomial"
print "Get polynomial by roots"
print "Get polynomial by points (Lagrange polynomial)"
print "Substitute polynomial for X in polynomial"
print "Table values to a file"
print "Graph polynomial"
end sub
sub showpolynomials
print "- Defined polynomials -"
for i = 0 to nPols
print poliName$(i);"=";polinPrint$(polynomial$(i))
next
print "--------------------"
end sub
sub doAssign cmd$
varName$=trim$(word$(cmd$,1,"="))
varVal$=trim$(word$(cmd$,2,"="))
i=findName(varName$)
if i<0 then
IF nPols<maxPol Then
nPols=nPols+1
i=nPols
else
notice "ERROR"+chr$(13)+"Out of space for polynomials"
exit sub
end if
end if
poliName$(i)=varName$
'other polynomial?
j=findName(varVal$)
if j>=0 then
polynomial$(i)=polynomial$(j)
else
select case
case matchPOpP(varVal$,"+")=1
call doAdd varVal$
polynomial$(i)=polynomial$(0)
case matchPOpP(varVal$,"-")=1
call doSub varVal$
polynomial$(i)=polynomial$(0)
case matchPOpP(varVal$,"*")=1
call doMul varVal$
polynomial$(i)=polynomial$(0)
case else
polynomial$(i)=polinRead$(varVal$)
end select
end if
print poliName$(i);"=";polinPrint$(polynomial$(i))
end sub
sub delpolynomial cmd$
varName$=trim$(mid$(cmd$,len("del ")+1))
i=findName(varName$)
if i=0 then
print "polynomial Ans could not be deleted"
exit sub
end if
if i<0 then
print "polynomial '"+varName$+" 'not found"
exit sub
end if
for j=i to nPols-1
poliName$(j)=poliName$(j+1)
polynomial$(j)=polynomial$(j+1)
next
nPols=nPols-1
end sub
sub doEval cmd$
varName$=word$(cmd$, 2)
i=findName(varName$)
if i<0 then
print "polynomial '"+varName$+" 'not found"
exit sub
end if
num=val(word$(cmd$, 3))
res=polinEval(polynomial$(i), num)
print poliName$(i);"(";num;")=";res
end sub
function matchPOpP(cmd$,op$)
op1$=trim$(word$(cmd$,1,op$))
op2$=trim$(word$(cmd$,2,op$))
i1=findName(op1$)
i2=findName(op2$)
if i1>=0 and i2 >=0 then matchPOpP=1
end function
sub doAdd cmd$
op1$=trim$(word$(cmd$,1,"+"))
op2$=trim$(word$(cmd$,2,"+"))
i1=findName(op1$)
if i1<0 then
print "polynomial '"+op1$+" 'not found"
exit sub
end if
i2=findName(op2$)
if i2<0 then
print "polynomial '"+op2$+" 'not found"
exit sub
end if
polynomial$(0)=polinAdd$(polynomial$(i1),polynomial$(i2))
print "Ans=";polinPrint$(polynomial$(0))
end sub
sub doSub cmd$
op1$=trim$(word$(cmd$,1,"-"))
op2$=trim$(word$(cmd$,2,"-"))
i1=findName(op1$)
if i1<0 then
print "polynomial '"+op1$+" 'not found"
exit sub
end if
i2=findName(op2$)
if i2<0 then
print "polynomial '"+op2$+" 'not found"
exit sub
end if
polynomial$(0)=polinSub$(polynomial$(i1),polynomial$(i2))
print "Ans=";polinPrint$(polynomial$(0))
end sub
sub doMul cmd$
op1$=trim$(word$(cmd$,1,"*"))
op2$=trim$(word$(cmd$,2,"*"))
i1=findName(op1$)
if i1<0 then
print "polynomial '"+op1$+" 'not found"
exit sub
end if
i2=findName(op2$)
if i2<0 then
print "polynomial '"+op2$+" 'not found"
exit sub
end if
polynomial$(0)=polinMul$(polynomial$(i1),polynomial$(i2))
print "Ans=";polinPrint$(polynomial$(0))
end sub
sub doEdit cmd$
varName$=trim$(mid$(cmd$,len("edit ")+1))
i=findName(varName$)
if i<0 then
'start empty
ans$=""
else
ans$=poliName$(i);"=";polinPrint$(polynomial$(i))
end if
prompt "Edit"+chr$(13)+"(this window supports PASTE from clipboard)";ans$
if ans$<>"" then
editRet$=ans$
else
editRet$=""
end if
end sub
function findName(name$)
'finds a name or returns -1
found =-1
for i = 0 to nPols
if poliName$(i)=name$ then found =i: exit for
next
findName=found
end function
'==================================
'library things
function polinPrint$(p$)
call polin2Arr p$, polinN
'call polinDebugPrint
'polinPrint$=polinDebugPrint$(polinN)
'print "polinN ",polinN
for i = polinN to 0 step -1
if polinCoefft(i) <0 then
'print "-";
else
if (polinCoefft(i)<>0) and (i<polinN) then
polinPrint$=polinPrint$;"+"
end if
end if
polinPrint$=polinPrint$;polinFormatCoefft$(i)
next
if polinPrint$="" then polinPrint$="0"
end function
function polinFormatCoefft$(i)
if polinCoefft(i)=0 then exit function
skipNum=(abs(polinCoefft(i))=1)
select case i
case 0
polinFormatCoefft$="";polinCoefft(i)
case 1
if skipNum then
if polinCoefft(i) <0 then
polinFormatCoefft$="-x"
else
polinFormatCoefft$="x"
end if
else
polinFormatCoefft$="";polinCoefft(i);polinTimesSign$;"x"
end if
case else
if skipNum then
if polinCoefft(i) <0 then
polinFormatCoefft$="-x"
else
polinFormatCoefft$="x"
end if
else
polinFormatCoefft$="";polinCoefft(i);polinTimesSign$;"x"
end if
polinFormatCoefft$=polinFormatCoefft$;"^";i
end select
end function
sub polin2Arr p$, byRef polinN
'maxPow=100 is global
dim polinCoefft(maxPow) 'clears array from leftovers
i=1
while 1
c$=word$(p$,i)
'print "a",i,c$
if c$="" then exit while
polinCoefft(i-1)=val(c$)
i=i+1
wend
polinN=i-2
if polinN<0 then polinN=0 'empty string, ~0
end sub
sub polinDebugPrint
'what is in array?
'skip higher 0's
for i = maxPow to 0 step -1
if polinCoefft(i)<>0 then exit for
next
polinN=i
print "polinN",polinN
print "polinCoefft:"
for i = 0 to polinN
print i, polinCoefft(i)
next
end sub
function polinDebugPrint$(polinN)
'easy polynomial printing
for i = polinN to 0 step -1
if i<>polinN then polinDebugPrint$=polinDebugPrint$;"+"
polinDebugPrint$=polinDebugPrint$;polinCoefft(i);"x^";i
next
end function
function polinEval(p$, x)
for i = numWords(p$) to 1 step -1
c$=word$(p$,i)
'print "pE",i,c$
polinEval=polinEval*x+val(c$)
next
end function
function polinMultN$(p$, n)
i=1
while 1
c$=word$(p$,i)
'print "a",i,c$
if c$="" then exit while
polinMultN$=polinMultN$;space$(i>1);n*val(c$)
i=i+1
wend
end function
function polinAdd$(p1$, p2$)
n=JBmax(numWords(p1$),numWords(p2$))
hasNot0=0
for i=n to 1 step -1
c=val(word$(p1$,i))+val(word$(p2$,i))
'print "pA",i,c
if c<>0 then hasNot0=1
if hasNot0 or (i=1) then
polinAdd$=str$(c);" ";polinAdd$
end if
next
polinAdd$=trim$(polinAdd$)
end function
function polinSub$(p1$, p2$)
polinSub$=polinAdd$(p1$, polinMultN$(p2$, -1))
end function
function polinMul$(p1$, p2$)
'loop along shorter polynomial (p1$)
if numWords(p1$) > numWords(p2$) then
call swap$ p1$, p2$
end if
'print "pM",p1$,"%", p2$
res$="0"
n=numWords(p1$)
for i=1 to n
c=val(word$(p1$,i))
'print "pM",i,c
'print "pM",polinMultN$(p2$, c)
res$=polinAdd$(res$, polinMultN$(p2$, c))'"p2$*c*x^(i-1)")
p2$="0 ";p2$
next
polinMul$=res$
end function
function polinRead$(a$)
'reads and normalises (gather same terms) polynomial
'1) read
maxTerms=100
dim terms$(maxTerms)
w$="" 'curr word
iw=0 'empty
lastSign$=""
for i = 1 to len(a$)
c$=mid$(a$,i,1)
select case c$
case " "
'skip
case "+","-"
iw=iw+1
terms$(iw)=lastSign$;w$
w$=""
if c$="-" then
lastSign$=c$
else
lastSign$=""
end if
case else
w$=w$+c$
end select
next
'last part
iw=iw+1
terms$(iw)=lastSign$;w$
'2)normalise
dim polinCoefft(maxPow)' clears
maxPower=0
for i=1 to iw
'split terms$(i) to number and power
select case
case instr(terms$(i),"x")=0
curPow=0 'x^0 aka Nothing ("")
num=val(terms$(i))
case instr(terms$(i),"x^")=0
curPow=1 'x^1 aka x
num=valOrOne(terms$(i)) 'magic of VAL!
case else
curPow=val(word$(terms$(i),2,"^"))
num=valOrOne(terms$(i))
end select
'print i, num, curPow
if maxPower<curPow then maxPower=curPow
polinCoefft(curPow)=polinCoefft(curPow)+num
next
'3)output
for i = 0 to maxPower
polinRead$=polinRead$;" "; polinCoefft(i)
next
polinRead$=mid$(polinRead$,2) 'strip first space
end function
'-------------------------------
function numWords(p$)
while 1
i=i+1
c$=word$(p$,i)
if c$="" then exit while
wend
numWords=i-1
end function
sub swap$ byRef a$, byRef b$
tmp$=a$
a$=b$
b$=tmp$
end sub
function valOrOne(n$)
select case
case instr(n$,"-x")=1
valOrOne=-1
case instr(n$,"x")=1
valOrOne=1
case else
valOrOne=val(n$)
end select
end function
'------------------------------------------------
'for JB 1.01 compatibility
function JBmax(x,y)
JBmax = x
if y>x then JBmax = y
end function
function JBmin(x,y)
JBmin = x
if y<x then JBmin = y
end function