Carl Love

Carl Love

28055 Reputation

25 Badges

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

MaplePrimes Activity


These are replies submitted by Carl Love

@grad_stu Yes, it can be done. It's a bit awkward though. The code that does the measuring must be part of the code passed to Run. And you make the return values be the timings and whatever else you'd ordinarily return. I'll post an example in a few hours, if you haven't figured it out by then.

@Ronan As explained in my previous Reply, the earlier speedup was largely due to me inadvertently exchanging the updates of h and jm, which incorrectly reduces substantially the number of inner loop iterations.

I think that you should remove Best Answer from my Answer and award it to @dharr .

@dharr You're right; it was a careless mistake on my part. Making that change substantially increases the number of inner loop iterations and hence the time, regardless of any updates to Modular. With this change, I think that the compiled code is faster.

Several more of the index variables can be eliminated. This is just to simplify the code; it has minimal effect on the time. These index variable eliminations could also be used in the compiled code.

BooleMobiusTransform:= proc(V::Vector[column](datatype= integer[8]))
uses LAM= LinearAlgebra:-Modular; 
local 
    n:= ilog2(numelems(V)), H:= Scale2(1,n), 
    im:= Scale2(H, -1), istart, b, r,
    R:= LAM:-Create(2, H, 0, integer[8])
;
    LAM:-Copy(2, rtable(1..H, V, subtype= Vector[column]), R);
    to n do 
        for istart by Scale2(im,1) to H do
            LAM:-AddMultiple(
                2,                            #modulus
                R, istart..(b:= im-1+istart), #addend
                R, (r:= istart+im..b+im),     #addend
                R, r                          #where to store sum
            )
        od;
        im:= Scale2(im, -1)
    od; 
    R
end proc
:

 

@Jean-Claude Arbaut The purpose of the syntax ':-foo' is to guard against the possibility that the user has globally made an unrelated assignment to the keyword foo. A better solution is to allow the passing of keywords as strings (e.g., "foo"), and much of the Maple library code written in the last few years does it that way. Strings are necessarily constant; there's no possibility that they've been reassigned.

@Jean-Claude Arbaut 

Neither your procedure nor the one in my Answer needs to extract or modify Edges(G) because the same information about edges is contained in the weight matrix.

Your procedure runs without error on an undirected graph, but the edge weights will be doubled (except for self loops). It won't work as-is on unweighted graphs, but this can be easily fixed by substituting the adjacency matrix for the weight matrix (see code below). 

If you learn only one general thing from my code today, let it be this: A procedure should not rely on a package having been loaded. Instead, start the procedure (or an encompassing module) with a uses declaration. (And never use the with command in a procedure.)

In the procedure below, I've excluded undirected graphs from the input in case you don't want that doubling, and also to show you how you can include a filter in the proc line.

Dir2Undir:= proc(G::And(GRAPHLN, satisfies(GraphTheory:-IsDirected)))
uses GT= GraphTheory;
    GT:-Graph(
        GT:-Vertices(G),
        rtable(
            ':-symmetric',
            (W-> W + W^+ - rtable(':-diagonal', W))(
                GT[
                    if GT:-IsWeighted(G) then WeightMatrix
                    else AdjacencyMatrix
                    fi
                ](G)
            )
        )
    )
end proc
:

 

@tomleslie 

Your procedure doesn't have a consistent way to deal with bidirectional edges in the digraph that have different weight in each direction. I don't know whether you considered this and decided to ignore it or whether the possibility hadn't occurred to you.

My procedure uses the sum of the weights, although it's not clear that this is what the OP wants. 

@AHSAN

It's not clear whether you want to use y as the independent variable of the ODE system or as the specific value of the independent variable at the upper boundary. You can't use it as both, which is how you currently have it. I'll make y the independent variable and use as the boundary. It's also not clear whether you want A to play some role in the final result or whether it's just a temporary intermediate constant of integration. I'll choose the latter, and so A will not be used in my solution at all.

ode:= diff(Phi(y), y$2) = K;  #2nd-order ODE
bc:= Phi(-Y) = 1, Phi(Y) = -r;

Sol:= dsolve({ode, bc}, Phi(y));

That's all there is to it.

@Mariusz Iwaniuk I will only comment at length on the numeric dsolve, which is where my expertise is. I don't think that you understood my Answer. The numeric dsolve has no problem whatsoever solving any (differentiable) branch of your ODE; it simply requires that you specify which branch. Okay, Mathematica's numeric solver does them all at once; so what, big fat deal?! It's trivial to get Maple to do the same thing if that's what you want. Like this:

ODE:= diff(y(x), x)^2 - diff(y(x), x)^4:
Sols:= map(
    ode-> dsolve({ode[], y(1)=1}, numeric), 
    {solve}({ODE}, diff(y(x), x))
):
plots:-display(
    plots:-odeplot~(Sols, x= 0..1, color=~ [blue, green, red])
);

I believe that most users solving practical problems do not want multiple solutions from a numeric ODE solver because the presence of ambiguity highlights a flaw in the way that the system was input and only one of the branches is physically relevant to them. For such users, that error message should be welcomed.

On the other hand, I think that the symbolic solver should give all solutions, and thus your first example (dsolve(..., 'explicit')) shows that there is a bug.

@Ronan Your most recently posted worksheet is in 2D Input, not 1D. I wonder what makes you think that it is 1D? When your cursor is within an code-input block, the entry mode will be shown in the leftmost pull-down menu on the lowest toolbar.

