Matrix: Need help to understand this behavior

M

Marcio Braga

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
 
F

Frantisek ZACEK

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.
 
M

Marcio Braga

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 said:
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
 
M

Marcio Braga

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

Have a nice day !!
Marcio
 
F

Frantisek ZACEK

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.
 
M

Marcio Braga

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
 
F

Frantisek ZACEK

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


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

Todd Benson

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
 
M

Marcio Braga

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
 
M

Marcio Braga

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top