Carl Love

Carl Love

28025 Reputation

25 Badges

12 years, 312 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Here's the worksheet:
 

restart:

RLC:= R*diff(x(t),t$2) + L*diff(x(t),t) + x(t)/C = 0;

R*(diff(diff(x(t), t), t))+L*(diff(x(t), t))+x(t)/C = 0

IC:= x(0)=10, D(x)(0)=0;

x(0) = 10, (D(x))(0) = 0

params:= [R=10, L=20, C= 1/100]:

Sol:= dsolve(eval({RLC, IC}, params));

x(t) = (10/7)*exp(-t)*sin(7*t)+10*exp(-t)*cos(7*t)

plot(eval(x(t), Sol), t= 0..5);

#Original square wave function:
step:= t-> piecewise(t < 0, 0, 1):
f:= t-> sum((-1)^n*step(t-n), n= 0..50):

#
#It's equivalent to this simpler function:
f:= t-> piecewise(floor(t)::even, 1, 0):

plot(f, 0..5, axes= frame, title= "Square Wave",thickness= 4, gridlines= false);

RLC2:= lhs(RLC) = 200*f(t/3);

RLC2 := R*(diff(x(t), t, t))+L*(diff(x(t), t))+x(t)/C = 200*piecewise((floor((1/3)*t))::even, 1, 0)

Sol2:= dsolve(eval({RLC2, IC}, params), numeric):

plots:-odeplot(Sol2, [[x(t), diff(x(t),t)]], t= 0..25, numpoints= 1000, thickness= 2, title= "Phase portrait", gridlines= false);

plots:-odeplot(Sol2, [t, x(t)], t= 0..25, numpoints= 1000, thickness= 2, title= "Solution curve", gridlines= false);

 


 

Download RLC.mw

You made a small mistake while solving. When you divide through by 10, the last term becomes 10*x. You have 50*x.

Here's how to check your work with Maple:
 

restart:

RLC:= R*diff(x(t),t$2) + L*diff(x(t),t) + x(t)/C = 0;

R*(diff(diff(x(t), t), t))+L*(diff(x(t), t))+x(t)/C = 0

IC:= x(0)=10, D(x)(0)=0;

x(0) = 10, (D(x))(0) = 0

params:= [R=10, L=20, C= 1/100]:

Sol:= dsolve(eval({RLC, IC}, params));

x(t) = (10/7)*exp(-t)*sin(7*t)+10*exp(-t)*cos(7*t)

plot(eval(x(t), Sol), t= 0..5);

 


 

Download RLC.mw

This will work for both sums and products, and many other types as well:

op(0, expr)(op(2.., expr))

The syntax M[i][j] is supported (although it can be extremely inefficient), and your assignment statements are actually being executed. So something(s) is/are being assigned the value 1. The questions are Why doesn't this produce your expected result? And what happened to those somethings? I submit the following two examples as aids towards you understanding that, knowing that you are a sophisticated user. I do not suggest that you or anyone else do this in actual polished code.

doit:= proc()  
local i, j, Row, M:= Matrix((3,3));                                                         
   for i to 3 do
      Row[i]:= M[i];  
      for j to 3 do  
         Row[i][j]:= 2^i*3^j                                     
      od;
      M[i]:= Row[i]                             
   od;              
   M 
end proc
:                                           
doit();  
doit:= proc()  
local 
   i, j, 
   M:= Matrix((3,3), order= C_order), 
   ByRows:= Vector(3, k-> ArrayTools:-Alias(M, 3*(k-1), [3]))
;                                                         
   for i to 3 do  
      for j to 3 do  
         ByRows[i][j]:= 2^i*3^j                                     
      od                             
   od;              
   M  
end proc
:                                           
doit(); 

Both examples produce the same result---a Matrix equivalent to Matrix((3,3), (i,j)-> 2^i*3^j). (I chose this Godel-numbering formula because you can immediately reconstruct the i and j from the entry alone.) The syntax M[i] extracts the ith row as an anonymous Vector, and M[i][j]:= ... assigns to the jth element of that Vector. What happens to that anonymous Vector? Unless you assign it back to M[i] (as in the first example), it gets garbage collected. The second example uses Alias to rename M's row vectors so that assignment to them (through the name ByRows) is equivalent to assignment to itself rather than to some anonymous object. So, this second example allows you to use syntax very similar to your original. But, once again, I do not recommend that you actually do this because there's no good reason to since there are several much better ways.

I'm sure that by now you know about unapply, as in unapply(f,x). However, it doesn't work well in this double-arrow situation. Cases that are too complicated for unapply can usually be handled by a special usage of subs:

g:= subs(_f= subs(_f= f, x-> _f), (a,b)-> _f)

Note that unlike Kitonum's Answer, this does produce a true double-arrow procedure:

(a,b)-> x-> a*x+b

