## 6682 Reputation

10 years, 178 days

## Recommendation...

Upload an executable worksheet using the big green up-arrow in the Mapleprimes toolbar.

Ideally this will be sufficiently complete to illustrate the problem you are having, including defnitions for all required quantities

## Don't send requests to my personal email...

All Maple-related communication should take place only on this site.

```I have this problem from which I want to separate constant but could not get after following your said procedure. can you pls solve for me
restart;
ode := N*diff(Phi(eta), eta, eta) - M^2*Phi(eta) = p;

bc := Phi(-sigma) = 1, Phi(sigma) = -k;```

The attached shows the

1. complete solution
2. the values of the two integration constants (although why you want these separately beats me
 > # # Set up and solve the problem the easy way. #   ode := N*diff(Phi(eta), eta, eta) - M^2*Phi(eta) = p;   bc := Phi(-sigma) = 1, Phi(sigma) = -k;   sol:=simplify(dsolve([ode, bc]));   (1)
 > # # Get the general solution in terms of a couple # of integration constants #   genSol:=dsolve(ode); # # Use odetest() on this solution and the supplied # boundary conditions, to determine required # values for the integration constants #   solve   ( odetest     ( genSol, [ode, bc])[2..3],     [_C1, _C2]   )[]; # # Substitute these constants of integration in the # general solution - givess the saem answer as the # previous execution group #   simplify( eval(genSol, %));   (2)
 >

## I can't make it any simpler...

than the attached

 > restart:   with(plots):
 > # # Set up a "toy" example of an 2nd order ode # with no initial/ boundary conditions and # solve it. # # Note that the colution contains two "unknown" # constants which Maple writes as _C1 and _C2 #   genSol:= dsolve(  diff(y(x),x,x) = 2*y(x) + 1                  ); (1)
 > # # So how are these two unknown constants to be # determined? The only way is to actually provide # two boundary conditions. So one could repeat # the above problem, but this time with a couple # of boundary conditions - as in the following, # which will produce a solution with no arbitrary # constants #   Sol:= dsolve( [ diff(y(x),x,x) = 2*y(x) + 1,                    y(0)=1,                    D(y)(0)=0                  ]                ); (2)
 > # # Despite what studying textbooks might lead you, # to believe, most ODEs cannot be solved "exactly" # and have to be solved "numerically", which Maple # will also do - the following will return a procedure # from which a "numerical" solution to the original # problem may be determined #   numSol:= dsolve( [ diff(y(x),x,x) = 2*y(x) + 1,                    y(0)=1,                    D(y)(0)=0                  ],                  numeric                ); (3)
 > # # So now we can plot the "exact" solution and the # "numerical" solution on the saem graph, just to # see if the difference is noticeable - and for # this ODE, it really isn't #   display   ( [ plot       ( rhs(Sol),         x=0..1       ),       odeplot       ( numSol,         [x,y(x)],         x=0..1       )     ],     color=[red, blue],     title="Exact and Numerical Solutions"   ); # # Although if one really wants to try one could # actually plot the difference between these two # solutions, just to see how accurate the numerical # solution process actually is. Before you get excited # by this plot, note the vertical scale indicating # that the error between the exact and numerical # solutions is O(10^-7) #   odeplot   ( numSol,     [x, y(x)-rhs(Sol)],     x=0..1,     title="Error between exact and numeric solutions"   );  > # # An alternative method of determining the values of the # constants in the general solution - ie genSol above, is # to use the odetest() command. Essentially this substitutes # the general solution, with the unknowns (_C1 and _C2) # into the original oded and supply the same boundary # conditions. Since all entries in the returned list should # be zero, the second and third entries in the returned list # give a pair of equations whihc the unknown constants _C1 # and _C2 must satisfy #   otest:= odetest( genSol,                    [ diff(y(x),x,x) = 2*y(x) + 1,                      y(0)=1,                      D(y)(0)=0                    ]                  ); (4)
 > # # Determine the values of the integration constants # which make all above list entries zero #   cVals:=solve(otest[-2..-1]); (5)
 > # # Now substitute the values of these constants in the # general solution. Note that this is identical to # the exact solution 'Sol' obtained above #   subs( cVals, genSol); (6)
 >

## Obsrervation...

Maple 2020 returns the two solutions you (and dharr) have already obtained, with no warniings. I wouldn't like to guarantee that this means there are no other solutions - probably just that the existence of any other solutions is very very unlikely.

 > restart; interface(version); solve({l*(2*l^2*lambda^4*sigma*w*a+l^2*lambda^2*mu*w*b+6*l*lambda^2*m*sigma*a^2-6*l*lambda^2*m*b^2+6*l*m*mu^2*a^2-l*lambda^2*    rho*sigma*a-l*mu^2*rho*a+4*lambda^2*sigma*w*a+4*mu^2*w*a) = 0,  l*(2*l^2*lambda^3*sigma*w*a+6*l^2*lambda^2*mu*w*b+2*l^2*lambda*mu^2*w*a+12*l*lambda^2*m*sigma*a*a-12*l*lambda^2*m*b*b-l*lambda^2*rho*sigma*a+12*l*m*mu^2*a*a-l*mu^2*rho*a+4*lambda^2*sigma*w*a+4*mu^2*w*a) = 0,  l*(5*l^2*lambda^3*sigma*w*b-3*l^2*lambda^2*mu*sigma*w*a-7*l^2*lambda*mu^2*w*b-3*l^2*mu^3*w*a+12*l*lambda^2*m*sigma*a*b+12*l*lambda^2*m*sigma*a*b-l*lambda^2*rho*sigma*b+24*l*lambda*m*mu*b*b+12*l*m*mu^2*a*b+12*l*m*mu^2*a*b-l*mu^2*rho*b+4*lambda^2*sigma*w*b+4*mu^2*w*b) = 0,  l*(8*l^2*lambda^3*sigma*w*a+6*l^2*lambda*mu^2*w*a+12*l*lambda^2*m*sigma*a*a+6*l*lambda^2*m*sigma*a^2+l^2*lambda*mu*w*b-6*l*lambda^2*m*b^2-l*lambda^2*rho*sigma*a+12*l*m*mu^2*a*a+6*l*m*mu^2*a^2-6*l*lambda*m*b^2-l*mu^2*rho*a+4*lambda^2*sigma*w*a+4*mu^2*w*a) = 0,  -l*(4*l^2*lambda^3*mu*sigma*w*a-l^2*lambda^3*sigma*w*b+l^2*lambda*mu^2*w*b-12*l*lambda^2*m*sigma*a*b+l*lambda^2*rho*sigma*b-12*l*lambda*m*mu*b^2-12*l*m*mu^2*a*b+l*mu^2*rho*b-4*lambda^2*sigma*w*b-4*mu^2*w*b) = 0,  6*l^2*(l*lambda^2*sigma*w*a+lambda^2*m*sigma*a^2+l*mu^2*w*a+m*mu^2*a^2-lambda*m*b^2) = 0, 2*l^2*(l*lambda^2*sigma*w*a+6*lambda^2*m*sigma*a*a+3*l*lambda*mu*w*b+l*mu^2*w*a+6*m*mu^2*a*a-6*lambda*m*b*b) = 0,  -2*l^2*(5*l*lambda^2*mu*sigma*w*a-l*lambda^2*sigma*w*b+5*l*mu^3*w*a-6*lambda^2*m*sigma*a*b-6*lambda^2*m*sigma*a*b-l*mu^2*w*b-6*lambda*m*mu*b^2-6*m*mu^2*a*b-6*m*mu^2*a*b) = 0,  6*l^2*b*(l*w+2*m*a) = 0}, {a, a, a, b, b});  (1)
 >

## Before you can read the data...

on your machine you will have to change the line

someData:=ExcelTools:-Import("C:/Users/TomLeslie/Desktop/testDAta.xls"):

to something that makes sense for your machine.

The filePath in the above command, ie

"C:/Users/TomLeslie/Desktop/testDAta.xls"

only refers to the location + filename I used on my computer to store the data for test purposes.

I have no idea where the data file is stored on your machine! Only you know this!

## Don't think this is possible...

If you examine the output of the dsolve() command in my original post, you will note that it contains q1(X) = q1(X) - in other words q1(x) is entirely arbitrary.

You can pick any function you want for q1(x), substitute it in the expressions for all the other functions, and the solution is still valid

## Correct...

The concept of recursion is very useful, but only when there is a "terminating case". So

x:=10
x:=x+1;

is perfectly fine, because the right-hand-side 'x+1', will evaluate to '10+1', ie 11, and 11 is assigned to 'x'. No problem

However

p:=p+1

doesn't make much sense. If applied in a brain dead way the right hand side 'p+1' will become '(p+1)+1' which will evaluate to '((p+1)+1)+1) - and so on ad infinitum

