retrieving the constant in an equation

Hi,
I want to know if there is a function or simple way that retrieves the constant of an equation?
e.g eq=2x^2+4y-6 the constant here is -6

gkokovidis's picture

retrieving the constant in an equation

>restart:
>eq:=2*x^2+4*y-6;

= 2*x^2+4*y-6

>tcoeff(eq);

-6

Regards,
Georgios Kokovidis
Dräger Medical

what if?

But in cases that we don't have any constant, tcoeff does not give us 0:

restart:
>eq:=2*x^2+4*y;

eq := 2*x^2+4*y

tcoeff(eq);

4

We need here to get 0 as the constant of the equation

Doug Meade's picture

remove and indets

Here is one possible solution to your problem.

Basically, you want to keep only the terms that do not contain any indeterminates (variables) in an expression.

e1 := 2*x^2+4*y-6:
e2 := 2*x^2+4*y:
remove(has,e1,indets(e1,name));
                                     -6
remove(has,e2,indets(e2,name));
                                      0

Other solutions are possible with typematch. Maybe someone else can post some of these.

Doug

---------------------------------------------------------------------
Douglas B. Meade
Math, USC, Columbia, SC 29208  E-mail: mailto:meade@math.sc.edu       
Phone:  (803) 777-6183         URL:    http://www.math.sc.edu/~meade/
Robert Israel's picture

Another way

You could set all variables in your polynomial to 0
(please don't call it an "equation", because it doesn't contain =).

> eval(eq, map(`=`,indets(eq),0));
John Fredsted's picture

Constant term of algebraic expression

Here is a method that works for any algebraic expression of any number of variables:

getConst := (expr::algebraic,vars::list(name)) -> select(is,expr,freeof(vars)):

where vars is a list of the considered variables of the algebraic expression. An example:

expr := x^2 + y^2 + z^2 - cos(x) - cos(y) - cos(z) + a:
getConst(expr,[x]);
getConst(expr,[y]);
getConst(expr,[z]);
getConst(expr,[x,y]);
getConst(expr,[y,z]);
getConst(expr,[z,x]);
getConst(expr,[x,y,z]);
                  2    2                      
                 y  + z  - cos(y) - cos(z) + a
                  2    2                      
                 x  + z  - cos(x) - cos(z) + a
                  2    2                      
                 x  + y  - cos(x) - cos(y) + a
                         2             
                        z  - cos(z) + a
                         2             
                        x  - cos(x) + a
                         2             
                        y  - cos(y) + a
                               a

use type, not is.

You should really be using `type', not `is', for the comparison.  That is

getConst := (expr::algebraic,vars::list(name)) -> select(type,expr,freeof(vars)):


 
Note that you may or may not want the following:
 

getConst(f[x]+x + y, [x]);

                                          y
 
