Introduction

Hey, everyone. This is the update to my DERIVE V4. With DERIVE V5, you can now differentiate any additive algebraic expression in the form of AX^N+BX^N+... and you can have as many terms as you want, added or subtracted in any order you want! Simply type in your expression, and the program will differentiate it using the Power Rule. Afterwards, you can check Y= for your equations; f(x) is set to Y₁, f'(x) is set to Y₂, and f”(x) is set to Y₃.

Like its predecessor, DERIVE V5 uses regression models to store numbers to strings and manipulates strings to piece together the addends/subtrahends of the expression. However, the string manipulation in this program is a lot more complicated than before.

Changelog

v5.0 - original version
v5.1 -
    x-terms with negative exponents are turned into fractions. (e.g. 2X^~2.3 -> 2/X^2.3)
    Estimated time remaining (per differentiation) for especially long expressions.
    Removed displaying the functions at the end. Go to the Y= to access your equations.

Download

Derive v5.1 - http://www.cemetech.net/programs/index.php?mode=file&path=/83plus/basic/math/Derivev5.1.zip

Explanation

Here, I will explain my code section by section. Effectively, you type in your expression, and this expression is set to a string. Then, the program breaks apart the string and differentiates each term sequentially. When the whole term is differentiated, the new equation is set to one of the Y variables. The process is repeated for second differentiation.

I. Setup

After clearing the home screen and setting Str5 to 0, L₁ to {1,2}, and “F’(X)” to Str0, (You’ll see the importance of Str5, L₁, and Str0 later.), the program asks for you to input your expression. You can even type in something as complex as: 1.2X23.6-6X^12.4+1337X²+5-X⁻¹+X^~3.9+42

For purposes of demonstration, let’s use the equation f(x)=1/3X³-1/2X²+X+4. This equation is immediately set to Str1 and then to Y₁, after which the program notifies the user it’s finding the derivative.