Asssignments are not equations - it is obviously true that one could write the equation  p=p2+1 and "solve" this equation for p, but the assignment p:=p2+1 doesn't make any sense

## @HaHu  You posted the code u :...

You posted the code

u := min(max(0, z), 1); z := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w; u := min(max(0, c), 1); c := (lambda(t)*e(t)+lambda(t)*((1-tau)*delta*e(t)+epsilon*i(t))+lambda(t)*(delta*tau*e(t)+epsilon*i(t)))/w; u := min(max(0, p), 1); p := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;
Error, recursive assignment

If I tidy this up a little, just to make it more readable

u := min(max(0, z), 1);
z := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;
u := min(max(0, c), 1);
c := (lambda(t)*e(t)+lambda(t)*((1-tau)*delta*e(t)+epsilon*i(t))+lambda(t)*(delta*tau*e(t)+epsilon*i(t)))/w;
u := min(max(0, p), 1);
p := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;
Error, recursive assignment

In the last line,

p := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;

note that 'p' depends on u. Now check the definition of u, which from your code is

u := min(max(0, z), 1);

so that u depends on 'z'. Now check the definition of 'z', which from your code is

z := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;

so that 'z' depends on u. Now check the definition of u, which from your code is

u := min(max(0, p), 1);