However, I believe (but I'm not sure) that if you change the istep+= h as discussed above, the rest of the code will work in 2D Input.

The syntax to n do is valid, and always has been valid, in all input modes. Indeed, all of the prepositional phrases of the do command are optional (forfrombytoinwhile​​​​​​, and until).

The problem that you were having was due to a more-subtle mistake in my posted code. Instead of saving the results in the vector R, it was putting them in a hidden temporary vector and then discarding them. Sorry about that. The syntax that the Modular package uses is unusual and unforgiving. Here is the corrected code:

BooleMobiusTransform:= proc(V::Vector[column](datatype= integer[8]))
uses LAM= LinearAlgebra:-Modular; 
local 
    n:= ilog2(numelems(V)), im:= Scale2(1, n-1), istep:= im, 
    jm:= 1, h:= Scale2(im, 1), istart, 
    R:= LAM:-Create(2, h, 0, integer[8]);
    LAM:-Copy(2, rtable(1..h, V, subtype= Vector[column]), R);
    to n do 
        istart:= 1;
        to jm do
            LAM:-AddMultiple(
                2,
                R, istart..im-1+istart, 
                R, istart+istep..im-1+istart+istep,
                R, istart+istep..im-1+istart+istep
            );   
            istart+= h
        od;
        (im, istep, jm, h):= Scale2~([im, istep, jm, h], [-1$3, 1])[]
    od; 
    R
end proc
:

The vast majority of the execution time of the erroneous code was spent creating those hidden temporary vectors. The current code operates on the vector "in-place" (as did your original). So this code will do the 2^25 case in 0.2 - 0.3 seconds, which makes it well over 100 times faster than the compiled code.

Instead of copying and pasting the code above, download the worksheet attached below. That way, you'll see what I mean by "1D input". You'll see that the code is upright, reddish brown, and monospaced just like in the box above.

BooleMobius.mw (worksheet download link)

@Ronan My code requires 1D input. Are you using 2D Input? The istep+= h is correct and means the same thing as istep:= istep+1. It required 1D input.. Sorry that I didn't mention that; I forget to because I never use 2D Input.

Note that the code above is several times faster than the compiled alternative, so it's probably worthwhile to switch your input mode.

I don't think that making a copy is strictly required, but it's easier to do it that way in LinearAlgebra:-Modular, which has a very unforgiving syntax

@Rouben Rostamian  Great Answer, Vote Up, and I even learned a few things from it. I think that there's one more thing that you should state, because I don't think that it's immediately obvious: Your process of finding the vectors is only valid because the right sides of the equations are constant. Of course, it's trivial to rearrange any equation so that that is true.

My opinion is that all algebraic equations eq given as input to any Maple program should be preprocessed with (lhs-rhs)(eq). One of the many advantages of doing that is that it eliminates the concern that I raised in the first paragraph. 

@nm It's not necessary to specify a domain more explicitly. If in the Question above one were to replace the word "between" with "of the region bounded by", then it would be phrased as a standard calculus textbook problem. It's then the job of the student to use geometric intuition and/or plotting to locate the bounded region in the xy-plane and to conceptualize it as an integral or sum of integrals, and to use algebra to determine limits of integration and integrands.

In some simple cases, if one uses that geometric intuition to define the region via inequalities, Maple may be able to procede automatically with both the symbolic algebra and symbolic integration to finish the problem entirely. I suspect that this is not one of those simple cases, but I'm curious to try it.

@Joe Riel Thanks for 0@@0; it's better than _@@0. I think that I'll use 1@@0 until something better turns up. The 1 better conveys the idea of "identity function". Another possibility is `@`(), but it's one more character. All of these evaluate to ()-> args.

 

@Joe Riel My code wasn't intended to handle the multi-argument abs case (which the OP stated doesn't occur in their work anyway). I'm sorry that my phrasing gave you the impression that that was my intention. Replacing abs(n,x) with x is mathematically nonsense.

Here is &inside's definition:

TypeTools:-AddType(`&inside`, (e, `in`::type, out::type)-> e::out and hastype(e, `in`)):

The following code allows for the multi-argument abs case by ignoring it; it only processes the 1-argument case:

evalindets(expr, specfunc(ln), evalindets, 'abs'(algebraic), op);

 

@Ioannis 

Usage of error: When you use the word error on MaplePrimes or on any forum devoted to a computer programming language, you need to specify whether you mean error 

  1. in the technical sense that that term is defined by the language (usually witnessed as the issuance of an error message), 
  2. in the sense that the results are incorrect.

Making that distinction is usually sufficient; although each of those cases has numerous subcases, such as syntax errorsruntime errorslogical errors, and bugs.

Usage of take: In three cases (one in the Question and two in the Reply), you've used the word take where you meant make. Since "t" and "m" are not adjacent on a standard keyboard, I assume that this is not a typo and that you truly don't understand the meaning of these words. I can usually interpret the meaning of the writing of non-native-English speakers, and so I usually wouldn't point out something like this; however, in this case I was truly confused by your usage of take in the Question; it was only while reading the Reply that I realized that you meant make. Since these are fundamental and essential English irregular transitive verbs (such that exchanging them produces syntactically correct meaningful sentences) whose meanings are totally unrelated, I suggest that you look them up and learn them well.

First 138 139 140 141 142 143 144 Last Page 140 of 709