Line 1: |
Line 1: |
− | The {{Forge|symbolic|symbolic package}} is part of the octave-forge project. | + | The {{Forge|symbolic|symbolic package}} is part of the [[Octave Forge]] project. |
| | | |
− | [[Category:Octave-Forge]] | + | [[Category:Octave Forge]] |
| + | |
| + | === Demos and usage examples === |
| + | |
| + | * '''I'm trying to substitute a double value into an expression. How can I avoid getting "warning: Using rat() heuristics for double-precision input (is this what you wanted?)".''' |
| + | |
| + | In general, you should be very careful when converting floating point ("doubles") to symbolic variables, that's why the warning is bothering you. |
| + | |
| + | <source lang="octave"> |
| + | |
| + | ## Demo of how to use a number (which was calculated in an octave |
| + | ## variable) in a symbolic calculation, without getting a warning. |
| + | |
| + | ## use octave to calculate some number: |
| + | a = pi/2 |
| + | |
| + | ## now do some work with the symbolic pkg |
| + | syms x |
| + | f = x * cos (x) |
| + | df = diff (f) |
| + | |
| + | ## Now we want to evaluate df at a: |
| + | |
| + | # subs (df, x, a) # this gives the "rats" warning (and gives a symbolic answer) |
| + | |
| + | ## So instead, try |
| + | |
| + | dfh = function_handle (df) |
| + | |
| + | dfh (a) |
| + | |
| + | ans = -1.5708 |
| + | |
| + | |
| + | ## And you can evaluate dfh at an array of "double" values: |
| + | |
| + | dfh ([1.23 12.3 pi/2]) |
| + | |
| + | ans = |
| + | -0.82502 4.20248 -1.57080 |
| + | |
| + | </source> |
| + | |
| + | |
| + | |
| + | * '''Demo of how to graph symbolic functions (by converting SYMBOLIC functions into ANONYMOUS functions)''' |
| + | |
| + | <source lang="octave"> |
| + | |
| + | ## The following code will produce the same vector field plot as Figure 1.14 from Example 1.6 (pg. 39) from A Student's Guide to Maxwell's Equations by Dr. Daniel Fleisch. |
| + | |
| + | ## Make sure symbolic package is loaded and symbolic variables declared. |
| + | pkg load symbolic |
| + | syms x y |
| + | |
| + | ## Write a Vector Field Equation in terms of symbolic variables |
| + | vectorfield = [sin(pi*y/2); -sin(pi*x/2)]; |
| + | |
| + | ## Vector components are converted from symbolic into "anonymous functions" which allows them to be graphed. |
| + | ## The "'vars', [x y]" syntax ensures each component is a function of both 'x' & 'y' |
| + | iComponent = function_handle (vectorfield(1), 'vars', [x y]); |
| + | jComponent = function_handle (vectorfield(2), 'vars', [x y]); |
| + | |
| + | ## Setup a 2D grid |
| + | [X,Y] = meshgrid ([-0.5:0.05:0.5]); |
| + | |
| + | figure |
| + | quiver (X, Y, iComponent (X, Y), jComponent (X,Y)) |
| + | |
| + | </source> |
| + | |
| + | |
| + | * '''Demo of Anonymous function to symbolic function and back to anonymous function and then the use of the interval pkg.''' |
| + | |
| + | <source lang="octave"> |
| + | % this is just a formula to start with, |
| + | % have fun and change it if you want to. |
| + | |
| + | f = @(x) x.^2 + 3*x - 1 + 5*x.*sin(x); |
| + | |
| + | % these next lines take the Anonymous function into a symbolic formula |
| + | |
| + | pkg load symbolic |
| + | syms x; |
| + | ff = f(x); |
| + | |
| + | % now calculate the derivative of the function |
| + | |
| + | ffd = diff(ff, x); |
| + | |
| + | % and convert it back to an Anonymous function |
| + | |
| + | df = function_handle(ffd) |
| + | |
| + | |
| + | % this uses the interval pkg to find all the roots between -15 an 10 |
| + | |
| + | pkg load interval |
| + | fzero (f, infsup (-15, 10), df) |
| + | |
| + | ans ⊂ 4×1 interval vector |
| + | |
| + | [-5.743488743719015, -5.743488743719013] |
| + | [-3.0962279604822407, -3.09622796048224] |
| + | [-0.777688831121563, -0.7776888311215626] |
| + | [0.22911205809043574, 0.2291120580904359] |
| + | </source> |
| + | |
| + | |
| + | * '''Demo of inputting a function at the input prompt and making an Anonymous function.''' |
| + | |
| + | <source lang="octave"> |
| + | # This prog. shows how to take a |
| + | # string input and make it into an anonymous function |
| + | # this uses the symbolic pkg. |
| + | disp("Example input") |
| + | disp("x^2 + 3*x - 1 + 5*x*sin(x)") |
| + | str_fucn=input("please enter your function ","s") |
| + | fucn_sym=sym(str_fucn) |
| + | f=function_handle(fucn_sym) |
| + | # now back to symbolic |
| + | syms x; |
| + | ff=formula(f(x)); |
| + | % now calculate the derivative of the function |
| + | ffd=diff(ff); |
| + | % and convert it back to an Anonymous function |
| + | df=function_handle(ffd) |
| + | % now lets do the second derivative |
| + | ffdd=diff(ffd); |
| + | ddf=function_handle(ffdd) |
| + | % and now plot them all |
| + | x1=-2:.0001:2; |
| + | plot(x1,f(x1),x1,df(x1),x1,ddf(x1)) |
| + | grid minor on |
| + | legend("f","f '", "f '' ") |
| + | </source> |
| + | |
| + | |
| + | * '''Demo of ODE with a step input and initial conditions.''' |
| + | |
| + | <source lang="octave"> |
| + | |
| + | ## This is a demo of a second order transfer function and a unit step input. |
| + | ## in laplace we would have 1 1 |
| + | ## _______________ * _____ |
| + | ## s^2 + sqrt(2)*s +1 s |
| + | ## |
| + | ## So the denominator is s^3 + sqrt(2) * s^2 + s |
| + | # and for laplace initial conditions area |
| + | ## t(0)=0 t'(0) =0 and the step has initial condition of 1 |
| + | ## so we set t''(0)=1 |
| + | ## In the code we use diff(y,1)(0) == 0 to do t'(0)=0 |
| + | ## |
| + | ## I know that all this can be done using the control pkg |
| + | ## But I used this to verify that this solution is the |
| + | ## same as if I used the control pkg. |
| + | ## With this damping ratio we should have a 4.321% overshoot. |
| + | ## |
| + | syms y(x) |
| + | sqrt2=sym(1.41421); |
| + | de =diff(y, 3 ) +sqrt2*diff(y,2) + diff(y) == 0; |
| + | f = dsolve(de, y(0) == 0, diff(y,1)(0) == 0 , diff(y,2)(0) == 1) |
| + | ff=function_handle(rhs(f)) |
| + | x1=0:.01:10; |
| + | y=ff(x1); |
| + | plot(x1,y) |
| + | grid minor on |
| + | |
| + | </source> |