so u depends on p;

Thus in the last line of the above code, ie

p := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;

when Maple makes all the evaluations on the right hand side - the name 'p' occurs on both sides of the assignment, in other words, this is equivalent to

p:=someFunctionOf(p)

which is a recursive assignment. Don't now how much clearer I can make it!

## Yes you have a recursive assignment...

because in the command

p := beta*(1-u)*s(t)*(sigma*e(t)+sigma*i(t))*(lambda(t)-lambda(t))/w;

'p' depends on u,
u depends on 'z',
z depends on u,
and u depends on 'p'

A quick way to check this is to apply the command indets(  expr, 'name') where 'expr' is the right-hand-side of the above assignment. This will return {p, t} - see the attached

## Well...

Importing dat from EXCEL is trivial with ExcelTools:-Import()

What happeans next is very dependent on exactly what the data in the Excel file represents: A (non-exhaustive) list of possinilities might be

1. samples fom a continuous-time impulse response
2. samples from a discete-time impulse response
3. samples from a continuous-time step response
4. samples from a disrete-time step response
5. discrete-time numerator/denominator coefficents
6. continuous-time numerator/denomiator coefficients
7. discrete time poles/zeros
8. continuous-time poles/zeros
9. probably a few others I can't think of at the moment

So when you say

How do you create a transfer function of a time response response of e.g some data in excel, csv etc

I'd have to say it depends a lot on what the hell the data in the Excel file represents

## Minimal changes...

to the worksheet you posted as  evalf_error_3.mw is given in the attached

## Try...

https://www.maplesoft.com/applications/view.aspx?SID=4514&view=html

whihc seems to cover most cases finite, semi-infinite, and infinite strings for a variety of initial conditions, and all using d'Alembert's equation

## Probably not much use but...

@Christopher2222
i just tried the command in my original post in a sequence of Maple releases - all running on 64-bit Windows 7

Maple 18 -     Fails

Maple 2015 - Fails

