acer

32490 Reputation

29 Badges

20 years, 7 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@Scot Gould  list_making_expression[]  acts like  op(list_making_expression) for something that evaluates to a list, and produces the expression sequence of entries.

restart

kernelopts(version)

`Maple 2024.0, X86 64 LINUX, Mar 01 2024, Build ID 1794891`

M := LinearAlgebra:-RandomMatrix(3)

Matrix(%id = 36893628144023405500)

L := `~`[proc (i) options operator, arrow; M[() .. (), i] end proc]([`$`(1 .. 3)])[]

Vector[column](%id = 36893628144023403084), Vector[column](%id = 36893628144023403204), Vector[column](%id = 36893628144023403324)

N := 3

L := `~`[proc (i) options operator, arrow; M[() .. (), i] end proc]([`$`(1 .. N)])[]

Vector[column](%id = 36893628144023394412), Vector[column](%id = 36893628144023394532), Vector[column](%id = 36893628144023394652)

L := `~`[proc (i) options operator, arrow; M[() .. (), i] end proc]([`$`(1 .. N)])

[Vector[column](%id = 36893628144023384300), Vector[column](%id = 36893628144023384420), Vector[column](%id = 36893628144023384540)]

 

notes on list-to-sequence:

 

T := [a, b, c]

[a, b, c]

T[]

a, b, c

op(T)

a, b, c

 

In a comment you wrote of this, but it only produces the first column.
So it's not what you'd want to use & test.

 

`~`[proc (i) options operator, arrow; M[() .. (), i] end proc](`$`(1 .. N))

Vector[column](%id = 36893628144023372492)

`~`[proc (i) options operator, arrow; M[() .. (), i] end proc](1, 2, 3)

Vector[column](%id = 36893628144023368156)

 

It's a shame that this doesn't work in 2D Input.

 

$5

1, 2, 3, 4, 5

"$5"

Error, invalid `$` operator

"$5"


Download SG_notes.mw

comment: In my Maple 2024.0 the following works for me in 2D Input,

  (i->M[.., i])~([$1..5])[]

though the form with [$5] works for me only in 1D input.

Btw, I'm not sure how you tested but if the square brackets are omitted then don't you get just the first column?

I only mentioned these because elementwise was specifically mentioned. I'd rather not introduce the extra overhead of calling even this simple user-defined anonymous operator N times.

@Scot Gould The following is done as an elementwise operation,

   (i->M[..,i])~([$5])[];

And you can remove the trailing [] if you'd accept a list of the column Vectors.

The following doesn't have a super short form (as an application of zip or `?[]` done elementwise) since M and the list of indexing specs are of different lengths.

   map[2](`?[]`,M,[[..,i]$i=1..5])[];

There are other less terse (and mostly less efficient) ways, some of which I might consider slick.

I don't know that you've going to get much shorter than what I showed in my Answer.

[edit] I had decided not to mention elementwise Vector construction over the listlist conversion of the transpose of the Matrix, since it's overly verbose as well as inefficient.

@sija I cannot tell from your code what it is that you are trying to do. I think that you should explain the goal, clearly and explicitly, in words.

@Ronan IIRC the lhs of a keyword call should have uneval quotes at least, and the rhs should be an uneval quoted global name, in order to adequately protect against values assigned to those names.

Sometimes I give both lhs and rhs the :- colon-dash to make them a global name.

It's not necessary to add the uneval quotes if the name is one of the stock protected names. The name symbol is one of those, so I didn't bother, since nobody should be unprotecting and assigning to that global name.

symbol := 3.1;

Error, attempting to assign to `symbol` which is protected.  Try declaring `local symbol`; see ?protect for details.


I was examining what maplemint reported, ealier. (I don't have all the time in the world for this, sorry...) And sometimes I miss things.

But a strong test is one which tests 1) that it works normally, and 2) that it doesn't break if either the keyword name or option value name were assigned. Consider the following attachment, which assigns to align at the top-level, and then runs the examples.

You can also add a $ to the end of a procedure's parameter specification. That will cause an error to get thrown if there are any extra/unexpected arguments passed when it is called. That can help in tracking down mistakes in the option specifications. (You could remove the $ when finished. Your taste.)

2024-03-09_Example_parm_names_changed_accc.mw

You can experiment with what breaks what. You could also test the other names in play. If you plan on using this procedure a great deal, or giving it to others, or using it for a long time, then such sanity checks are one kind of useful "unit test".

Single back-quotes are used to turn language keywords into names. That's a very different meaning of the word "keyword" than we're using here. Examples include `if`, `global`, `union`, etc.

For procedure parameters the word "keyword" refers to one particular class of optional parameter. For those I've used single forward-quotes (a.k.a. uneval quotes). The purpose is to avoid your procedure use breaking if the names had been assigned some values at the higher level. You won't really notice the effect unless you do actually make such assignments and you lacked the quotes -- examples can break.

It's unfortunate that the word "keyword" has these two different meaning (and that each often deals with a different kind of quotes). Ambiguity is a problem.

@Kitonum That works in your Maple 2018, and up to at least Maple 2022.2.

But it does not work in Maple 2024.0 or Maple 2023.2.1.

The OP's attachment was saved by him using Maple 2024.0.

@Ronan You haven't given any explanation as to why a clash (such as `print`) would cause a problem. What problem would it cause, that you don't know how to overcome?

Why precisely do you need to avoid any "clash"? Can you give an example of such a "clash", for which you believe that you could not utilize your procedure successfully?

The worksheet you've shown doesn't make your purported problem clear, IMO. You used Line as the procedure's parameter name, yet then passed it line=... as an argument, so naturally that doesn't do much. What were you trying to illustrate (apart from your using the wrong name when calling it...)?

Why do you think that you cannot/oughtn't use the lowercase name line for your keyword parameter name in the definition of your procedure?

Please be very explicit, because I really don't understand what you're trying to convey. Thanks.

ps. There are lots of Library procedures that use some other Library procedure name as one of its keyword parameters. An example of such a keyword is value, which is also the name of a top-level command. That doesn't prevent such procedures from being used properly.

I forgot to mention, your (mixed Vector/list) elementwise arithmetic can also be done using infix notation, which I think looks tidier here than the prefix form. Eg,

restart;

with(plottools): with(plots,display):

l := ([2,-3,1],<3,7/9,6>):   # 3d line point + vector

P := [7,-8,9]:

pl := lambda*l[2] +~ l[1]; #3d line as vector eqn

Vector(3, {(1) = 3*lambda+2, (2) = (7/9)*lambda-3, (3) = 6*lambda+1})

vnl := pl -~ P; #vector from Point P to 3D line

Vector(3, {(1) = 3*lambda-5, (2) = (7/9)*lambda+5, (3) = 6*lambda-8})

vnl.l[2] assuming `real`; #dot product of vectors= 0 when perpendicular

(3694/81)*lambda-532/9

sol := solve( {  }, [lambda] )[];

[lambda = 2394/1847]

intP := eval(pl,sol):  #intersection point

l2 := P,eval(vnl,sol):  #perpendicular 3D line through P

pl2 := lambda*l2[2] +~ l2[1]; #3D line as vector eqn

Vector(3, {(1) = -(2053/1847)*lambda+7, (2) = (11097/1847)*lambda-8, (3) = -(412/1847)*lambda+9})

Download Perpendicular_3D_lines_acc.mw

@mmcdara The whole top-level local declaration thing seems like a bad idea to me. I would never use it in my own work.

I simply use another name, instead of one with a special meaning to Maple.

Is it deliberate to have sigma__nu in M, etc, while having sigma__v in sigma__Y, etc?

@vv Thanks!

That is consistent with the cited Documentation sentence, which mentions, "...as if it had been entered or read from a file".  If one enters the name (eg. manually types it in at the top-level) then any top-level locally-declared name is what one would then get, naturally.

But by default (ie. with no special top-level local declaration of it) entering a name at the top-level gets the global name. I don't know whether in future I'll always qualify my own personal description of this issue, to cover the special situation of a local declaration. Maybe. If I remember. (I'm not a huge fan of the top-level local declarations, btw.)

ssystem(sprintf("cat %s",cat(kernelopts(':-homedir'),"/file.mpl")));

[0, "a;"]

restart;
local a:
a := 17:
:-a:=18:        
p := proc()
  local a;
  a := 25;
  read cat(kernelopts(':-homedir'),"/file.mpl");
  %;
end proc:
p();

17

Download parse_ex4.mw

@Anthrazit See also the first paragraph of the Description section of the Help page for the parse command,

"The parse command takes a Maple string and parses the string into a Maple expression as if it had been entered or read from a file."

Another example, where I have a file names file.mpl in my home directory, whose contents are just the single line,
   a;

restart;

a := 17:

p := proc()
  local a;
  a := 25;
  read cat(kernelopts(':-homedir'),"/file.mpl");
  %;
end proc:

p();

17

Download parse_ex3.mw

@mmcdara I had written it at first with convert,base .

Then I did some perfomance stress testing and noticed that Explode was slightly faster (for the sizes I considered).

@jasser 

restart;

 

ee := 0.04572;

0.4572e-1

-op(2,frac(ee));

5


note: This does not first strip off trailing zeroes.

ee := 77777.9200;

77777.9200

-op(2,frac(ee));

4

Download fl_op.mw

Note that in your earlier examples the log10 of the repeating part can be used to indicate which is the last decimal position occupied by the non-repeating part. So trailing zeroes needn't get in your way there.

So, for example, if you wanted the number of decimal places (to the right of the dot, including zeroes to its left) taken up by the fractional part of the non-repeating part, then you could compute that as 1 less than the decimal place in which the repeating part started.

with(NumberTheory):

q := RepeatingDecimal(1/12);

_m140005007471616

nrp := NonRepeatingPart(q, output=float)

0.80e-1

rp := RepeatingPart(q, output=float);

0.3e-2

-1 - floor(log10(rp));

2

 

q := RepeatingDecimal(113/112);

_m140005003208448

nrp := NonRepeatingPart(q, output=float)

0.8900e-2

rp := RepeatingPart(q, output=float);

0.285714e-4

-1 - floor(log10(rp));

4

Download rep_dec_2.mw

First 50 51 52 53 54 55 56 Last Page 52 of 594