Joe Riel

9660 Reputation

23 Badges

20 years, 6 days

MaplePrimes Activity


These are answers submitted by Joe Riel

You can use ?FileTools[ReadDirectory].  For example, the following code creates a list of all files in the directory /tmp with extension .mpl and then reads them, as Maple scripts:

files := FileTools:-ReadDirectory("/tmp", 'returnonly' = "*.mpl"):
for file in files do read file; end do;

The notes in the pdf are confusing.  I don't see how t is related to m (the assignment m := t+1 makes little sense), and what defines the recursion when t (or is it m?) is less than 6?  Is A defined?  As a complete guess, I'd try something like

B := proc(M)
local m;
    if M < 6 then
        return 'B'(M)
    else
        m := iquo(M,2);
        if M :: even then
            return 1/(6 + A(m) - B(2*m-4) - B(2*m-1)*(4-B(2*m-3)));
        else
            return B(2*m)*(4-B(2*m-1));
        end if;
    end if;
end proc:

Gack, I just realized my implementation of bogosort was far too efficient.  The actual algorithm is supposed to shuffle the list until it is sorted, thus, O(n!). Fortunately, implementing the actual algorithm is much easier:

bogosort := proc(L :: list(numeric))
local l;
    l := L;
    while not ListTools:-Sorted(l) do
        l := combinat:-randperm(l);
    end do;
    return l;
end proc:
> time(bogosort(combinat:-randperm(5)));
                                     0.036

> time(bogosort(combinat:-randperm(6)));
                                     0.100

> time(bogosort(combinat:-randperm(7)));
                                     2.876