That is, type(freeof(f[x],x) returns true. 

acer's picture

quibble

Since freeof is not protected and may have been assigned a value by the user, or may be used alongside a local of the same same from within a procedure, that call would be better as,

select(type,expr,':-freeof'(vars)):

It bothers me a little, that the help-pages like ?type,freeof don't show it being used that way. That's also a general complaint I have about many help-pages -- the lack of uneval quotes in examples where they may be necessary in a general context. I also wonder why mint doesn't complain about this example.

 

acer

protecting types

Your quibble is relevant.  I'm fairly careful about adding the forward quotes in production code, but that example was proves otherwise. I've been considering adding a typeface in my maplev emacs mode for standard unprotected types but haven't got around to it.

Note, however, that one has to distinguish the usage.  As a rule, one should not use forward quotes in argument declarations, but they are necessary (for protection) in the actual code, as well as local declarations. There have been inconsistencies on this in various releases. 

Mint doesn't complain because it sees freeof(x) as a function call.

acer's picture

right, thanks

Thanks for that, about mint. I don't know what I could have been thinking.

Yes, there are some gotchas when using code based on Maple 11's parameter-processing but within a Maple 10 session.

acer

John Fredsted's picture

Using type

Concerning the use of type instead of is: you are absolutely right, of course. Thanks for pointing that out.

Concerning your example: you may have a point there. Fooling around with that expression I stumbled upon the following.

Why does type([x] + 1,algebraic) and type([x],algebraic) evaluate differently, the former being true, the latter being false?

Robert Israel's picture

type

According to the definition in ?type,algebraic:

An expression is of type algebraic if it is one of the following types:
complex type/extended_numeric `+` `*` `^`
function indexed name SDMPolynom
SERIES series type/uneval zppoly
 

[x]+1 is certainly of type `+`, and therefore it is of type algebraic.  On the other hand, [x] is not any of the listed types; it is a list.

The question of whether [x]+1 does anything useful as an expression is beside the point, as far as type is concerned.

 

John Fredsted's picture

Sleepy me

You are absolutely right, of course. Prior to posting I thought something along the following lines:

If a sum of an integer (which is algebraic) and something else is algebraic, then that something else must also be algebraic. That, clearly, is not Maple thinking. Thanks for waking me up.

JacquesC's picture

algebraic is a surface type

In Maple lingo (although I don't know if it appears in the documentation anywhere!), type algebraic is a surface type.  That means that it only checks the outermost 'type' present in the object at hand to make a decision.  This makes it extremely fast, but also rather counter-intuitive (as John found out the hard way).  So much so that there is a fair bit of code in Maple's own library which is not so well protected by type-checks because they use 'algebraic' where they really mean "deep algebraic".

Now, as far as I know, Maple still does not have a type for a "deep algebraic"!  It has some 'deep' types - polynom and ratpoly come to mind. 

John Fredsted's picture

Thanks for making it clear

Thanks, Jacques, for making clear this point concerning surface contra deep types, which exactly hit the nail on the head concerning how I felt about the issue yesterday.

Actually, for a short while yesterday, I tried to formulate something along these lines, but gave up trying because I could not figure out how to put it. With your post you have now provided me with the vocabulary for doing so.

John Fredsted's picture

Deeply algebraic

Am I correct in thinking that the following procedure will verify whether or not an expression is "deeply algebraic"?

isDeeplyAlgebraic := proc(x)
	if not type(x,algebraic) then false
	elif type(x,atomic) then type(x,algebraic)
	else andmap(isDeeplyAlgebraic,x)
	end if
end proc:
JacquesC's picture

Almost

One would indeed think that that is it.

However the problem is that sometimes you want to consider some expressions to be "algebraic" even though it is made up of non-algebraic pieces!  For example, consider int(f(x),x=0..1).  That is not algebraic in your sense, as neither type `=` nor `..` are algebraic.  So the problem is some data representations for what we think of as algebraic objects are not made up of pieces which are considered 'algebraic' (nor should they be!). 

Note that the only exception(s) to your code are all of the same shape: they are a 'mathematical function' (so of surface type function) where some additional data is represented non-algebraically.  For those 'mathematical functions', the best thing is to not recurse into them, at least if you wish DeeplyAlgebraic to correspond to something more intuitive.

John Fredsted's picture

Almost happy

Thanks for that precise analysis. I wonder, though, how these (special) mathematical functions should be handled by the procedure: simply adding a line like

elif type(x,function) then true

is of course quite nonsensical as that would also make f([x]), say, deeply algebraic - in fact, for functions it would make isDeeplyAlgebraic behave surface algebraically. Is there a compact way of doing such a thing, or does one have to treat each case individually?

JacquesC's picture

type 'mathfunc'

The closest type is type 'mathfunc', which tests if Maple's knowledge of a function is deep enough that it knows it is a "mathematical function" instead of a random procedure.  This is by no means fail-safe, but it is a reasonable approximation.  I think there might be a similar type for things like Int and Sum as well, but I can't find it right now.

In general you have to treat each case individually.  This is why many functions in Maple have 'extension mechanisms', so that users can plug in new cases themselves.

John Fredsted's picture

Thanks

Thanks for setting the course. Now it is up to me to set sail.

design of 'mathfunc'

I wonder why 'mathfunc' fails in some cases, eg:

lf:=[bernoulli, euler, ilog2, unwindK]:
seq([lf[i],type(lf[i],mathfunc)],i=1..nops(lf));

[bernoulli, false], [euler, false], [ilog2, false], [unwindK, false]

Ie, is there a list or something like that where they are included by hand, and some functions are missed?
 

 

 

Robert Israel's picture

mathfunc

Well, the code of `type/mathfunc` is quite simple:

`type/mathfunc` := proc(f)
     type(f,'symbol') and member(f,{'Dirac', 'ilog', 'Product', 'Limit', 'limit', 'int'}) 
     or type(f,'name') and type(`evalf/` || f,'procedure') 
     or type(f,'procedure') and member('operator',[op(3,eval(f))])
end proc
 

So, for example, ilog is a mathfunc because it's explicitly listed, ilog10 is one because there's a procedure `evalf/ilog10`, and any function that you might define using -> qualifies by the third clause. 

I have no idea why there should be a procedure `evalf/ilog10` but no `evalf/ilog2`.

John Fredsted's picture

Surface and nested types

Almost by accident, today I stumbled upon the following help page which is relevant for this thread:

?type,surface

Just for the record.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}