This usage of subs is AFAIK undocumented, and it cannot be fully understood through an understanding of ordinary subs. However, it has extensive and long-standing use in library code, such as in the code of unapply itself. For me, it's a fundamental tool of meta-programming, and it's often the only way to accomplish a goal, such as producing a procedure that can be compiled to external code or used with evalhf or Threads. The procedure g produced by Tom's method cannot be used like that.

 

I just showed you yesterday how to generate 2000-bit primes! Did you see that Answer?

There are no special commands needed to work with large integers in Maple. You just enter the computation normally, for example: 2^2000. It can easily handle numbers even much larger than that.

@Christian Wolinski 

Aha! I managed to deconstruct subsindets. The basic built-in subsindets (by which I mean without any options in square brackets) is equivalent to this Maple procedure: 

SubsIndets:= proc(e, t::type, T)
local J:= sort([indets(e, t)[]], (x,y)-> length(x)<length(y)), r:= e; # [*1]
   to nops(J) do (J,r):= subs(J[1]= T(J[1], _rest), [J[2..], r])[] od;
   r
end proc:

So, applying it to your examples:

e:= (((Q(a)^3)^(5/4))^(15/7))^(6/8);
T:= x-> `if`(op(1,x)::specfunc(Q), Q(x), x);
SubsIndets(e, anything^rational, T);
SubsIndets(e, specfunc(Q)^rational, Q);

So, considering the simplicity of the recursive process in the above algorithm, this may be the intended behavior. If so, then the take-away is that the user should refine the type in the second argument rather than filtering to some subset of that type in the transformation procedure. If you have trouble refining the type, you can always resort to something like this:

And(t, satisfies(proc(x) ... end proc))

[*1] As of Maple 2017 (I believe), that sort command can be shortened to

sort([indets(e,t)[]], key= length)

The commands nextprime or prevprime can do it very quickly. Here's three examples: the smallest 2000-bit prime, the largest, and a random one:

p:= nextprime(2^1999);
q:= prevprime(2^2000);
randomize(): r:= nextprime(rand(p-1..q-1)());

 

The computations are trivial, of course, and shown below. I'm not sure of the exact output that you want for the table and plot; one option for each is shown below.

restart:
X:= [3,6,4,13]:  Y:= [8,6,5,7]:
Pts:= `[]`~(X,Y);
Dist:= proc(X,Y) option remember; sqrt(add((X-~Y)^~2)) end proc:
Pairs:= combinat:-choose(Pts,2):
(Dist@op)~(Pairs):
DistTable:= copy(op(4, eval(Dist)));
plot(Pairs, style= pointline, symbolsize= 20, symbol= solidcircle);

Generally, I'd say no. The only reason that I've ever done it was to make a precise measurement of the scalability of a multi-threaded computation, i.e., what fraction of time reduction is achieved for each additional processor.

The command that you want is

indets(expr, {identical(y), identical(y)^anything});

It can be done by

if andmap(evalb, zip(`<=`, a, b)) then ...

This is a little better than `and`(seq(...)) because the andmap will stop and return false as soon as it has found any false inequality.

Note that forall and exists are pretty much inert placeholders unless they're used with code that specifically processes them. (I know of no such code, but I could easily write some; on the other hand, andmap and ormap, respectively, are their finite-set equivalents.)

The syntax is A:-B:-foo(). As far as I know, the A::B syntax is only used by showstat and similar debugger commands, and its purpose is to allow for access to module locals as well as exports (for debugging purposes only, of course).

If you want to call foo from inside A but outside B, you should use B:-foo() (i.e., without the A:- prefix).

The command

NameStrings:= index~(index~(LibraryTools:-ShowContents(), 1), 1..-3):

will produce a list of all top-level (i.e., global) names in the library. For a "naked" (i.e., no added packages) installation of Maple 2019.1, that's 14,590 names. The names are given as strings; if they were given as names, some of them (the ones that aren't tables, modules, or procedures) would evaluate spontaneously as you looked at them, which would probably ruin the effect. I'll assume that if you want, you can figure how to decide which of these names are protected. If not, I'll give some help.

There are two other categories of names that might be of interest to you: names inside modules (packages), and builtin names (commands such as evalf that are stored directly in the kernel rather than in a library). I would guess the module category has about 100,000 names (I haven't counted), and the builtin category about 500 (I listed them once, several years ago). Each of these lists could be produced with a handful or so of lines of code, if you're interested.

Your series command uses 1 as the third argument, the order argument. That extracts only the "constant" term, which truly is 0. If you increase that to a larger integer, you'll get some nonzero terms.

I think that it's usually better to use asympt for series "at" infinity. In this case, that would be

asympt(w6(A,5,27/4,k), k, 4);

where 4 can be increased to any larger integer.

First 134 135 136 137 138 139 140 Last Page 136 of 395