What is the purpose of that exercise?  The point of bogosort is to be inefficient.  As such, the following violates that principle by using an Array as the internal data structure; a far more inefficient method would subsitute into a list (thus limiting is "use" to 100 element lists, which probably isn't unreasonable).

bogosort := proc(L :: list(numeric))
local A,i,j,n,pick,sorted;
    A := Array(L);
    n := nops(L);
    if n<2 then return L end if;
    pick := rand(1..n);
    sorted := false;
    do
        # check whether Array is sorted
        sorted := true;
        for i to n-1 do
            if A[i] > A[i+1] then
                sorted := false;
                break
            end if;
        end do;
        if sorted then
            return [seq(A[i], i=1..n)];
        end if;

        # randomly pick two elements and sort them
        i := pick();
        j := pick();
        if i < j then
            if A[i] > A[j] then
                (A[i],A[j]) := (A[j],A[i]);
            end if;
        elif j < i then
            if A[j] > A[i] then
                (A[i],A[j]) := (A[j],A[i]);
            end if;
        end if;
    end do;
end proc:


bogosort(combinat:-randperm(100));

x^n with n a negative integer. 

Here's an improvement on the method I previously described.  To avoid touching most of the image a mask is created. 

with(ImageTools):

img1 := Read("watermark.jpg");
img2 := RGBtoGray(img1);
img3 := Threshold(img2,0.9);#View(img3);

# Create a mask.  First use a "bandpass" filter to remove all
# intensities not between 0.7 and 0.85.

bandpass := proc(x) if x < 0.7 or x > 0.85 then 0 else 1 end if; end proc:
mask := map[evalhf](eval(bandpass), img2);

# Now use convolutions followed by threshold operations to remove
# the fine lines.
kernel := Matrix(7,1,fill=1): mask := Threshold(Convolution(mask,kernel,weight=1), 0.5);
kernel := Matrix(1,7,fill=1): mask := Threshold(Convolution(mask,kernel,weight=1), 0.5);
kernel := Matrix(20, fill=1): mask := Threshold(Convolution(mask,kernel,weight=1),0.01);

# Apply the filter operation previously described.
filter := proc(x) if x < 0.7 then x else 1 end if; end proc:
img5 := map[evalhf](eval(filter), img2);

# Now use the mask, and its complement, to combine the filtered image
# with the original image.  Only the region in the mask is filtered.

img6 := Mask(img5, mask);
img7 := Mask(img2, Complement(mask));
img8 := evalhf(img6+img7);

# View and save the result
View(img8);

Write("nowatermark.jpg", img8);

Is the textfile a Maple script?  The ?read command works for that.  Maybe the problem you are having is entering the correct path.  Be aware that backslashes in Maple strings are used to escape particular characters (so "\t" is the tab character).  To enter an actual backslash character you have to escape it, that is, double it: "\\".

Here is a simple method that removes the watermark without too much lossage. This could be improved with masks, but requires more work.

First, let's try the really easy way, which uses the ?ImageTools[Threshold] procedure

with(ImageTools):
img1 := Read("watermark.jpg"):
img2 := RGBtoGray(img1): # convert to grayscale
img3 := Threshold(img2): # use Threshold function to remove watermark
View(img3);

That removes the watermark, but is a bit grainy.  Rather than using a pure threshold function, which moves the bits to either 0 or 1, lets first figure out where the intensity of the watermark lies by plotting its histogram.

watermark := GetSubImage(img1,275,125,30,30):  # zoom in on portion with watermark
Preview(watermark);
PlotHistogram(watermark);

The plot shows a spike between about 0.7 and 0.8.  The following filter leaves intensites that are below 0.7 alone, but moves those above that threshold to 1 (white).

filter := proc(x) if x < 0.7 then x else 1 end if; end proc:
img5 := map[evalhf](eval(filter), img2); # apply filter to grayscale image
View(img5);  # better than img3, lets save it
Write("nowatermark.jpg", img5);

Followup: Christopher222's use of the ?ImageTools[Clip] procedure is a simpler way to apply the filter I manually created above.

To better see what is happening, do

plot([g,x->x], 0..1);

The intersection is a fixed point for g, that is, g(x0) = x0, with x0 = 0.9047882178730188...

You can solve for x0

fsolve(g(x) = x);
                                   0.9047882178730188

The reason that your loop is in a two-cycle is due to numerical approximation in the evaluation of g.  Try changing the setting of Digits and noting how the loop values change.

You also might want to run your corrected procedure (after applying Axel's suggestion) through ?mint:

Procedure gen( x0, a, b, M, n ) on lines 1 to 30
  These variables were used as the same loop variable for nested loops:  i
Global names used in this file:  gen
 

It should be clear what the issue is.  Whether it is a problem depends on what you are intending (I didn't examine the algorithm). To more clearly see this, I indented it for you:

gen:=proc(x0,a,b,M,n)
local i,x,r,d,j,f;
    r:= Vector(n);
    d:= Vector(n);
    f:= Vector(n);
    x:= x0;
    for i to n do
        x:=irem(a+x*b,M);
        r[i]:=2*evalf(x/M);
        f[i]:=evalf(x/M);
        if r[i]>1 then
            d[i]:=sqrt(2*evalf(Pi))*exp(-2*(r[i]-1))*2*exp(-(r[i]-2)^2/2);
        else
            d[i]:=2*sqrt(2/evalf(Pi))*exp(-r[i]^2/2);
        end if;
        for i to n do
            if d[i]<2/3 then
                for j to infinity
                while d[i]<=exp(-f[j] ^2/2) do
                    d[i]:=f[j]
                end do;
            else for j to infinity
                 while d[i]<=exp(-(exp(-2*(f[j]-1))*2-2)^2/2) do
                     d[i]:=f[j]
                 end do;
            end if;
        end do;
        return (d);
    end do;
end proc:

Before considering the recursive method, let's consider a weakness in the current procedure.  Try it with

(**) bisection(cos, 0, 3, 0.001);
Error, (in bisection) unable to evaluate sign

To find the cause of that error you'll need to do some debugging. For that, let's invoke Maple's debugger.  Because I'm using the command-line interface, the interactions will be slightly different than what you will see using the debugger interface in the Standard worksheet, however, you should be able to resolve that.

A convenient way to invoke the debugger is to use the ?stoperror function. 

(**) stoperror(""):           
(**) bisection(cos, 0, 3, 0.001);
Error, unable to evaluate sign
bisection:
   6     if sign(f(c)) = sign(f(a)) then
           ...
         else
           ...
         end if

The error message that the debugger is displaying is the error that will occur if the next statement is executed. At this point we can see what is being passed to the sign functions:

DBG> f(c)
cos(3/2)

The problem is that Maple is being asked to compute sign(cos(3/2)).  The sign function will not numerically evaluate the cosine, so the result is unknown.  To avoid that, you can call the ?evalf procedure to evaluate the cos to a floating point. However, rather than inserting evalf functions here, you could immediately convert the input arguments to floats, then the call to the cosine will be automatically evaluated as a float.  Here is the updated procedure

bisection2 := proc(f, A::realcons, B::realcons, delta::positive)
local a,b,c;
    a := evalf(A); # convert A and B to floats
    b := evalf(B);
    while abs(b-a)>delta do
        c := (a+b)/2:
        if sign(f(c))=sign(f(a)) then
            a := c;
        else
            b := c;
        end if;
    end do;
    (a+b)/2;  # return the value, don't just print it.
end proc:

Alas, what you ask for is currently not available in MapleSim.  You could approximate a time-delay element with one of the transmission lines in the Electrical menu.

Are these variables that you use at top-level in a worksheet, or are they local to procedures or modules?  The first doesn't make much sense because there is no method for declaring top-level variables. I rarely use document mode to write procedures, preferring the comfort of an external editor. There I may include an inline comment, say

someproc := proc()
local L  # list of random values
    , k  # counter
    ;
  ...
end proc:

I don't know of any tools for tracking these when written in the usual Maple format, however, I've occasionally used noweb, a literate-programming tool that will produce an index of procedures and variables (depending on what you mark up).  For a Maple example, see solving_a_sudoku_puzzle_with_maple.

An interesting possibility for top-level variables might be to use ?setattribute to tag them with documentation (that is, essentially, what Maple uses for the option string of procedures).

Your original premise is flawed.  That is, the additional assumption that cos(x*y) <> 0 implies sin(x*y) <> 1.  So the only solution to the equation is x=0.

Take a look at ?StringTools[FormatTime] and ?StringTools[ParseTime].

First 75 76 77 78 79 80 81 Last Page 77 of 114