Maple 2016 - Fails

Maple 2017 - Succeeds

Maple 2018 - Succeeds

Maple 2019 - Succeeds

Maple 2020 - Succeeds

I haven't been able to work out what the hell is different between Maple 2106 and Maple 2017, so have no useful suggestions to make (other than update Maple)

## Programming practice...

There is an important distinction between using (for example) m and m__2. If neither of these is assigned to anything, then both will prettyprint as m2 so they "appear" to be exactly the same. However the first of these refers to the second entry in an indexable quantity (table, list vector etc). The second is just a name which happens to have a suffix.

As a more concrete/complete example suppose you have some code where you have to distinguish between an 'old' and a new value of a variable called 'x', Using x[old] and x[new] will create a table called 'x' with two 'keys' called 'old' and 'new'. Using x__old and x__new will just create two simple variable names which happen to prettyprint with a suffix.

Somewhat surprisingly (to me at least), a lot of the time, either approach will "work" - but every once in a while, the distinction will bite you! - and it might take you a while to figure out why.

The general recommendation is to use `[]` when you absolutely know that you want an indexable quantity, ie you are thinking of storing data in a 'container', such as a table/array/whatever. If you just want a couple of completely independent variable names, then use `__`

#####################################################

Modules and Packages - sorry this got a bit TLDR

A long time ago, "packages" in Maple, (such as the plots() package) were implemented using tables. You could "more-or-less" think of the

with(plots);

command as loading a table into your workspace, with the 'keys' of the table being the commands you want to run, and the "entries" of the table being the corresponding procedures (aka code) which actually executes. Since such a package looked/behaved a bit like a table, if you just wanted to call a specific command you would use plots[odeplot].

At some point (quite a long time ago) Maple decided that this table-based approach to writing packages needed improvement, and came up with the module-based method. Most (all?) in-built packages were converted from from the table-based to module-based. The default calling mechanism for a command from a module-based package is with the member selection operator. ':-', so for example  plots:-odeplot().

However in order not to break all the user code which had been written before a package was converted from table-based to module-based, command selection using the (old-fashioned) square brackets '[]' had to be supported.

So, does it matter whether you use

packageName[packageCommand](arguments) or

packageName:-packageCommand(arguments)

???
Where might the distinction be relevant? The only one I can think of is if you happen (inadvertenly) to use the name of a packageCommand as a 'name' for something else in your own code.

For example in the worksheet I provided previously, if you happen to have a variable called 'odeplot', the code

```  odeplot:=fred:
plots:-odeplot(nsol, [[t, r(t)],[t, theta(t)]], t=0..10, color=[red,blue], axes=boxed);
```

will still generate the plot you want, but

```  odeplot:=fred:
plots[odeplot](nsol, [[t, r(t)],[t, theta(t)]], t=0..10, color=[red,blue], axes=boxed);
```

will give you an error message, because plots[odeplot] will first evaluate to plots[fred], and then you get

Error, fred is not a command in the plots package

So, on balance, I would recommend sticking with ':-'

A counterexample

I suppose it is possible that if a package contains two commands which do different things but will accept the same argument list then the ability to select which command to execute might be useful. This is actually much simpler to do using the '[]' notation

For example, consider the toy example

```  M:=<1,2,3 ; 4,5,6>;
f:= a->`if`( a>0, Row, Column):
LinearAlgebra[f(2)](M, 1);
LinearAlgebra[f(0)](M, 1);
```

the command

LinearAlgebra[f(2)](M, 1);

will output the first row of the matrix 'M' and the command

LinearAlgebra[f(0)](M, 1);

will output the first column

It is possible to replicate this behaviour using ':-' rather than '[]', but it is more awkward

```M:=<1,2,3 ; 4,5,6>;
f:= a->`if`( a>0, Row, Column):
parse(cat(`LinearAlgebra`, `:-`, f(2)))(M,1);
parse(cat(`LinearAlgebra`, `:-`, f(0)))(M,1);
```

Whilst either of the above will work, I would regard both as evidence of "wilfully obscure programming practice"

﻿