cartesian product

ruby

    Next

  • 1. Running a specific test in a test file.
    I remember there was a way to run a specific test from a test file. ruby test_file.rb Runs the all the tests. How can I select one from this? Also is there any complete reference on this (which argument the ruby command takes when running test files)? John

cartesian product

Postby walter a kehowski » Mon, 08 Aug 2005 17:56:22 GMT

Hello,

How would I create a function that will take list (array) of integers and 
return their cartesian product?

Thank You,

Walter Kehowski
nuby 



Re: cartesian product

Postby Giovanni Intini » Mon, 08 Aug 2005 18:27:47 GMT

> How would I create a function that will take list (array) of integers and

You could do something like:

a = [1, 2, 3]

b = []

a.each do |elementone|
 a.each do |elementtwo|
    b << [elementone, elementtwo]
 end
end

That should do the trick (I haven't tested it though)



Re: cartesian product

Postby walter a kehowski » Mon, 08 Aug 2005 18:50:35 GMT






Giovanni,

Yes, that works. Another nuby question: How to make it a function? Such as 
cartprod(a,b) returning c?

Walter



Re: cartesian product

Postby walter a kehowski » Mon, 08 Aug 2005 19:00:44 GMT





Remember that in Ruby you seldom have standalone functions. You should
probably create a class that has the cartprod method.

Giovanni,

Here's what I have so far:

def cartprod(a,b)

 c=[]

 a.each do |ae|
  b.each do |be|
    c << [ae, be]
  end
 end

return c

end

a=[1,2,3]

b=[4,5,6]

c=cartprod(a,b)

c.each { |ce| print ce,"\n" }

and this does print all the elements of c. Great. Now how do I do a class? 
Can I create a new method for Array?

Walter Kehowski



Re: cartesian product

Postby Giovanni Intini » Mon, 08 Aug 2005 19:01:28 GMT

Remember that in Ruby you seldom have standalone functions. You should
probably create a class that has the cartprod method.



Re: cartesian product

Postby daz » Mon, 08 Aug 2005 19:16:44 GMT





class Array
  def cartprod(b)
    c=[]
    each do |ae|
      b.each do |be|
        c << [ae, be]
      end
    end
    c
  end
end

a=[1,2,3]
b=[4,5,6]

c = a.cartprod(b)

c.each { |ce| p ce }


daz




Re: cartesian product

Postby Giovanni Intini » Mon, 08 Aug 2005 19:22:45 GMT

if you want to create a new method for array just do

class Array
  def cartprod(ary)
    result = []
    self.each do |ae|
      ary.each do |be|
        result << [ae, be]
      end
    end
    result
  end
end

this way you can have an array and do new_array =
source_array.cartprod(other_array)



Re: cartesian product

Postby Robert Klemme » Mon, 08 Aug 2005 21:41:19 GMT







Note that it might be more memory efficient to write a iteration method:

def cartprod(a,b)
  a.each {|ae| b.each {|be| yield ae, be}}
end

Then you can also do this if needed

c=[]
cartprod(a,b) {|x,y| c << [x,y]}

If you just need every combination once the iteration approach is more 
efficient.

Kind regards

    robert


Re: cartesian product

Postby Martin DeMello » Mon, 08 Aug 2005 23:46:39 GMT



Or even better, 

if block_given?
  yield ae, be
else
  (c ||= []) << ae, be
end

martin

Re: cartesian product

Postby Randy Kramer » Tue, 09 Aug 2005 02:15:13 GMT



I'm sure you know what you're talking about, but I wonder how many others 
will, even with comments.  (Maybe I just need to go back to Pascal?)

Randy Kramer



Re: cartesian product

Postby Hal Fulton » Tue, 09 Aug 2005 02:22:09 GMT





Haha... if it's this line you have trouble with

   (c ||= []) << ae, be

it's not that hard.

The ||= is a well-known idiom -- same as c = c || []  here. Basically
"assign c this value, unless it is already non-nil."

So then you have either an existing array or an empty one.
Then you can append (<<) onto it.

If it's the yield that bothers you, just study a bit more
Ruby. Pascal was wonderful in 1980 -- unless you already knew
something better -- but I'm content to let it go now. ;)


Hal





Re: cartesian product

Postby Randy Kramer » Tue, 09 Aug 2005 02:55:56 GMT



Hal,

Thanks--that line was the most confusing. (Yield I at least have a clue about, 
though I would need to think about it in this context a little more.)

regards,

Randy Kramer




Re: cartesian product

Postby walter a kehowski » Tue, 09 Aug 2005 07:01:23 GMT

Hello,

Here's what I have so far, combining the previous suggestions of Robert 
Klemme and Martin DeMello:

class Array

  def cartprod(a,b)
     a.each {|ae|
     b.each {|be|
      if block_given?
        yield ae,be
      else
        (c ||= []) << ae,be
      end
  end

end #Array

However,

c=cartprod([1,2,3],[4,5,6])

c.each { |ce| print ce,"\n" }

gives the following syntax error:

cartprod.rb:24: syntax error
        (c ||= []) << ae,be
                         ^
cartprod.rb:26: syntax error
cartprod.rb:132: syntax error

and I would like to take the cartesian product of an arbitrary number of 
sets in the most elegant way.




Re: cartesian product

Postby walter a kehowski » Tue, 09 Aug 2005 07:30:04 GMT

Hello,

The following is not in the spirit of previous comments

class Array

  def cartprod(b)

    c=[]
    each {|ae| b.each {|be| c << [ae, be] } }
    c.collect! {|ce| ce.flatten}

  end #cartprod

end #Array

a=[[1,2,3],[4,5,6],[7,8,9]]

c=a[0]
as=a.slice(1..a.length-1)
as.each {|ase| c=c.cartprod(ase) }
c.each  {|ce| ce.each {|x| print x," " }; print "\n" }

Would the following be desirable? If cartprod has two or more arguments, do 
the usual thing, but if it has just one, it takes the cartesian product with 
that argument, i.e, cartprod(a) gives cartprod(a,a) or a.cartprod(a), etc.

And thanks for all the suggestion so far. I usually just play around with 
Perl but got $#@% fatigue. It was a toss-up between Python and Ruby so here 
I am.

Walter Kehowski



Re: cartesian product

Postby Dave Burt » Tue, 09 Aug 2005 07:42:18 GMT

walter a kehowski wrote...

class Array
  def cartprod(b)
    each do |ae|
      b.each do |be|
        if block_given?
          yield ae, be  # <-- you can yield multiple objects
        else
          (c ||= []) << [ae, be]   # <-- you need to put (ae, be) in a 
single
                                   # object (i.e. an array) to put in an 
array
        end
      end   # <-- you had missed 2 closing braces (line 132 error)
    end
    c  # <-- you want to return this if no block was given
  end
end

Cheers,
Dave 



Similar Threads:

1.cartesian product of arrays

Hello,

did I miss some standard library function? Anyway, then I'll do it on
my own:

def cartprod(*args)
  result = [[]]
  while [] != args
    t, result = result, []
    b, *args = args
    t.each do |a|
      b.each do |n|
        result << a + [n]
      end
    end
  end
  result
end

Example:
cartprod([1,2],[3,4,5],[6,7,8])
=> [[1, 3, 6], [1, 3, 7], [1, 3, 8], [1, 4, 6], [1, 4, 7], [1, 4, 8],
    [1, 5, 6], [1, 5, 7], [1, 5, 8], [2, 3, 6], [2, 3, 7], [2, 3, 8],
    [2, 4, 6], [2, 4, 7], [2, 4, 8], [2, 5, 6], [2, 5, 7], [2, 5, 8]]

Regards
  Thomas

2.cartesian product - next to last version

Hello,

Since the original thread got a little long, I decided to post my next to 
last version in a new thread. My previous version gave results like 
[[1,4],7] for more than two arrays when you really wanted [1,4,7]. The trick 
is to flatten each element of the product. The following works for any 
number of arrays. Of course you might want a product in which the elements 
of that product are arrays. Any suggestions?

class Array

  def cartprod(b=[])
    if b.empty? then
      #assume self an array of arrays
      inject {|cp,x| cp.cartprod(x) }
    else
      z = inject([]) {|a,x| b.inject(a) {|a,y| a << [x,y]}}
      z.collect! {|x| x.flatten }
    end
  end

end


a=[1,2,3]
b=[4,5,6]
c=[7,8,9]

# works fine
p [a,b,c].cartprod

# doesn't work since [1,4,7,[10,11]] is [1,4,7,10,11]
d=[10, [11,12]]
p [a,b,c,d].cartprod


3.Cartesian and polar coordinates library

Hello,

For a personal project I had to create a library of cartesian and polar
coordinates. Is anyone else interested in this code? If so I'll try to turn
it in to a library and release it on rubyforge.
Just my way of saying thanks for Ruby, this turns out to be a really nice
language!

Regards,
Bart

4.Fastest way to compute dot product (inner product) in Ruby?

5.Product Class #2

[Note:  parts of this message were removed to make it a legal post.]

I was wondering if anyone had any ideas on how I could make the following
method "return "$#{@price}0" if "@price" only has one 0 after the ".", and
just "return "$#{@price}" if it has two?
Thanks.

(The following method is inside a class called "Product"... Hence the
subject)

    def price
        if @price.to_s.length == 4
            return "$#{@price}"
        else @price.to_s.length
            return "$#{@price}0"
        end
    end

6. how to create a product instance?

7. dot-product operators and strides for linear algebra

8. Howto ? :: multi notes for same product in rails



Return to ruby

 

Who is online

Users browsing this forum: No registered users and 70 guest