pagan

5147 Reputation

23 Badges

17 years, 122 days

 

 

"A map that tried to pin down a sheep trail was just credible,

 but it was an optimistic map that tried to fix a the path made by the wind,

 or a path made across the grass by the shadow of flying birds."

                                                                 - _A Walk through H_, Peter Greenaway

 

MaplePrimes Activity


These are replies submitted by pagan

You wrote that you wanted to take clusters ("max area") of spikes and get the "general max" for them.

So, how far apart do the outermost spikes from two distinct clusters have to be for them to get correctly identified as being from two distinct groups? Let's suppose the answer to that is distance X.

Now, what happens if the end spikes from two distinct clusters fall at less than X distance apart? The algorithm would (mis)identify all spikes from both clusters as being in just one single group. And hence it would identify just a single "general max" despite the fact that there were really two cars (clusters of spikes) present.

If you take X too large, then distinct cars coming close together can get misidenfied as being a single car.

Now what happens if you take X as very small. If X is too small, then spikes from a single cluster may fall at more than X distance apart. In that case, such spikes more than X apart would (by defn of X) get identified as being from separate clusters. And so a single car's spikes could get misidentified as being due to several apparent cars.

So X should be neither too small or too large, if the "general max" of the clusters is to be correctly identified with the right number of cars. So my question is, what size should X be (not just for your cited .wav file, but for any other data you intend to analyse).

Now, distance apart of spikes is not the only possible criterion that can resolve this. Bounding some higher derivative(s) of the smoothing curve might also suffice (but be trickier to specify). Or, in the car example you might be able to state a range for acceptable width of clusters on the basis of the pitch and the known car speeds.

You might be able to use CurveFitting:-ArrayInterpolation for this task. You shouldn't have to convert to lists.

The ambiguity can be the same, for passing cars. How do you want to distinguish between the spikes of two different cars if they pass by the microphone close together in time? Even without overlap of their "max areas" they might still occur close enough for your intended result to be unclearly specified. (It may not happen in your cited .wav file, but it looks like a general issue to me, given only what you've written so far.)

The ambiguity can be the same, for passing cars. How do you want to distinguish between the spikes of two different cars if they pass by the microphone close together in time? Even without overlap of their "max areas" they might still occur close enough for your intended result to be unclearly specified. (It may not happen in your cited .wav file, but it looks like a general issue to me, given only what you've written so far.)

map is a top-level (not part of any package) routine that operates on a wide variety of structures. The LinearAlgebra package is not required for using map. Map is an export of the LinearAlgebra package, and acts in-place upon Matrices and Vectors.

map is a top-level (not part of any package) routine that operates on a wide variety of structures. The LinearAlgebra package is not required for using map. Map is an export of the LinearAlgebra package, and acts in-place upon Matrices and Vectors.

The trick is not merely to move the with() outside of the proc body. The trick is to not utilize with() at all, but to utilize uses instead as Doug mentioned.

Also, you cannot utilize `=` as a simple evalb kind of equality test between mutable Array/Vector/Matrix objects.

And it is not necessary to convert the q and w objects to be Arrays.

In the procedure below, Maple will utilize LinearAlgebra:-Equal and ArrayTools:-AddAlongDimension.

> RownColumn:=proc(n::Matrix)
> local m, en, q, w, Arr:
> uses ArrayTools, LinearAlgebra;
>   m:=n:
>   en:=min(op(1,m)):
>   Arr:=Vector[column](1..en,1):
>   q:=AddAlongDimension(m,1):
>   w:=AddAlongDimension(m,2):
>   if Equal(Transpose(q),Arr) and Equal(w,Arr) then
>     return yes;
>   else
>     return no;
>   fi:
> end proc:
>
> m:=Matrix([[0,0,1,0],[1,0,0,0],[0,0,0,1],[0,1,0,0]]):
> RownColumn(m);
                                      yes

The trick is not merely to move the with() outside of the proc body. The trick is to not utilize with() at all, but to utilize uses instead as Doug mentioned.

Also, you cannot utilize `=` as a simple evalb kind of equality test between mutable Array/Vector/Matrix objects.

And it is not necessary to convert the q and w objects to be Arrays.

In the procedure below, Maple will utilize LinearAlgebra:-Equal and ArrayTools:-AddAlongDimension.

> RownColumn:=proc(n::Matrix)
> local m, en, q, w, Arr:
> uses ArrayTools, LinearAlgebra;
>   m:=n:
>   en:=min(op(1,m)):
>   Arr:=Vector[column](1..en,1):
>   q:=AddAlongDimension(m,1):
>   w:=AddAlongDimension(m,2):
>   if Equal(Transpose(q),Arr) and Equal(w,Arr) then
>     return yes;
>   else
>     return no;
>   fi:
> end proc:
>
> m:=Matrix([[0,0,1,0],[1,0,0,0],[0,0,0,1],[0,1,0,0]]):
> RownColumn(m);
                                      yes
> M:=Matrix([[1,2,3],[2,3,4],[3,7,5]]):

> add(M[i,3-i+1],i=1..3),add(M[i,3-i],i=1..2),add(M[i,3-i-1],i=1..1);
                                   9, 4, 1

> seq(add(M[i,3-i+3-j-1],i=1..3-j+1),j=1..3);
                                   9, 4, 1

> Mflip:=ArrayTools:-FlipDimension(M,2):

> seq(convert(MTM:-diag(Mflip,i),`+`), i=0..2);
                                   9, 4, 1

That last way, using diag and FlipDimension and convert, is not very efficient in that it produces lots of unnecessary intermediate objects.

> M:=Matrix([[1,2,3],[2,3,4],[3,7,5]]):

> add(M[i,3-i+1],i=1..3),add(M[i,3-i],i=1..2),add(M[i,3-i-1],i=1..1);
                                   9, 4, 1

> seq(add(M[i,3-i+3-j-1],i=1..3-j+1),j=1..3);
                                   9, 4, 1

> Mflip:=ArrayTools:-FlipDimension(M,2):

> seq(convert(MTM:-diag(Mflip,i),`+`), i=0..2);
                                   9, 4, 1

That last way, using diag and FlipDimension and convert, is not very efficient in that it produces lots of unnecessary intermediate objects.

> M:=Matrix([[1,2,3],[2,3,4],[3,7,5]]);
                                   [1    2    3]
                                   [           ]
                              M := [2    3    4]
                                   [           ]
                                   [3    7    5]
 
> add(M[i,1],i=1..min(op(1,M))); # adding first column
                                       6
 
> add(M[3,i],i=1..min(op(1,M))); # adding third row
                                      15
 
> ArrayTools:-AddAlongDimension(M,1); # adding along rows
                                  [6, 12, 12]
 
> ArrayTools:-AddAlongDimension(M,2); # adding along columns
                                     [ 6]
                                     [  ]
                                     [ 9]
                                     [  ]
                                     [15]
 
> add(M[i,i],i=1..min(op(1,M))); # main diagonal
                                       9
Converting to another data structure (eg. list) is usually not a (relatively) efficient way, since it creates garbage objects which must be memory-managed.
> M:=Matrix([[1,2,3],[2,3,4],[3,7,5]]);
                                   [1    2    3]
                                   [           ]
                              M := [2    3    4]
                                   [           ]
                                   [3    7    5]
 
> add(M[i,1],i=1..min(op(1,M))); # adding first column
                                       6
 
> add(M[3,i],i=1..min(op(1,M))); # adding third row
                                      15
 
> ArrayTools:-AddAlongDimension(M,1); # adding along rows
                                  [6, 12, 12]
 
> ArrayTools:-AddAlongDimension(M,2); # adding along columns
                                     [ 6]
                                     [  ]
                                     [ 9]
                                     [  ]
                                     [15]
 
> add(M[i,i],i=1..min(op(1,M))); # main diagonal
                                       9
Converting to another data structure (eg. list) is usually not a (relatively) efficient way, since it creates garbage objects which must be memory-managed.

This is explained on the do help page, in the bullet point labeled "Note about Nested Loops" within the Description section.

As stated, that is not accurate.

We may have reason to suspect that the OP is considering exact rational coefficients for the polynomials due to some earlier posts. But evalb may not be adequate for testing polynomials with coefficients in the float domain.

> A := [a^2+b+1,a-1.00]:
> B := [a^2+b+1,a-1.0]:

> evalb(A=B);
                                     false
 
> verify(A,B,list('polynom'(float(10),{a,b})));
                                     true

With floats in the picture, it's up to the individual to decide what is accepted as "equal".

> evalb(1.0=1.00);
                                     true
 
> evalb(a-1.0=a-1.00);
                                     false

As stated, that is not accurate.

We may have reason to suspect that the OP is considering exact rational coefficients for the polynomials due to some earlier posts. But evalb may not be adequate for testing polynomials with coefficients in the float domain.

> A := [a^2+b+1,a-1.00]:
> B := [a^2+b+1,a-1.0]:

> evalb(A=B);
                                     false
 
> verify(A,B,list('polynom'(float(10),{a,b})));
                                     true

With floats in the picture, it's up to the individual to decide what is accepted as "equal".

> evalb(1.0=1.00);
                                     true
 
> evalb(a-1.0=a-1.00);
                                     false

It isn't clear, from the single example you gave, whether all  the given variables must be present. For example, would a+b  be  a polynomial that you would want returned  in your initial example L?

Also, your criteria could be that only names {a,b,c} must be present, or that all of {a,b,c} must be present. Your wording and sole example is ambiguous in this respect. And Roman's and Robert's code will behave differently in these regards (and neither would pick up a+b although we don't know yet whether you want that one).

> L:=[a+b+c,x+ab+d^3,y+c,a+b,a+b+c*d];
                                      3
           L := [a + b + c, x + ab + d , y + c, a + b, a + b + c d]
 
> select(f->indets(f)={a,b,c}, L);
                                  [a + b + c]
 
> select(t -> has(t,a) and has(t,b) and has(t,c), L);
                           [a + b + c, a + b + c d]
Hence it was not clear whether you might have wanted either of these.
> select(f->(indets(f) minus {a,b,c})={}, L);
                              [a + b + c, a + b]
 
> select(f->({a,b,c} minus indets(f))={}, L);
                           [a + b + c, a + b + c d]
First 50 51 52 53 54 55 56 Last Page 52 of 81