1. Better Way to Do This

Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(i) then return 0 end if 
	end for 
	return 1 
end function 
new topic     » topic index » view message » categorize

2. Re: Better Way to Do This

euphoric said...

Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(i) then return 0 end if 
	end for 
	return 1 
end function 

Would this be faster ?

function no_atoms( sequence s ) 
integer i = length(s) 
while(sequence(s[i]) and i > 0 ) do 
  i -= 1 
end while 
if i = 0 then return 1 else return 0 end if 
end function 
new topic     » goto parent     » topic index » view message » categorize

3. Re: Better Way to Do This

I'm not sure which is faster, but wouldn't you want to make it a type? i.e. sequence_of_strings or something.

Jeremy

new topic     » goto parent     » topic index » view message » categorize

4. Re: Better Way to Do This

euphoric said...

Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(i) then return 0 end if 
	end for 
	return 1 
end function 

There is a Eu v4 library routine for this. It's in std/types.e

public type sequence_array( object x ) 
    if not sequence(x) then  
        return 0 
    end if 
	 
    for i = 1 to length(x) do 
        if not sequence(x[i]) then  
            return 0 
        end if 
    end for 
    return 1 
end type 

Note that this also allows empty sequences so if you must have at least one element you can use it like this ...

  if length(S) and sequence_array(S) then  
     ... 

By the way, your code above wouldn't work as you don't update the 'i' variable.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Better Way to Do This

DerekParnell said...
euphoric said...

Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(i) then return 0 end if 
	end for 
	return 1 
end function 

There is a Eu v4 library routine for this. It's in std/types.e ... By the way, your code above wouldn't work as you don't update the 'i' variable.

Thanks Derek. I figured there was something already available. I also modified the code in browser before I submitted it, so it wasn't the original... just something I thought would be faster but didn't verify. getlost

It was originally this:

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		i = i and sequence(s[t]) 
	end for 
	return i 
end function 

But I figured that would go through the entire sequence, so if there was an atom at s[1], why waste all that time? Of course, if the atom was at s[$], then no algorithm will get there faster. Right?

new topic     » goto parent     » topic index » view message » categorize

6. Re: Better Way to Do This

bernie said...

Would this be faster ?

function no_atoms( sequence s ) 
integer i = length(s) 
while(sequence(s[i]) and i > 0 ) do 
  i -= 1 
end while 
if i = 0 then return 1 else return 0 end if 
end function 

Yeah, that's faster all right! Here's the program I used to test the speeds. Bernie, your suggested code was waaaaaay faster than any other. It should definitely replace our std/lib sequence_array()!

include std/console.e 
 
atom t 
 
