Matrix: Need help to understand this behavior

Discussion in 'Ruby' started by Marcio Braga, Aug 17, 2008.

  1. Marcio Braga

    Marcio Braga Guest

    a=[1]
    b=a # make matrix "b" equal matrix "a", but expected 2
    separated matrices
    b[0]=2*b[0] # I want to change matrix "b" (and not matrix "a")
    p a # print matrix "a" and see the "issue"

    The expected value in the matrix "a" should be 1, but instead it is 2.

    Why ?

    Thank you.
    Marcio
    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 17, 2008
    #1
    1. Advertising

  2. On Sun, Aug 17, 2008 at 3:55 PM, Marcio Braga <> wrote:
    > a=[1]
    > b=a # make matrix "b" equal matrix "a", but expected 2
    > separated matrices
    > b[0]=2*b[0] # I want to change matrix "b" (and not matrix "a")
    > p a # print matrix "a" and see the "issue"
    >
    > The expected value in the matrix "a" should be 1, but instead it is 2.
    >
    > Why ?
    >
    > Thank you.
    > Marcio



    Typical Ruby behavior.

    In Ruby, variables reference objects rather than contain values.
    Therefore, when you write b = a, b references the same object as a does.
    Therefore, when you modify b, you modify a.
    See the obejct_ids in your code:

    $>cat mat.rb
    #!/usr/bin/env ruby -wKU

    a = [1]
    b = a
    puts a.object_id
    puts b.object_id
    b[0] = 2 * b[0]
    p a
    p b
    $>ruby mat.rb
    284610
    284610
    [2]
    [2]
    $>

    See ? same objects.

    To do what you want, you need to duplicate your array rather than just
    assign it :
    $>cat dup_mat.rb
    #!/usr/bin/env ruby -wKU

    a = [1]
    b = a.dup
    puts a.object_id
    puts b.object_id
    b[0] = 2 * b[0]
    p a
    p b
    $>ruby dup_mat.rb
    284540
    284530
    [1]
    [2]
    $>

    Hope it helped.

    --
    Frantisek ZACEK (zacek_f) -- SRS 2008
    Frantisek ZACEK, Aug 17, 2008
    #2
    1. Advertising

  3. Marcio Braga

    Marcio Braga Guest

    Just to complement, as a contrast, the code below works as expected, or
    in other words, the content of matrix "a" is not changed when you change
    the content of matrix "b".

    b=[]
    a=[1]
    b[0]=a[0] # explicitly set a single element and not the entire
    matrix
    b[0]=2*b[0]
    p a

    Marcio


    Marcio Braga wrote:
    > a=[1]
    > b=a # make matrix "b" equal matrix "a", but expected 2
    > separated matrices
    > b[0]=2*b[0] # I want to change matrix "b" (and not matrix "a")
    > p a # print matrix "a" and see the "issue"
    >
    > The expected value in the matrix "a" should be 1, but instead it is 2.
    >
    > Why ?
    >
    > Thank you.
    > Marcio


    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 17, 2008
    #3
  4. Marcio Braga

    Marcio Braga Guest

    Thank you Zacek. I understand your point and that help very much.

    Have a nice day !!
    Marcio


    Frantisek ZACEK wrote:
    > On Sun, Aug 17, 2008 at 3:55 PM, Marcio Braga <>
    > wrote:
    >> Thank you.
    >> Marcio

    >
    >
    > Typical Ruby behavior.
    >
    > .....
    >
    > Hope it helped.

    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 17, 2008
    #4
  5. On Sun, Aug 17, 2008 at 4:22 PM, Marcio Braga <> wrote:
    > Just to complement, as a contrast, the code below works as expected, or
    > in other words, the content of matrix "a" is not changed when you change
    > the content of matrix "b".
    >
    > b=[]
    > a=[1]
    > b[0]=a[0] # explicitly set a single element and not the entire
    > matrix
    > b[0]=2*b[0]
    > p a
    >
    > Marcio
    >
    >


    Here you create explicitely two objects therefore : no problem whereas
    on the first snippet, you only have one.


    --
    Frantisek ZACEK (zacek_f) -- SRS 2008
    Frantisek ZACEK, Aug 17, 2008
    #5
  6. Marcio Braga

    Marcio Braga Guest

    Zacek and all: how to duplicate a matrix that has elements that are also
    matrix ?
    For example:

    a = [[1]]
    b = a.dup
    puts a.object_id
    puts b.object_id
    puts a[0].object_id # the same object
    puts b[0].object_id # the same object
    b[0][0] = 2 * b[0][0]
    p a
    p b

    So, matrix "a" and "b" are different objects but each internal matrix
    element continue to be the same object. Do I need to duplicate each one
    ?

    Thank you
    Marcio
    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 17, 2008
    #6
  7. On Sun, Aug 17, 2008 at 4:53 PM, Marcio Braga <> wrote:
    > Zacek and all: how to duplicate a matrix that has elements that are also
    > matrix ?
    > For example:
    >
    > a = [[1]]
    > b = a.dup
    > puts a.object_id
    > puts b.object_id
    > puts a[0].object_id # the same object
    > puts b[0].object_id # the same object
    > b[0][0] = 2 * b[0][0]
    > p a
    > p b
    >
    > So, matrix "a" and "b" are different objects but each internal matrix
    > element continue to be the same object. Do I need to duplicate each one
    > ?
    >
    > Thank you
    > Marcio
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >



    I don't think there is a simple way to achieve that.
    I would suggest:
    a=[[1]]
    b=a.dup.colllect { |e| e.dup }

    --
    Frantisek ZACEK (zacek_f) -- SRS 2008
    Frantisek ZACEK, Aug 17, 2008
    #7
  8. Marcio Braga

    Todd Benson Guest

    On Sun, Aug 17, 2008 at 9:53 AM, Marcio Braga <> wrote:
    > Zacek and all: how to duplicate a matrix that has elements that are also
    > matrix ?
    > For example:
    >
    > a = [[1]]
    > b = a.dup
    > puts a.object_id
    > puts b.object_id
    > puts a[0].object_id # the same object
    > puts b[0].object_id # the same object
    > b[0][0] = 2 * b[0][0]
    > p a
    > p b
    >
    > So, matrix "a" and "b" are different objects but each internal matrix
    > element continue to be the same object. Do I need to duplicate each one
    > ?


    It's a Matrix, right? (some of this stolen from a previous thread)...

    require 'matrix'
    class Matrix
    def []=(i, j, n)
    @rows[j] = n
    end
    end

    m = Matrix[['a', 'b'], ['c', 'd']]
    k = m.clone
    k[0, 0] = 'e'
    puts k.to_a
    puts m.to_a

    Todd
    Todd Benson, Aug 18, 2008
    #8
  9. Marcio Braga

    Marcio Braga Guest

    > I don't think there is a simple way to achieve that.
    > I would suggest:
    > a=[[1]]
    > b=a.dup.colllect { |e| e.dup }


    Ok.
    So I need to create "my own" function to do that (just in case
    a=[[[1]]])

    Thank you
    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 18, 2008
    #9
  10. Marcio Braga

    Marcio Braga Guest

    > It's a Matrix, right? (some of this stolen from a previous thread)...
    >
    > require 'matrix'
    > class Matrix
    > def []=(i, j, n)
    > @rows[j] = n
    > end
    > end
    >
    > m = Matrix[['a', 'b'], ['c', 'd']]
    > k = m.clone
    > k[0, 0] = 'e'
    > puts k.to_a
    > puts m.to_a
    >
    > Todd


    At first I was not considering to handle them using Matrix class (just
    Array class) but thank you to call attention to this clone method of
    Matrix.

    Marcio
    --
    Posted via http://www.ruby-forum.com/.
    Marcio Braga, Aug 18, 2008
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Danny Anderson
    Replies:
    5
    Views:
    1,489
    Martin Eisenberg
    Jan 26, 2004
  2. lvcargnini

    Matrix composed by two matrix

    lvcargnini, Jul 4, 2006, in forum: VHDL
    Replies:
    3
    Views:
    2,649
    Jonathan Bromley
    Jul 5, 2006
  3. Holgerson

    Matrix*Vector and Vector*Matrix

    Holgerson, Oct 25, 2007, in forum: C++
    Replies:
    3
    Views:
    401
    Holgerson
    Oct 26, 2007
  4. Terry Reedy
    Replies:
    0
    Views:
    543
    Terry Reedy
    Apr 2, 2009
  5. Robert Kern
    Replies:
    0
    Views:
    582
    Robert Kern
    Apr 2, 2009
Loading...

Share This Page