These are scripts I use to serialize some of the practice exercises we get on multivariable calculus, statistics and physics 2 class, they are not meant to be easy to understand or a tutorial on how to write CAS programs on the HP Prime graphing calculator but rather a set of solutions I was able to come up with, for some a valuable resource nonetheless.
I used to have a more complicated method for solving this, luckily multivariable Taylor series expansion is already implemented natively. You can find more info about the previous method here.
par={f=sin(x+y), v={x,y}, p=[1,1], ord=5}
series(f(par),v(par),p(par),ord(par))
This program builds a list with the format {{[solution point 1],[eigenvalues for the hessian matrix on that point]}, ..}
used to analyze maxima and minima of f
par={f=2*x^3+15*y^3–9*x*y, v={x,y}}
apply((p)->{p,EIGENVAL((hessian(f(par),v(par)))((v(par)) = p))},solve((grad(f(par),v(par))) = (makelist(0,x,0,size(v(par)))),v(par)))
Finds the minima/maxima and lambda values for f
restrited by the functions defined in r
par = {f = (sqrt(x^2+y^2+5)),v = {x,y},l = {l1},r = {(x-1)^2+y^2-1}}
solve((grad(f(par)+dot(l(par),r(par)),concat(v(par),l(par))))=(makemat(0,size(concat(v(par),l(par))))),concat(v(par),l(par)))
This CAS function takes a function as the first argument, a list of integration variables as the second, and a list of lists as the third containing two elements interpreted as the lower and upper integration limits respectively, the order of said lists should follow the order of the previous argument.
function, {var1, var2, ...}, {{var1_lim1, var1_lim2}, {var2_lim1, var2_lim2}, ...}
#cas
iint(function_, vars_, limits_):= begin
local gint_, index_, size_, result_;
gint_ := 'int';
result_ := function_;
size_ := min(size(vars_), size(limits_));
for index_ from 1 to size_ do
result_ := gint_(result_,
vars_[index_],
limits_[index_](1),
limits_[index_](2));
end;
return result_;
end;
#end
I've been messing around with this for far too long, but I finally found a usable solution, it involves code generating code (not elegant and unpredictable sometimes) to get it to be "eval safe", by this I mean that variables like X
or Y
won't be replace by their values.
The result is a function called cprods
that will return a function ready to compute the cartesian product for the limits and the variables passed to it. If a given point is within the specified boundaries, then the result will be true, and false otherwise.
#cas
cprods(variables_, limits_):= begin
local size_, index_, var_name_, ll_name_, ul_name_;
local var_list_, cond_, result_, gprogram_, tmp_mark_;
size_ := min(size(variables_), size(limits_));
// Since we're defining temp globals we should
// randomize the names to avoid name collisions
tmp_mark_ := rand(100000000);
gprogram_ := 'program';
var_name_:=(index_)->"variable_" + index_ + "_" + tmp_mark_ + "_";
ll_name_:=(index_)->"lower_limit_" + index_ + "_" + tmp_mark_ + "_";
ul_name_:=(index_)->"upper_limit_" + index_ + "_" + tmp_mark_ + "_";
cond_ := "";
var_list_ := "{ "
for index_ from 1 to size_ step 1 do
(#(var_name_(index_))) := variables_[index_];
(#(ll_name_(index_))) := limits_[index_,1];
(#(ul_name_(index_))) := limits_[index_,2];
if index_ > 1 then
cond_ := cond_ + " AND "
var_list_ := var_list_ + ", ";
end;
var_list_ := var_list_ + var_name_(index_);
cond_ := cond_ + ll_name_(index_) + " ≤ " + var_name_(index_) + " ≤ " + ul_name_(index_);
end;
var_list_ := var_list_ + " }";
result_ := expr("gprogram_("+ var_list_ +", nop, '" + cond_ + "')");
for index_ from 1 to size_ step 1 do
cas("purge(" + var_name_(index_) + ");");
cas("purge(" + ll_name_(index_) + ");");
cas("purge(" + ul_name_(index_) + ");");
end;
return result_;
end;
#end
With this function defined we can pass to it our limits and variables, then pass the returned function to the Advanced Graphing
app.
par = {f = 1,v = {y,x},l = {{(16-x^2)/8,√(16-x^2)},{0,4}}}
Advanced_Graphing::V1:=cprods({'X','Y'},(l(par))((v(par)) = {'X','Y'}))
This program will compute the center of gravity or discrete mean given a function describing density (function_
) with respect to the variables passed as the list vars_
, within the limits defined in limits_
, the input format is the same as for iint
which also needs to be defined for this to make use of it. This returns a vector representing the center of gravity or discrete mean. The total number for integrals computed by this function varies depending on the size of vars_
, and it 's equal to d+d*d
where d
is equal the size of said list.
#cas
dmean(function_, vars_, limits_):= begin
local index_, size_, result_, total_;
result_ := [];
total_ := iint(function_, vars_, limits_);
size_ := min(size(vars_), size(limits_));
for index_ from 1 to size_ do
result_[index_] :=
iint(function_ * vars_[index_],
vars_, limits_)/total_;
end;
return result_;
end;
#end
This function will compute the Fourier series for a periodic function expr_
with var_
defined in a_ .. a_ + T_
up to the n_
th term. If the optional parameter save_
is set to false then the an_
th and bn_
th terms won't be calculated for the symbolic value of n_
, this can be useful if the expression for these can only be solved using numerical approximations.
#cas
fourier_series(expr_, var_, T_, n_, a_, save_ = true):= begin
local args_, i_, result_, an_, bn_, saved_b_, saved_a_, ni_;
args_ := [expr_, var_, T_, nvar_, a_];
if save_ then
saved_a_ := fourier_an(op(args_));
saved_b_ := fourier_bn(op(args_));
an_ := 'limit(saved_a_, nvar_, ni_)';
bn_ := 'limit(saved_b_, nvar_, ni_)';
else
an_ := 'fourier_an(op(subst(args_, nvar_=ni_)))'
bn_ := 'fourier_bn(op(subst(args_, nvar_=ni_)))'
end;
ni_ := 0;
result_ := (1/2) * eval(an_);
for ni_ from 1 to n_ do
result_ += eval(an_) * cos(2*ni_*π*var_/T_) + eval(bn_) * sin(2*ni_*π*var_/T_);
end;
return result_;
end;
#end
fourier_series(x, x, 2, 20, -1)
This program only contains a function that takes a vector and returns a vector of the same size where an n
th element is progressively defined as the sum of its value on the n
th position at original vector and the value of the n
th - 1 element of the returned vector. For example the function call vec_acc([x, y, z])
would yield the expression [x, x+y, x+y+z]
, given the variables x
, y
and z
are interpreted as symbolic.
#cas
vec_acc(vec):=
begin
local a, res;
res := vec;
for a from 2 to size(vec) do
res[a] := res[a-1] + res[a];
end;
return res;
end;
#end