function no_atoms_1( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(s[t]) then return 0 end if 
	end for 
	return 1 
end function 
 
function no_atoms_bernie_1( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	if i=0 then return 1 else return 0 end if 
end function 
 
function no_atoms_bernie_2( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	return not i 
end function 
 
function no_atoms_stdlib( object x ) 
    if not sequence(x) then 
        return 0 
    end if 
 
    for i = 1 to length(x) do 
        if not sequence(x[i]) then 
            return 0 
        end if 
    end for 
    return 1 
end function 
 
sequence a 
a = repeat({},500) 
a &= 1 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_2( a ) 
end for 
?time()-t 
 
for x=1 to 100000 do 
	no_atoms_stdlib( a ) 
end for 
?time()-t 
 
wait_key() 

The no_atoms_bernie_2() was just my testing of the "not" thingie. Didn't help. getlost

I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!

new topic     » goto parent     » topic index » view message » categorize

7. Re: Better Way to Do This

euphoric said...
bernie said...

Would this be faster ?

function no_atoms( sequence s ) 
integer i = length(s) 
while(sequence(s[i]) and i > 0 ) do 
  i -= 1 
end while 
if i = 0 then return 1 else return 0 end if 
end function 

Yeah, that's faster all right! Here's the program I used to test the speeds. Bernie, your suggested code was waaaaaay faster than any other. It should definitely replace our std/lib sequence_array()!

include std/console.e 
 
atom t 
 
function no_atoms_1( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(s[t]) then return 0 end if 
	end for 
	return 1 
end function 
 
function no_atoms_bernie_1( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	if i=0 then return 1 else return 0 end if 
end function 
 
function no_atoms_bernie_2( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	return not i 
end function 
 
function no_atoms_stdlib( object x ) 
    if not sequence(x) then 
        return 0 
    end if 
 
    for i = 1 to length(x) do 
        if not sequence(x[i]) then 
            return 0 
        end if 
    end for 
    return 1 
end function 
 
sequence a 
a = repeat({},500) 
a &= 1 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_2( a ) 
end for 
?time()-t 
 
for x=1 to 100000 do 
	no_atoms_stdlib( a ) 
end for 
?time()-t 
 
wait_key() 

The no_atoms_bernie_2() was just my testing of the "not" thingie. Didn't help. getlost

I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!

Probably, it's faster because in your example you put the atom at the end of the sequence, and Bernie's implementation begins from this point.

Depending on the uniformity of your sequences, it's possible to improve the speed if you store (cache) the index of the sequence when the function aborts. Then, on the next call, the circular search would begin at that stored point.

Regards,
Fernando

new topic     » goto parent     » topic index » view message » categorize

8. Re: Better Way to Do This

euphoric said...

Yeah, that's faster all right!

Sorry to burst the bubble, but the test is flawed.

Bernie's routines start from the back of the sequence and yours and mine from the front. Your test data had the atom as the last item so naturally, bernie's would find it first. Plus you forgot to reset the timer for the last test.

Here is some revised code.

include std/console.e 
 
atom t 
 
function no_atoms_1( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(s[t]) then return 0 end if 
	end for 
	return 1 
end function 
 
function no_atoms_bernie_1( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	if i=0 then return 1 else return 0 end if 
end function 
 
function no_atoms_bernie_2( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	return not i 
end function 
 
function no_atoms_stdlib( sequence x ) 
    for i = 1 to length(x) do 
        if not sequence(x[i]) then 
            return 0 
        end if 
    end for 
    return 1 
end function 
 
sequence a 
-- Put atom in the middle. 
a = repeat({},250) & 1 & repeat({},250) 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_2( a ) 
end for 
?time()-t 
t = time() 
for x=1 to 100000 do 
	no_atoms_stdlib( a ) 
end for 
?time()-t 
 
wait_key() 

I get these results ...

c:\temp>eui test 
0.5 
0.641 
0.656 
0.469 

euphoric said...

I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!

Good question ... don't know the answer yet.

new topic     » goto parent     » topic index » view message » categorize

9. Re: Better Way to Do This

Fernando said...

Probably, it's faster because in your example you put the atom at the end of the sequence, and Bernie's implementation begins from this point.

Depending on the uniformity of your sequences, it's possible to improve the speed if you store (cache) the index of the sequence when the function aborts. Then, on the next call, the circular search would begin at that stored point.

DOH! I failed to understand that. Hmmmm.

Our standard lib function is the fastest it seems. Yay!

new topic     » goto parent     » topic index » view message » categorize

10. Re: Better Way to Do This

DerekParnell said...

Sorry to burst the bubble, but the test is flawed.

Thank you Derek and Fernando for your diligent coder brains and hawk-like eyes. smile

DerekParnell said...
euphoric said...

I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!

Good question ... don't know the answer yet.

I could understand if the test for i was first, because it would short circuit, right? Hmmmmm.

Take your time. You'll figure it out.

new topic     » goto parent     » topic index » view message » categorize

11. Re: Better Way to Do This

The tests do not blow up at the sequence test because you always put in an atom in the sequences you are testing. If you put a sequence in that contains no atoms your program will crash. Try passing in {""}

new topic     » goto parent     » topic index » view message » categorize

12. Re: Better Way to Do This

DerekParnell said...
euphoric said...

Yeah, that's faster all right!

Sorry to burst the bubble, but the test is flawed.

Bernie's routines start from the back of the sequence and yours and mine from the front. Your test data had the atom as the last item so naturally, bernie's would find it first. Plus you forgot to reset the timer for the last test.

Here is some revised code.

include std/console.e 
 
atom t 
 
function no_atoms_1( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(s[t]) then return 0 end if 
	end for 
	return 1 
end function 
 
function no_atoms_bernie_1( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	if i=0 then return 1 else return 0 end if 
end function 
 
function no_atoms_bernie_2( sequence s ) 
integer i = length(s) 
	while sequence(s[i]) and i > 0 do 
		i -= 1 
	end while 
	return not i 
end function 
 
function no_atoms_stdlib( sequence x ) 
    for i = 1 to length(x) do 
        if not sequence(x[i]) then 
            return 0 
        end if 
    end for 
    return 1 
end function 
 
sequence a 
-- Put atom in the middle. 
a = repeat({},250) & 1 & repeat({},250) 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_1( a ) 
end for 
?time()-t 
 
t = time() 
for x=1 to 100000 do 
	no_atoms_bernie_2( a ) 
end for 
?time()-t 
t = time() 
for x=1 to 100000 do 
	no_atoms_stdlib( a ) 
end for 
?time()-t 
 
wait_key() 

I get these results ...

c:\temp>eui test 
0.5 
0.641 
0.656 
0.469 

euphoric said...

I do have a question. When i gets to zero, why doesn't the test for sequence(s[i]) fail? Or is 0 a valid sequence element?!

Good question ... don't know the answer yet.

The answer is simple. i never reaches 0, the loop exits when i is 1. I discovered this when I changed the data to include only sequences. i then reached 0 and produced the usual error.

new topic     » goto parent     » topic index » view message » categorize

13. Re: Better Way to Do This

LarryMiller said...

The answer is simple. i never reaches 0, the loop exits when i is 1. I discovered this when I changed the data to include only sequences. i then reached 0 and produced the usual error.

Smarty pants. I'm going to bed now! smile

new topic     » goto parent     » topic index » view message » categorize

14. Re: Better Way to Do This

bernie said...
euphoric said...

Is there a standard lib or more efficient function that could replace this? I'm using this for a type definition. The variable needs to be all sequences.

function no_atoms( sequence s ) 
integer i = 1 
	for t=1 to length(s) do 
		if atom(i) then return 0 end if 
	end for 
	return 1 
end function 

Would this be faster ?

function no_atoms( sequence s ) 
integer i = length(s) 
while(sequence(s[i]) and i > 0 ) do 
  i -= 1 
end while 
if i = 0 then return 1 else return 0 end if 
end function 

Sorry I went to bed and realized I put the short-circuit wrong.

It should of been this:

function no_atoms( sequence s ) 
integer i = length(s) 
while( i > 0 and sequence(s[i]) ) do -- <----<< 
  i -= 1 
end while 
if i = 0 then return 1 else return 0 end if 
end function 

[/quote]

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu