Carl Love

Carl Love

28055 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

First, here are some things that you're doing wrong in your code snippet:

  1. By row, I assume that you mean Row from LinearAlgebra. Note that its name is capitalized.
  2. When the left operand of := is a function call (such as your row(out, k)), it is not evaluated (i.e., the function is not called) before the assignment[*1]. Rather, these assignments are stored in something called the remember table of row. (At the moment, it's not useful to explain remember tables further; but I'll be happy to when it becomes actually useful.)
  3. To do an assignment to a left operand that needs to be evaluated first, use assign, as in assign(f(x)= y).
  4. I assume that out is a matrix, but it would need to be already created, and have the correct dimensions for your idea to have any chance of working. (And there are several other reasons why this won't work, but they're too complicated to explain right now. Anyway, there are several other easy ways to do what you want.)

Second, just for the sake of showing you some briefer syntax, here's a slight variation on Joe's Answer:

#shortcut "hand-typed" matrix constructor syntax:
M:= <1, 2, "A"; 2, 3, "B"; 3, 4, "A">;

M[[seq](`if`(M[i,3]="A", i, NULL), i= [rtable_dims](M)[1])];

Third, there's a matrix-based superstructure called a DataFrame that's perfect for fancy row-selection operations such as I suspect you have in mind. A DataFrame is just an Object whose underlying structure is an ordinary Matrix with many OOP-style fancy indexing methods overloaded onto the regular square-bracket indexing operator.

In the code below, is the matrix from above, and columns is a list of names for the columns. There's nothing special about the names that I chose ([1, 2, key]).

DM:= DataFrame(M, columns= [1, 2, key]):
DM[DM[key]=~ "A"];


Footnote [*1]There's only one exception to this that I'm aware of: When function cat is the left operand of :=, then it IS evaluated before the assignment is made, as in

cat(x, 3):= 4;

which assigns 4 to x3.

 

Like this:

W:= `[]`~(P, Q);

An operator is called a binary infix operator if it can take 2 arguments and can be placed between (rather than in front of) them. So, most familar arithmetic operators (such as +, -, *, /, =, <, ^, and others) are binary infix operators. The way that you wrote your Question suggests that you want to use oper in infix form. This is easy in Maple, and it's one of my favorite features of Maple's syntax. The operator's name should begin with &, followed by letters or a wide variety of punctuation marks.

AnyOp:= proc(`&op`, x, y) x &op y end proc:
AnyOp(`*`, 7, 3), AnyOp(`+`, 7, 3); 

                             
21, 10

When the operator is not being used in infix form, it must be in back quotes (notice `&op` immediately after proc). This is true for all infix operators, not just those beginning with (notice `*` and `+` above). On the other hand, when they are used in infix form, they must NOT have quotes.

In the examples above, the operation that is passed to `&op` need not be infix as long as it can accept two arguments (see iquo and irem below):

AnyOp:= (`&?`, x, y)-> x &? y:
AnyOp~([`*`, `+`, `-`, `/`, `mod`, iquo, irem, `^`], 7, 3);

                  [21, 10, 4, 7/3, 1, 2, 1, 343]

Since mod is one of Maple's infix operators, even though it's just alphabetic characters, it needs the quotes when it's passed.

 

The plot can be made perfectly (no gaps, no jaggedness) and easily (no fancy options or extra points or precision needed) by these steps:

  1. Express your Watt equation as an expression implicitly equated to 0.
  2. Convert the expression from polar coordinates to Cartesian (x,y). (There's a command for that, but rather than looking up its syntax, I just used the usual well-known substitutions.)
  3. Rationalize the resulting algebraic function with evala@Norm. (The resulting rational function can be simplified significantly, which might be useful if you're going to do further algebra on it; but, it plots with no trouble without simplification.)
  4. Put in your numeric parameters.
  5. Plot with implicitplot.
restart:
WattEq:= r^2 - (b^2 - (a*sin(theta) + sqrt(c^2 - a^2*cos(theta)^2))^2);
params:= [a= 3.1, b= 1.1, c= 3.]:  rng:= -1.2..1.2:
W:= (evala @ Norm @ eval[recurse])(
    WattEq,
    #polar to cartesian: 
    [r= sqrt(x^2+y^2), (cos,sin)(theta)=~ (x,y)/~r]
);
  

plots:-implicitplot(eval(W, params), (x,y)=~ rng, scaling= constrained);

The most-basic way to remove specific cases of inertness is to change a name beginning with % to the equivalent name without a %. Thus, this handles your case:

Set:= eval({op}(InertForm:-Parse(Str)), %Vector= Vector);
InertForm:-ToMathML(`%+`(Set[]));

 

Here are two procedures: The first detects whether its argument is an overload, and the second deconstructs an overloaded argument into its original procedures.

IsOverload:= (P::procedure)-> 
    evalb(indets(ToInert(eval(P)), specfunc(_Inert_OVERLOADLIST)) <> {})
:
UnOverload:= (P::And(procedure, satisfies(IsOverload)))->
    indets(
        subsindets(
            ToInert(eval(P)), 
            specfunc(_Inert_OVERLOADLIST), 
            %overload@[FromInert]@op
        ),
        specfunc(%overload)
    )[-1]
:

#Example usage:

P:= overload([
    proc(n::And(posint, even)) option overload; n/2 end proc,
    proc(n::And(posint, odd)) option overload; 3*n+1 end proc,
    proc(n) 'procname'(args) end proc
]);
P := overload(
  [
  proc (n::(And(posint, even))) option overload; (1/2)*n end proc, 
  proc (n::(And(posint, odd))) option overload; 3*n+1 end proc, 
  proc (n) ('procname')(args) end proc])

IsOverload~([P, cos]);
                         [true, false]
UnOverload(P);
%overload(
  [
  proc (n::(And(posint, even))) option overload; (1/2)*n end proc, 
  proc (n::(And(posint, odd))) option overload; 3*n+1 end proc, 
  proc (n) ('procname')(args) end proc])

 

Replace with %*:

P:= a %* b %* c %* d %* e;

In your 7-year-old version of Maple, you may need to use prefix form:

P:= `%*`(a, b, c, d, e);

Here's another way to do the unit conversion on a vector or matrix that I suspect is closer to what you were originally trying. Enter your vector, highlight and right click, do the unit conversion as you originally tried. When that's done, the vector will appear unchanged, as you initially reported. Now, give the command

rtable_eval(%);

The unit-converted vector should now appear.

The issue here is somewhat like the rtablesize issue that I wrote about an hour ago in the sense that the computations are already done but you're not seeing the results; however, in this case the issue doesn't only affect the display. (It took me many years to fully understand the rtable_eval command, so you'll likely need to just accept that it's the "magic command" that does what you want in this case.)

What you described is indeed an efficient (although somewhat mysterious) way to fill a matrix. It doesn't matter whether the entries are floats or any other type. The key step is to use the very mysterious command rtable_eval on the row vector; it changes the symbolic variables (ABC, etc.) in the row vector to their assigned values. Like this:

restart:
OutVec:= <A, B, C>^%T: #row vector
OutMat:= Matrix((9, numelems(OutVec)), datatype= anything):
#The datatype could be hfloat or anything else or omitted entirely.

MyFuncs:= proc(k)
    :-A:= (k-1)^2;
    :-B:= k^2;
    :-C:= (k+1)^2;
    rtable_eval(OutVec)
end proc
:
for k to upperbound(OutMat)[1] do
    OutMat[k]:= MyFuncs(k)
od
:
OutMat;

Whether you send this matrix to Excel afterwards is irrelevant; that'd be handled exactly like sending any matrix to Excel, e.g., as shown by @dharr .

I can't tell you how to do it with context-menu-based commands such as you appear to be using, but these text-based commands do it:

convert~(<20., 30., 40.>*Unit(MPa), units, psi);
convert~(<150., 300., 600.>*Unit(psi), units, MPa);

Note the ~ after convert, which causes the command to be applied elementwise to the vector. It works exactly the same for a matrix, array, list, set, or table.

What you describe should be fairly easy because Maple (since Maple 2018) has an on-board Python interpreter and a small package of commands to support it. See help page ?Python.

It's easier to write a procedure for this that works for an arbitrary number of arguments than it is to write one specific to 4 arguments. In the procedure below, you'll need to fill in the ...'s.

biggest4:= proc(S::seq(realcons)) #i.e., the arguments will be a SEQuence of REAL CONStants
local 
    M:= S[1], #Initialize max to 1st argument (arbitrarily).
    x #any of the arguments
;
    #Compare every argument to the max computed so far and adjust it if needed:
    for x in S do
        #The "is" command is sometimes needed to compare complicated symbolic
        #expressions that represent real numbers:
        if is(x > ...) then ...:= ... fi 
    od;
    M #procedure's return value
end proc
:
biggest4(-1/3, 0, 7/3, -2);

If you omit the is, this'll still work for these example numbers.

I'm sure that you know the standard techniques, so I wonder why they're working for me but not for you:

S:= select(type, [solve](diff(F,z), z), realcons);
allvalues(S[min[index](eval~(F, z=~ S))]);

 

@mehdibgh It should come as no surprise that fff has some negative values. So, sqrt(fff) has some imaginary values. To check, extract the min and max values from the data matrix of a plot of fff (not sqrt(fff)):

(min, max)(op([1,3], plot3d(fff, zeta__1= -1..1, eta__1= -1..1)));
              -1.68517697876451*10^(-7), 0.000874224224310557

So the negative values have relatively small magnitude, but they are there nonetheless. If fff has been constructed to be positive valued, then these negatives are from rounding errors in the huge number of floating-point calculations. In this case, just ignore the imaginary parts.

I'm amazed that anyone finds these imaginary parts surprising!

1) Plotting them all: This can be done by using plots:-display on a matrix of individual plots.

2) Finding equivalence classes (under graph isomorphism or any other property): This can be done with ListTools:-Categorize; or, if you know a function that gives an equivalence class representative, it can be done more efficiently with ListTools:-Classify.

# This likely only works in 1D-input!
#
DrawGraphs:= (L::{list,set}(Graph))->
local n:= nops(L), c:= isqrt(n);
    (plots:-display@Matrix)(
        (ceil(n/c), c), 
        (i,j)-> local k:= (i-1)*c+j; 
            if k<=n then GraphTheory:-DrawGraph(L[k], 'title'= k, _rest)
            else plot('axes'= 'none')
            fi
    ):   
n:= 50:
LG:= ['GraphTheory:-RandomGraphs:-RandomGraph(6,7)' $ n]:
ListTools:-Categorize((i,j)-> GraphTheory:-IsIsomorphic(LG[i],LG[j]), [$1..n]);
# Indices in each sublist represent isomorphic graphs.
[1, 11, 14, 15, 18, 19, 23, 24, 36, 38], [2, 41, 47, 50], [3, 5], 
  [4, 13, 44, 46], [6], [7, 12, 25, 33, 39, 49], [8], [9, 27], 
  [10, 29], [16], [17, 40], [20, 31, 34], [21, 42], 
  [22, 28, 30, 32, 48], [26], [35], [37], [43], [45]

DrawGraphs(LG);

 

First 46 47 48 49 50 51 52 Last Page 48 of 395