Code:
:ClrHome
:”0”→Str5
:{1,2}→L₁
:Input “F(X)=“,Str1
:Str1→Y₁
:”F'(X)”→Str0
:Output(4,1,”FINDING”)
:Output(4,9,”F'(X)”)
:Goto AA


*5.1 Update* - Using experimental data, I developed an equation to estimate the amount of time it takes to complete a differentiation, based on the number of terms in the expression. This program can currently differentiate one term every 1.3 or so seconds. If there are more than seven terms, the calculator will display a time estimate on the screen. This time estimate algorithm occurs before each differentiation.

Code:
:0->F
:0->P
:0->M
:While inString(Str1,"+",F+1)!=0
:If inString(Str1,"+",F+1)!=0:P+1->P
:inString(Str1,"+",F+1)->F
:End
:0->F
:While inString(Str1,"-",F+1)!=0
:If inString(Str1,"-",F+1)!=0:M+1->M
:inString(Str1,"-",F+1)->F
:End
:P+M+1->T
:If T>7
:Then
:Output(5,1,"EST. TIME:")
:Output(5,12,round(1.3T,1))
:End


II.a. Finding the Location of the First Term

The first time through the differentiation algorithm, the program starts at Lbl AA. This section locates the first instance of the + or – sign appearing in the function (in Str1), and the location of this sign is set to Z. Everything to the left of this sign is the first term.

Code:
:Lbl A
:inString(Str1,"+")→X
:inString(Str1,"-")→Y
:If X≠0 and Y≠0 and X<Y:X→Z
:If X≠0 and Y≠0 and Y<X:Y→Z
:If X=0 and Y≠0:Y→Z
:If X≠0 and Y=0:X→Z
:If X=0 and Y=0:Goto B
:sub(Str1,Z,~Z+1+length(Str1))→Str1
:If sub(Str1,1,1)="-":"~"+sub(Str1,2,length(Str1)-1)→Str1
:If sub(Str1,1,1)="+":sub(Str1,2,length(Str1)-1)→Str1
:Lbl AA
:inString(Str1,"+")→X
:inString(Str1,"-")→Y
:If X≠0 and Y≠0 and X<Y:X→Z
:If X≠0 and Y≠0 and Y<X:Y→Z
:If X=0 and Y≠0:Y→Z
:If X≠0 and Y=0:X→Z
:If X=0 and Y=0:Goto B


II.b. Preparing to Differentiate

Once the location of the first sign is determined, the first term is isolated and set to Str2 (In this case, “1/3X³”). Then, different tests make sure the term is compatible with the differentiation algorithm. It has to be notated “BX^M”, where B is the coefficient, and M is the power. (“1/3X³” is turned into “1/3X^3” and set to Str2.)

Code:
:Lbl AB
:sub(Str1,1,Z-1)→Str2
:If inString(Str2,"X")=0:Str2+"X^0"→Str2
:If sub(Str2,1,1)="X":"1"+Str2→Str2
:If sub(Str2,1,2)="~X":"~1"+sub(Str2,2,length(Str2)-1)→Str2
:If inString(Str2,"X⁻¹")>0:sub(Str2,1,~1+inString(Str2,"X"))+"X^~1"→Str2
:If inString(Str2,"^")=0:Str2+"X^1"→Str2
:If inString(Str2,"X²")>0:sub(Str2,1,~1+inString(Str2,"X"))+"X^2"→Str2
:If inString(Str2,"X³")>0:sub(Str2,1,~1+inString(Str2,"X"))+"X^3"→Str2


II.c. Differentiation, Part 1
Here, I had to work around the data type incompatibility between strings and numbers. If I tried “AX^N”→Str5, then Str5 would literally be “AX^N”. But I couldn’t do AX^N→Str5 because AX^N is a number, and strings are literal sequences of text.

Effectively, the first part of this section of code multiplies B and N to make A, the coefficient of the derivative of the current term, then converts A into string form using a linear regression. Str2 is “1X^3”, and the first line of code multiplies 1/3 and 3 together. The product, 1, is set to A. To convert this number to string form, I set {A,A} to L₂ then set the linear regression of L₁ on L₂ to Y₄. (If you remember, L₁ is {1,2}.) The result is “<the value of A>+0X” is set to Y₄ and then to Str3. So in our case, “3+0X” is set to Y₄ and then to Str3.

The second part of this section subtracts 1 from M to make N, the power of the derivative of the current term, then converts N into string form. 1 is subtracted from 3 and the difference, 2, is set to N. I use the same process as was used with the coefficient to convert this number to string form. The value of N is set to Str4.


Code:
:expr(sub(Str2,1,~1+inString(Str2,"X")))*expr(sub(Str2,1+inString(Str2,"^"),length(Str2)-inString(Str2,"^")→A
:{A,A}→L₂
:LinReg(a+bx) L₁,L₂,Y₄
:Equ►String(Y₄,Str3)
:sub(Str3,1,~1+inString(Str3,"+"))→Str3
:If Str3="0":Goto A
:
:~1+expr(sub(Str2,1+inString(Str2,"^"),length(Str2)-:inString(Str2,"^")→N
:{N,N}→L₂
:LinReg(a+bx) L₁,L₂,Y₄
:Equ►String(Y₄,Str4)
:sub(Str4,1,~1+inString(Str4,"+"))→Str4


II.d. Differentiation, Part 2

Finally, after all the preparation, the program finally has all the components needed to make the differentiated term. In this case, A=1 and N=2. Effectively, this program pieces together the string form of A, “X^” and the string form of N to make the full differentiated term (Str3+”X^”+Str4=”1X²”). It also removes extraneous coefficients and powers, if there are any (“1X²” is turned into “X²”). The final derivative of the term is set to Str5.

After this, the program removes the term just differentiated from Str1 (“1/3X³+1/2X²+X+4” becomes “-1/2X²+X+4”.) The minus sign is turned into a negative sign, then the whole process is repeated. As the program differentiates successive terms, the derivatives are added onto Str5. After going through all necessary repetitions of this process, Str5 is “X²-X+1”.

Code:
:If Str5≠"0" and :sub(Str3,1,1)≠"~":Str5+"+"+Str3+"X^"+Str4→Str5
:If Str5≠"0" and sub(Str3,1,1)="~":Str5+"-"+sub(Str3,2,length(Str3)-1)+"X^"+Str4→Str5
:If Str5="0":Str3+"X^"+Str4→Str5
:If Str4="1":sub(Str5,1,inString(Str5,"X^1"))→Str5
:If Str4="0":sub(Str5,1,~1+inString(Str5,"X^0"))→Str5
:If inString(Str5,"X^2")≠0:sub(Str5,1,inString(Str5,"X^2"))+"²"→Str5
:If inString(Str5,"X^3")≠0:sub(Str5,1,inString(Str5,"X^3"))+"³"→Str5
:Goto A


II.e. Finishing up Differentiation

Now, there are no more + or – signs in Str1. If the remaining term is an x-term, the program adds “+0” to Str1 and differentiates the expression again. In this case, Str1 is “4,” so there is no need to do this.

Code:
:Lbl B
:If inString(Str1,"X^0"):sub(Str1,1,~1+"X^0")→Str1
:If inString(Str1,"X")≠0
:Then
:length(Str1)+1→Z
:Str1+"+0"→Str1
:Goto AB
:End


III. Setting up Second Differentiation

If you’ll remember, “F’(X)” is Str0. This is how the program knows to set Str5 to Y₂ and not Y₃. Str5 is set to Str1 and “0” is set to Str5, so the program can run the differentiation algorithm again with the first derivative. “F’’(X)” is set to Str0 so it doesn’t set the second derivative to Y₂ upon completion.

Code:
:If "F'(X)"=Str0
:Then
:Str5→Y₂
:Str5→Str1
:"0"→Str5
:Output(4,9,"F''(X)"
:"F''(X)→Str0
:Goto AA
:End


IV. The Results

The second derivative is set to Y₃, then the first, second, and third derivative are displayed. As program finishes, it lets the user know he or she can find these equations in Y= at any time, then it clears all variables used in this program.

Code:
:If "F''(X)"=Str0
:Then
:Str5→Y₃
:
:Equ►String(Y₁,Str1)
:Equ►String(Y₂,Str2)
:Equ►String(Y₃,Str3)
:ClrHome
:Output(1,1,"F'(X)=")
:Output(1,7,Str2)
:Pause
:ClrHome
:Output(1,1,"F''(X)=")
:Output(1,8,Str3)
:Pause
:ClrHome
:Output(4,3,"ALL EQUATIONS")
:Output(5,5,"ARE IN Y=")
:
:DelVar Y₄DelVar Str1DelVar Str2DelVar Str3DelVar Str4DelVar Str5DelVar Str0DelVar XDelVar YDelVar ZDelVar ADelVar N
ClrAllLists


Conclusion

I had a lot of fun doing this project, and it took some effort to figure out how to allow the user to input his function. I've done other programs in the past, but this is my most complex one to date, and it's the one I'm most proud of. I'm not sure how many more major updates I'll do, since adding the product rule and quotient rule would be very difficult. Any updates hereafter will probably be optimizations. In the near future, I plan to edit the code for Derive v5.1 slightly to create a similar program that integrates non-implicit additive expressions.
Earlier versions of my program were reliant on linear, quadratic, cubic, and quartic regressions, but now that it's not, I see no reason why the program should be limited to fourth-degree functions. With some work, I might be able to find a way to differentiate any x-term.
Good luck with this project; it seems quite ambitious, and I appreciate that you wrote that in-depth explanation of how it works. From a TI-BASIC point of view, I noticed that you have a series of what are called memory leaks in the code under heading "3. String Parsing". A memory leak occurs when you Goto out of an If/Then/End, If/Then/Else/End, Repeat/End, While/End, or For/End construct. Because you start a construct that will require the calculator to find an End, but you never hit that End, the calculator will remember the fact that it needs to account for that missing End until your program terminates. As you do this more and more in a single program, it will get slower and slower as the parser juggles information about more and more missing Ends. One possible way to repair that code:
Code:
// I assume it's possible for Str6 to contain useful information?
If 0<length(Str6
Then
If "0"=Str6
""->Str6
Else
""->Str6
End
// Now account for all the rest and tack them onto Str6
// The Str1 case is a little different from Str2 through Str5
If "0"!=Str1
Str1->Str6
If 0<len(Str6
Then
If expr(Str2)!=0:Str6+"+"+Str2->Str6
Else
If "0"!=Str2
Str2->Str6
End
If 0<len(Str6
Then
If expr(Str3)!=0:Str6+"+"+Str3->Str6
Else
If "0"!=Str3
Str3->Str6
End
If 0<len(Str6
Then
If expr(Str4)!=0:Str6+"+"+Str4->Str6
Else
If "0"!=Str4
Str4->Str6
End
If 0<len(Str6
Then
If expr(Str5)!=0:Str6+"+"+Str5->Str6
Else
If "0"!=Str5
Str5->Str6
End
Thanks, Kerm. I'll have to look at it some more after I post the 5.1 update.

Edit: Actually, I don't see the section you're referring to... (There's no longer a section called "3. String Parsing".) Maybe you're referring to my old Derive v4 code.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement