Carl Love

Carl Love

28055 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@danielpf In the way that it's used that's akin to how sum is used, i.e., with an index variable, add is much older than Maple 2015! I've used Maple extensively since Maple V r4 (circa late 1990s), and I don't recall any version that I've used not having add. What changed in Maple 2015 was possibly an update to add that allows an unindexed form of the command to be used on data containers, for example, add([3,5,7]).

@Rohith Sorry, I just now see that you changed my filter, and that you're now wondering why your change didn't have the desired effect. Specifically, you added `&/`(1, name) to the allowed operands. My Reply immediately above was written  under the assumption that you were using exactly the same filter as I had written. So, now your question makes much more sense to me, and I no longer think that your desired output is an unrealistic expectation!

So, I'd like to discuss at least four things about this:

  1. State your desired rules as precisely as possible.
  2. The new rule that I infer from your attempted change.
  3. Why your attempt didn't work.
  4. How to make it work, assuming that what I inferred in (2) is correct.

1. The Rules: This is pretty much what I said in my previous Reply. If you find it difficult to express your desired rules in English, I will be able to infer them from examples that you provide of complicated expressions matched with the desired extractions. The overall rule as I see it so far is that you want to extract all subexpressions consisting of an operator acting on exactly two atomic operands. There is some slight vagueness in that rule about the exact definitions of operator and atomic, and some even slighter vagueness about the definition of operand. That vagueness is what we seek to make more precise.

2. What I infer: I infer that you want 1/X to be considered atomic when itself is atomic. Is that right? 

3. Why it didn't work: What we deal with here are called structured types, and they form an entire sub-language of Maple. The meta-operators of that language are detailed on the extremely dense help page ?type,structure. I've read that page surely more than a hundred times in the 18 or so years that I've used Maple. The keywords of that language are mostly described on individual help pages ?type,keyword. And it's trivial and common for one to add one's own keywords and meta-operators. This is best done with the package TypeTools.

The meta-operators `&*` and `&+` are predefined, but there is no predefined equivalent for any other operator; specifically, there is no `&/`. Thus your attempt to use `&/` makes it just an undefined function symbol (which is nonetheless allowed by the language). But the function that we're interested in is `%/`, not `&/`.[1]

4. How to make it work: This is a relatively small change to the filter:

value(
   indets(
      InertForm:-Parse("1/v[0]*V1+1"), #string!
      #selects operators with exactly two operands, both of which are names,
      #negated names, reciprocals, integers, or floats:
      And(
         specfunc(
            {name, numeric, (-1) &* name, 1 %/ name}, #atomic operands
            {`%+`, `%*`, `%/`, `%^`} #desired operators
         ), 
         Not(1 %/ name), #subtract reciprocals
         2 &under nops #exactly 2 operands
      ) 
   )                                            
);

If the above is rejected by your system with a syntax error (which may happen due to an older Maple), replace 1 %/ name by `%/`(1, name) both places that it occurs.

This is getting complicated enough that we should now expand the type language with our own keywords to handle it. This will allow recursion. This will be the subject of my next Reply.

[1]Although it's tangential to this discussion, you're probably wondering at this point What's the difference between & and %? And what do the quotes `` mean? And how's that different from the other quotes " " and ' '?

Answer: Prepending to an operator or to an ordinary function name or to even to a plain alphanumeric symbol makes it inert. Applying value to an expression removes one level of inertness from all of its inert subexpressions. Multiple %s can be used, as long as it's done inside `` (aka back quotes, left quotes).

An effect akin to inertness (known as delayed evaluation or unevaluation) is achieved by enclsoing an expression in single quotes ' ', as in x:= 'x'. Whereas the inertness achieved with is stable---an expression doesn't become active until you explicitly remove the inertness---the delayed evaluation achieved with ' ' is ephemeral and often quite frustrating to work with because there are many things that can cause expressions to spontaneously evaluate.

Prepending to an operator or plain alphanumeric symbol allows it to be used as an infix operator, that is, it can be placed between its operands. Unlike the situation with %, there is no semantic connection whatsoever between an &-operator and its underlying symbol. Thus, this is the mechanism by which new infix operators can be defined.

Enclosing any string of characters whatsoever (no matter how complicated, reserved, lenghty, unprintable, or empty) between the back quotes ` ` turns it into a symbol. The kernel's parser then ignores its internal contents (although the GUI does not). This allows you to use it in a variety of contexts where its internal characters would otherwise confuse the parser. For example, if an &-operator is used other than as an infix operator, then it must be enclosed by ` `.  

Double quotes " " are very similar. They are used to form string literals. The difference between symbols and string literals is that symbols are used for a variety of purposes (e.g., they can be assigned values and be variables), but string literals are just simply string literals, as in most other computer languages.

All three type of quotes are always used in pairs in the Maple (1-D) Input. Prime symbols might be used for differentiation in the 2-D Input. I'm not sure because I try to avoid that Input form as much as possible.

 

@Rohith Like I said, you need to provide a large variety of more-complicated examples matched with the output you desire. If you don't, we're just going to go back and forth like this a hundred or so times, each time making a small adjustment to the code.

What part of the following rules don't you like? I may be able to change the rules:

  1. is an atomic operand.
  2. v[0] is an atomic operand.
  3. / is an operator.

Therefore, the only subexpression consisting of an operator acting on exactly two atomic operands is 1/v[0]. My code has precisely fulfilled the rules that you've put forth.

If you changed the input to V1/v[0] + 1, then you'd get the output that you expect. But I thought that part of the point of your project was to analyze the raw-form input, before it's simplfied (either manually or by Maple).

@taro VV has followed that help page advice 100% correctly. The problem being discussed here has nothing to do with the use of quotes.

@Kitonum The difference that this makes in the  layout of the problem is interesting. It can be simplified to

Grading:-Quiz("What is the sum?", (R,A)-> value(A)=R, ()-> `%+`((rand(1..20)$2)()), inertform);

@taro Compare the  output of these two:

eval(Diff(sin(x), x), x= 0);
subs(x= 0, Diff(sin(x), x)):

The eval knows that the x is a bound variable inside Diff, and subs does not.
 

@taro Although your subs command produces the correct result in this case, it's a bad choice for three reasons.

1. subs doesn't "know" any math, it can only blindly make substitutions, some of which may not be mathematically valid. That's why eval(e, x= a) is the preferred alternative to subs(x= a, e) in situations where something mathematical happens to e immediately afterwards, (which is most situations).

2. subs doesn't evaluate its result. For example, try subs(x= 0, sin(x)).

3. If x= a and y= b are independent substitions into e (in particular, the order that they're done doesn't matter), then subs([x= a, y= b], e) is far more efficient than subs(x= a, y= b, e).

 

Certainly the problem as stated cannot produce anything like that graph.

The graph looks possibly like the solution of a pair of nonlinear differential equations x'(t) = f(x,y,t), y'(t) = g(x,y,t). Could you be missing something like that?

Oh, and I agree with Mariusz. It's impolite to not give Thumbs Up or Best Answer to good/best Answers.

@acer My guess is that in order to get close to Matlab times for this, you'll need to implement a QR factorization that can be updated based on the deletion or addition of single columns from the original matrix. There are about 3 pages on this in Matrix Computations by Golub and Van Loan (let me know if you don't have access to a copy). In this particular algorithm, columns are always deleted on the left and added on the right (so the matrix's columns behave as if queued). Perhaps it is possible to exploit that special positioning of the deletions and insertions to simplify the QR updating (and thus get one-up on Matlab). I believe that QR is used in this algorithm simply because it is the factorization of dense unstructured matrices that is most amenable to being updated. 

In addition to that, you'll need to correct the OP's constant creation and destruction of rtables. If you've read the code, this is no doubt obvious to you, and I simply mention it for the benefit of other readers, especially the OP.

@kfli The embedded assignment is semantically equivalent to the non-embedded assignment, so I guess that my reasons are aesthetic, but also with a practical component. About 30 years ago was a great era of development of "software metrics": ways of measuring how long it takes (or how costly it is) to write and maintain code. (I am recalling this all from distant memory; I'll need to check, if possible, some details.) One striking thing that I read was that the overall coding time was more closely correlated with the number of lines of code than with the language, the complexity of the code, or the number of characters of code.

Regardless of whether that's actually true for most programmers, it's certainly true for me. So, I maintain a consistent and rigorous indenting style, I use a reasonable but not excessive amount of white space (my white space amount (minus the indents and right sides) is about equivalent to standard English text), and I strive to reduce the number of lines as much as possible. I put lengthy comments at the top of a procedure. I strive to get procedures to fit onto one screen. I can hold the entire procedure in my mind at once if it can fit on one screen.

 

@acer 

The algorithm under discussion is a method of numerically solving a system of nonlinear algebraic equations of the form F(X) = X, where is a vector of unknowns. (Please excuse me if I'm stating something that you already know.) I don't know yet whether it's restricted to real numbers, continuous functions, Lipschitz continuous functions, etc. If one needs to solve the more-usual system G(X) = 0, I'm sure that you can see how to modify so that it fits the format of the present algorithm.

Since it performs essentially the same job as fsolve or DirectSearch:-SolveEquations, those might be good things to compare it to.

@kfli If you want to solve df.gamma = fval by QR decomposition, you can do something like

gamma:= LinearAlgebra:-LeastSquares([((Q,R):= LinearAlgebra:-QRDecomposition(df))], fval);

with perhaps some adjustments if you're willing to store and together in NAG format. Since the above will work even if df has only one column, I don't think that you should have special code for that case, at least not at this point in the development. That alone eliminates a great many lines of code.

@Ida2018 You are using the Natural units enviroment. If, instead, you use the Simple environment, then variables can "have" units, so to speak, and your original solve command should work as is, and the result will be expressed with units attached.

@Ida2018 I am putting my next Reply under my Answer, where it belongs.

@kfli 

MTM[ldivide](R, df) is equivalent to df /~ R (for scalar R and Vector df). All of Maple's elementwise operators (those that end with ~) have the same precedence, associativity, and commutativity as the corresponding operator without the ~. So df /~ R means "divide every element of df by R" (for scalar R and Vector df), which is clearly what you want.

So, the three lines can be replaced by

R:= norm(df, 2);
Q:= df /~ R;  #Normalize df.
gamma:= Q^+ . fval /~ R; #Note Maple's transpose operator.

In Maple 2018, the three lines can be (and IMO should be) replaced by the single line

gamma:= (Q:= df /~ (R:= norm(df, 2)))^+ . fval /~ R;

Please tell me whether you're using Maple 2018 so that I don't waste more time distinguishing it.

What you have labelled "Alt 1" and "Alt 3" unquestionably give the same results (modulo possibly a little round-off error, only with floating-point computation). Thus, we need to discuss whatever technique you're using to decide whether things are equal or unequal because you're doing it wrong.

 

 

 

First 307 308 309 310 311 312 313 Last Page 309 of 709