Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.* 1 > Newsgroup comp.lang.tcl

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 08-23-2009, 07:59 PM
fjval@unizar.es
Guest
 
Posts: n/a
Default Need help with grouping some data into only one data sctructure

Hello to everyone,

I'm modelling electrical networks, for optimizing its layout

An electrical network and its components are defined with these data
structures:
buses {}
lines($generator)
generators($generator)
loads($generator)
transformers($generator)
capacitorbanks($generator)

The procs to handle the data in & out are shown below (not all of
them, only for buses & lines data structs, the others are similar,
only changing data struct names).

This method works o.k. for one instatiation of the data struct. The
problem arises when in need to make a lot of different networks
derived from this, (for exampe, to apply a genetic algorithm to
optimize its layout), because it is impossible to make a "list of
networks".

The problem with my approach is that I don't kow how to make an array
(or a list) of "electrical networks".
(in C it would be done with and array of electrical networks, because
you can put them in a struct type).

The problem why I can't do this, is because tcl is a non typed
language (or loosely typed), so I cannot define something as "structs"
as in C., so wandering in the web I saw
http://users.telenet.be/koen.vandamm...l_objects.html

What about this method for implementing "tcl objects"? Can it be used
to implement "structs"? (although in the link they all them "tcl
objects").


What I need to do is something like (in C):

/*definition of a network*/
#define NUM_BUSES 200
struct network {
int buses[NUM_BUSES];
struct line lines[NUM_BUSES];
struct generators generators[NUM_BUSES];
struct loads loads[NUM_BUSES];
struct trafos transformers[NUM_BUSES];
struct cbanks capacitorbanks[NUM_BUSES];
}

/*list of networks*/
struct network population[3000]

/*individual variables to run the optimization method*/
struct network individual_t;
struct network individual_t_plus_1;


I have wirte this C code on the fly, so maybe are some errors, but
sure it serves to make an idea of what I mean.

It seems that I'm not able to find a valid approach to "group" all the
data structs of a network into one, so it can be treated as a unity.
Some suggestions please?

Thanks in advance


#================================================= ================================================== =============
buses.tcl
#================================================= ================================================== =============
#!/usr/bin/tclsh


#================================================= ================================================== =============
#definicion de variables
set buses__ {}
array set buses_type__ {}
#array set buses_voltage {}


#================================================= ================================================== =============
proc topology_buses_add {bus} {
global buses__
lappend buses__ $bus
}

#
proc topology_buses_list {} {
global buses__
return $buses__
}

#
proc topology_buses_length {} {
global buses__
return [llength $buses__]
}


#
proc topology_buses_reset {} {
global buses__
unset buses__
set buses__ {}
}


#================================================= ================================================== =============
proc topology_buses_type_set {bus type} {
global buses_type__
set buses_type__($bus) $type
}

#
proc topology_buses_type_get {bus} {
global buses_type__
return $buses_type__($bus)
}

#
proc topology_buses_type_reset {} {
global buses_type__
unset buses_type__
array set buses_type__ {}
}















#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============
#================================================= ================================================== =============






#================================================= ================================================== =============
lines-var.tcl
#================================================= ================================================== =============
#!/usr/bin/tclsh

#================================================= ================================================== =============
set lines__ {}
array set lines_bus1__ {}
array set lines_bus2__ {}
array set lines_length__ {}
array set lines_build__ {}
array set lines_cable__ {}



#================================================= ================================================== =============
#
proc topology_lines_add {line} {
global lines__
lappend lines__ $line
}

#
proc topology_lines_list {} {
global lines__
return $lines__
}

#
proc topology_lines_length {} {
global lines__
return [llength $lines__]
}

#
proc topology_lines_reset {} {
global lines__
unset lines__
set lines__ {}
}

#================================================= ================================================== =============
#
proc topology_lines_bus1_set {line bus} {
global lines_bus1__
set lines_bus1__($line) $bus
}

#
proc topology_lines_bus1_get {line} {
global lines_bus1__
return $lines_bus1__($line)
}

#
proc topology_lines_bus1_list {} {
global lines_bus1__
return $lines_bus1__
}

#
proc topology_lines_bus1_reset {} {
global lines_bus1__
unset lines_bus1__
array set lines_bus1__ {}
}

#================================================= ================================================== =============
#
proc topology_lines_bus2_set {line bus} {
global lines_bus2__
set lines_bus2__($line) $bus
}

#
proc topology_lines_bus2_get {line} {
global lines_bus2__
return $lines_bus2__($line)
}

#
proc topology_lines_bus2_list {} {
global lines_bus2__
return [$lines_bus2__]
}

#
proc topology_lines_bus2_reset {} {
global lines_bus2__
unset lines_bus2__
array set lines_bus2__ {}
}

#================================================= ================================================== =============
#
proc topology_lines_length_set {line length} {
global lines_length__
set lines_length__($line) $length
}

#
proc topology_lines_length_get {line} {
global lines_length__
return $lines_length__($line)
}

#
proc topology_lines_length_list {} {
global lines_length__
return [$lines_length__]
}

#
proc topology_lines_length_reset {} {
global lines_length__
unset lines_length__
array set lines_length__ {}
}

#================================================= ================================================== =============
#
proc topology_lines_build_set {line built} {
global lines_build__
set lines_build__($line) $built
}

#
proc topology_lines_build_get {line} {
global lines_build__
return $lines_build__($line)
}

#
proc topology_lines_build_list {} {
global lines_build__
return [$lines_build__]
}

#
proc topology_lines_build_reset {} {
global lines_build__
unset lines_build__
array set lines_built__ {}
}

#================================================= ================================================== =============
#
proc topology_lines_cable_set {line cable} {
global lines_cable__
set lines_cable__($line) $cable
}

#
proc topology_lines_cable_get {line} {
global lines_cable__
return $lines_cable__($line)
}

#
proc topology_lines_cable_list {} {
global lines_cable__
return [$lines_cable__]
}

#
proc topology_lines_cable_reset {} {
global lines_cable__
unset lines_cable__
array set lines_cable__ {}
}
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 08-23-2009, 09:03 PM
Jeff Godfrey
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

fjval@unizar.es wrote:
> Hello to everyone,
>
> I'm modelling electrical networks, for optimizing its layout
>
> An electrical network and its components are defined with these data
> structures:
> buses {}
> lines($generator)
> generators($generator)
> loads($generator)
> transformers($generator)
> capacitorbanks($generator)
>
> The procs to handle the data in & out are shown below (not all of
> them, only for buses & lines data structs, the others are similar,
> only changing data struct names).
>
> This method works o.k. for one instatiation of the data struct. The
> problem arises when in need to make a lot of different networks
> derived from this, (for exampe, to apply a genetic algorithm to
> optimize its layout), because it is impossible to make a "list of
> networks".
>
> The problem with my approach is that I don't kow how to make an array
> (or a list) of "electrical networks".
> (in C it would be done with and array of electrical networks, because
> you can put them in a struct type).
>
> The problem why I can't do this, is because tcl is a non typed
> language (or loosely typed), so I cannot define something as "structs"
> as in C., so wandering in the web I saw
> http://users.telenet.be/koen.vandamm...l_objects.html
>
> What about this method for implementing "tcl objects"? Can it be used
> to implement "structs"? (although in the link they all them "tcl
> objects").


While there are probably lots of ways to organize your data, since
you're familiar with 'C' structs, the [struct::record] package in tcllib
might be of particular interest.

http://tcllib.sourceforge.net/doc/record.html

Jeff
Reply With Quote
  #3 (permalink)  
Old 08-24-2009, 12:11 AM
Andrew Mangogna
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

fjval@unizar.es wrote:

> Hello to everyone,
>
> I'm modelling electrical networks, for optimizing its layout
>
> An electrical network and its components are defined with these data
> structures:
> buses {}
> lines($generator)
> generators($generator)
> loads($generator)
> transformers($generator)
> capacitorbanks($generator)
>


[ snip of long list stuff ]

I agree with the suggestion of the OP that if you conceive of the problem in "C"
like structures that you will want to look at the "struct::record" package in
tcllib. Indeed tcllib has a whole set of packages to give you more
sophisticated data structuring. If you want more object orientiation, as
suggested by the reference you included, then "incr Tcl" is to Tcl what C++ is
to "C" (approximately). A third suggestion might be to approach the problem
relationally and look at TclRAL (http://tclral.sourceforge.net) or SQLite as
(http://www.sqlite.org). Relational approaches will often yield data structures
for which ad hoc questions or queries are much easier to apply. Using basic Tcl
arrays, lists and dicts to model complicated relationships of data can be done,
but at some considerable strain to your brain.

--
Andrew Mangogna
Reply With Quote
  #4 (permalink)  
Old 08-24-2009, 07:45 AM
tom.rmadilo
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

My example of how to do this uses namespaces for data storage and
generic procedures to manipulate each instance of the data structure.

Here's a link to the basic code:

http://junom.com/gitweb/gitweb.perl?...tnt/tcl;h=ade5

Specifically look at nvlist-procs.tcl and nvlist-init.tcl

The fact that the nvlist is similar to a record is not really
important to the idea.

The idea is to import the nvlist procs into a namespace so that you
can more easily maintain a data structure in the new namespace.
Obviously you can repeat this for as many namespaces as you want
without conflict.

The procedures are generic, just like you would use in C in your
example. It is also expected that the programmer will write thin
wrappers around the basic API. nvlist-init.tcl has a few examples, and
you can search the git repo for other working examples.

If you use tcl 8.5, there are some hints (commented out code) which
would work better than the code for 8.4.

I use nvlists when I need key->value and also value->key, or a two way
map. It is also generalized, the "value" is by default everything
after the first list element, so you could have multiple values
associated with a key. Also, keys can appear more than once in an
nvlist, but you can adjust how this works.


Reply With Quote
  #5 (permalink)  
Old 08-24-2009, 01:44 PM
Gerald W. Lester
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

fjval@unizar.es wrote:
> Hello to everyone,
>
> I'm modelling electrical networks, for optimizing its layout
>
> An electrical network and its components are defined with these data
> structures:
> buses {}
> lines($generator)
> generators($generator)
> loads($generator)
> transformers($generator)
> capacitorbanks($generator)
>
> The procs to handle the data in & out are shown below (not all of
> them, only for buses & lines data structs, the others are similar,
> only changing data struct names).
>
> This method works o.k. for one instatiation of the data struct. The
> problem arises when in need to make a lot of different networks
> derived from this, (for exampe, to apply a genetic algorithm to
> optimize its layout), because it is impossible to make a "list of
> networks".
>
> The problem with my approach is that I don't kow how to make an array
> (or a list) of "electrical networks".
> (in C it would be done with and array of electrical networks, because
> you can put them in a struct type).
>
> The problem why I can't do this, is because tcl is a non typed
> language (or loosely typed), so I cannot define something as "structs"
> as in C., so wandering in the web I saw
> http://users.telenet.be/koen.vandamm...l_objects.html
>
> What about this method for implementing "tcl objects"? Can it be used
> to implement "structs"? (although in the link they all them "tcl
> objects").


Others have pointed you at the structs package.

Another solution, assuming you have Tcl 8.5, would be to use lists or arrays
of dicts. You can think of a dict as a structure definition with the key
being the field name -- in fact it can be a deep (i.e. multi-level) field.

List can act like C arrays (they are are index by integer element number).

Arrays are hash tables. Their index/keys are any string. So you can think
of them as a cheap SQL like table with a unique key.


--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
Reply With Quote
  #6 (permalink)  
Old 08-24-2009, 03:18 PM
tom.rmadilo
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

On Aug 24, 6:44*am, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
> fj...@unizar.es wrote:
> > Hello to everyone,

>
> > I'm modelling electrical networks, for optimizing its layout

>
> > An electrical network and its components are defined with these data
> > structures:
> > * *buses {}
> > * *lines($generator)
> > * *generators($generator)
> > * *loads($generator)
> > * *transformers($generator)
> > * *capacitorbanks($generator)

>
> > The procs to handle the data in & out are shown below (not all of
> > them, only for buses & lines data structs, the others are similar,
> > only changing data struct names).

>
> > This method works o.k. for one instatiation of the data struct. The
> > problem arises when in need to make a lot of different networks
> > derived from this, (for exampe, to apply a genetic algorithm to
> > optimize its layout), because it is impossible to make a "list of
> > networks".

>
> > The problem with my approach is that I don't kow how to make an array
> > (or a list) of "electrical networks".
> > (in C it would be done with and array of electrical networks, because
> > you can put them in a struct type).

>
> > The problem why I can't do this, is because *tcl is a non typed
> > language (or loosely typed), so I cannot define something as "structs"
> > as in C., so wandering in the web I saw
> >http://users.telenet.be/koen.vandamm...ts/tcl_objects...

>
> > What about this method for implementing "tcl objects"? Can it be used
> > to implement "structs"? (although in the link they all them "tcl
> > objects").

>
> Others have pointed you at the structs package.
>
> Another solution, assuming you have Tcl 8.5, would be to use lists or arrays
> of dicts. *You can think of a dict as a structure definition with the key
> being the field name -- in fact it can be a deep (i.e. multi-level) field..
>
> List can act like C arrays (they are are index by integer element number)..
>
> Arrays are hash tables. *Their index/keys are any string. *So you canthink
> of them as a cheap SQL like table with a unique key.
>


Dict is obviously a good choice, and if it is going to be a long term
project, I would stick to a built in data structure: lists, arrays or
dicts.

But for top level organization, when you have multiple copies of the
same gigantic substructure, tcl namespaces provide a unique solution.
The examples code above used the global namespace, but we only have
one of those, and it should be reserved for the overall application.
The procedures are also in the global namespace making them difficult
to import. A useful pattern is the generic API and this typically
employs [upvar] to link to the data structure being manipulated. Using
this pattern allows your programs to work with multiple persistent
data structures by just changing the reference. You can also avoid
upvar if your API both creates and maintains the data structure, then
you just supply the "name" of the overall network to every API
([method object ... ]). This is typical of many tcl commands ([lappend
listName ...]). Array and dict extend this to [class method
object ...].
Reply With Quote
  #7 (permalink)  
Old 08-24-2009, 03:39 PM
Gerald W. Lester
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

tom.rmadilo wrote:
> On Aug 24, 6:44 am, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
>> fj...@unizar.es wrote:
>>> Hello to everyone,
>>> I'm modelling electrical networks, for optimizing its layout
>>> An electrical network and its components are defined with these data
>>> structures:
>>> buses {}
>>> lines($generator)
>>> generators($generator)
>>> loads($generator)
>>> transformers($generator)
>>> capacitorbanks($generator)
>>> The procs to handle the data in & out are shown below (not all of
>>> them, only for buses & lines data structs, the others are similar,
>>> only changing data struct names).
>>> This method works o.k. for one instatiation of the data struct. The
>>> problem arises when in need to make a lot of different networks
>>> derived from this, (for exampe, to apply a genetic algorithm to
>>> optimize its layout), because it is impossible to make a "list of
>>> networks".
>>> The problem with my approach is that I don't kow how to make an array
>>> (or a list) of "electrical networks".
>>> (in C it would be done with and array of electrical networks, because
>>> you can put them in a struct type).
>>> The problem why I can't do this, is because tcl is a non typed
>>> language (or loosely typed), so I cannot define something as "structs"
>>> as in C., so wandering in the web I saw
>>> http://users.telenet.be/koen.vandamm...ts/tcl_objects...
>>> What about this method for implementing "tcl objects"? Can it be used
>>> to implement "structs"? (although in the link they all them "tcl
>>> objects").

>> Others have pointed you at the structs package.
>>
>> Another solution, assuming you have Tcl 8.5, would be to use lists or arrays
>> of dicts. You can think of a dict as a structure definition with the key
>> being the field name -- in fact it can be a deep (i.e. multi-level) field.
>>
>> List can act like C arrays (they are are index by integer element number).
>>
>> Arrays are hash tables. Their index/keys are any string. So you can think
>> of them as a cheap SQL like table with a unique key.
>>

>
> Dict is obviously a good choice, and if it is going to be a long term
> project, I would stick to a built in data structure: lists, arrays or
> dicts.
>
> But for top level organization, when you have multiple copies of the
> same gigantic substructure, tcl namespaces provide a unique solution.
>...


I did not mean to imply that namespaces should not be utilized in
conjunction with list, arrays and namespaces.

Sames goes for the OO methods (tclOO, Snit, Incr Tcl, XOtcl, ...)

--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
Reply With Quote
  #8 (permalink)  
Old 08-24-2009, 05:05 PM
tom.rmadilo
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

On Aug 24, 8:39*am, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
> tom.rmadilo wrote:

(blah blah blah)

> I did not mean to imply that namespaces should not be utilized in
> conjunction with list, arrays and namespaces.


> Sames goes for the OO methods (tclOO, Snit, Incr Tcl, XOtcl, ...)


Right, I should have said: organize both the API and the data into
something besides the global environment, assuming you want to handle
multiple examples of the model at the same time. I have nearly zero
experience (or interest) in the OO methods, so I can't offer a useful
opinion.
Reply With Quote
  #9 (permalink)  
Old 08-25-2009, 12:22 AM
fjval
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

On Aug 23, 11:03 pm, Jeff Godfrey <jeff_godf...@pobox.com> wrote:
> fj...@unizar.es wrote:
> > Hello to everyone,

>
> > I'm modelling electrical networks, for optimizing its layout

>
> > An electrical network and its components are defined with these data
> > structures:
> > buses {}
> > lines($generator)
> > generators($generator)
> > loads($generator)
> > transformers($generator)
> > capacitorbanks($generator)

>
> > The procs to handle the data in & out are shown below (not all of
> > them, only for buses & lines data structs, the others are similar,
> > only changing data struct names).

>
> > This method works o.k. for one instatiation of the data struct. The
> > problem arises when in need to make a lot of different networks
> > derived from this, (for exampe, to apply a genetic algorithm to
> > optimize its layout), because it is impossible to make a "list of
> > networks".

>
> > The problem with my approach is that I don't kow how to make an array
> > (or a list) of "electrical networks".
> > (in C it would be done with and array of electrical networks, because
> > you can put them in a struct type).

>
> > The problem why I can't do this, is because tcl is a non typed
> > language (or loosely typed), so I cannot define something as "structs"
> > as in C., so wandering in the web I saw
> >http://users.telenet.be/koen.vandamm...ts/tcl_objects...

>
> > What about this method for implementing "tcl objects"? Can it be used
> > to implement "structs"? (although in the link they all them "tcl
> > objects").

>
> While there are probably lots of ways to organize your data, since
> you're familiar with 'C' structs, the [struct::record] package in tcllib
> might be of particular interest.
>
> http://tcllib.sourceforge.net/doc/record.html
>
> Jeff


I have taken a look at struct::record

And I made my first try. I have only defined 2 out of 6 categorias in
the model, for simplicity:

#!/usr/bin/tclsh8.5

#................................................. ............
package require struct::record
namespace import ::struct::record::*

#definition of the records
record define buses_record {
buses
{array set buses_type {} }
}

#
record define lines_record lines {
lines
lines_bus1
lines_bus2
lines_length
lines_build
lines_cable
}

#
record define network_record {
{record buses_record buses}
{record lines_record lines}
}

#instance of network
network_record network

#growing list elements
network.buses.buses [concat [network.buses.buses] "bus1"]
network.buses.buses [concat [network.buses.buses] "bus2"]
network.buses.buses [concat [network.buses.buses] "bus3"]
puts "buses: [network.buses.buses]"

foreach bus [network.buses.buses] {
puts $bus
}

foreach bus [network.buses.buses] {
network.buses.buses_type($bus) "type$bus"
}

And the output is:

../objects2.tcl
buses: bus1 bus2 bus3
bus1
bus2
bus3
invalid command name "network.buses.buses_type(bus1)"
while executing
"network.buses.buses_type($bus) "type$bus""
("foreach" body line 2)
invoked from within
"foreach bus [network.buses.buses] {
network.buses.buses_type($bus) "type$bus"
}"
(file "./objects2.tcl" line 51)

So you can make a list a member of a record, but you can't make an
"array var" a member of a record.

So it seems the struct::record is not a solution.


Reply With Quote
  #10 (permalink)  
Old 08-25-2009, 12:25 AM
fjval
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

On Aug 24, 7:05 pm, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> On Aug 24, 8:39 am, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:> tom.rmadilo wrote:
>
> (blah blah blah)
>
> > I did not mean to imply that namespaces should not be utilized in
> > conjunction with list, arrays and namespaces.
> > Sames goes for the OO methods (tclOO, Snit, Incr Tcl, XOtcl, ...)

>
> Right, I should have said: organize both the API and the data into
> something besides the global environment, assuming you want to handle
> multiple examples of the model at the same time. I have nearly zero
> experience (or interest) in the OO methods, so I can't offer a useful
> opinion.


The problem is that "something", it seems as if tcl is not able to
offer an structured way of doing anything with variables, but the
simpler things.
Reply With Quote
  #11 (permalink)  
Old 08-25-2009, 01:51 AM
fjval
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

Dicts ar discarded at all.

Sure they be the greatest thing since the slice-bread, but, the man
page is completely inintelligle.

Cannot make sense of it (4 hours reading it and I cannot understand
what is a dict.. I suposse because in NOwhere is it explained).

And the example program is... subrealistic I'm afraid.

Moreover, dicts seem to be a "2D data struct", not able to make an
elaborated structure.

Example code of the man page:


# Data for one employee
dict set employeeInfo 12345-A forenames "Joe"
dict set employeeInfo 12345-A surname "Schmoe"
dict set employeeInfo 12345-A street "147 Short Street"
dict set employeeInfo 12345-A city "Springfield"
dict set employeeInfo 12345-A phone "555-1234"
# Data for another employee
dict set employeeInfo 98372-J forenames "Anne"
dict set employeeInfo 98372-J surname "Other"
dict set employeeInfo 98372-J street "32995 Oakdale Way"
dict set employeeInfo 98372-J city "Springfield"
dict set employeeInfo 98372-J phone "555-8765"
# The above data probably ought to come from a database...

# Print out some employee info
set i 0
puts "There are [dict size $employeeInfo] employees"
dict for {id info} $employeeInfo {
puts "Employee #[incr i]: $id"
dict with info {
puts " Name: $forenames $surname"
puts " Address: $street, $city"
puts " Telephone: $phone"
}
}

Reply With Quote
  #12 (permalink)  
Old 08-25-2009, 03:44 AM
fjval
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

I'm going to put more info about the problem.


************************************************** ************************************************** ***************************
The electrical network is defined with the next data structures.

This is is a real network example.


#--------------------------------------------------------------
#buses
buses {bus0 bus1 bus2 bus3}

buses_type(bus0) S
buses_type(bus1) PQ
buses_type(bus2) PQ
buses_type(bus3) PQ

#--------------------------------------------------------------
#lines
lines {line12}

line_bus1(line12) bus1
line_bus2(line12) bus2
line_length(line12) 1.0
line_cable(line12) cable_10_100
line_build(line12) S

#--------------------------------------------------------------
#loads
load {load1}
load_bus(load1) bus3
load_Pn(load1) 11456000
load_Qn(load1) 0
load_Vn(load1) 69000

#--------------------------------------------------------------
#generators
generator {gen0}

gen_operation(gen0) uncontrolled
gen_bus(gen0) bus0
gen_Sn(gen0) 90000000
gen_Vn(gen0) 13200
gen_Qmax(gen0) 40000000
gen_Qmin(gen0) -50000000
gen_Pmax(gen0) 400000000
gen_Pmin(gen0) 0.0

#--------------------------------------------------------------
#transformers
transformer {trafo1 trafo2}

trafo_operation(trafo1) uncontrolled
trafo_bus1(trafo1) bus0
trafo_bus2(trafo1) bus1
trafo_V1n(trafo1) 13200
trafo_V2n(trafo1) 132000
trafo_Sn(trafo1) 5000000
trafo_R1(trafo1) 0.0
trafo_X1(trafo1) 3.4848
trafo_R2(trafo1) 0.0
trafo_X2(trafo1) 0.0
trafo_Rfe(trafo1) 1000000000000.0
trafo_Xmu(trafo1) 1000000000000.0
trafo_desfase(trafo1) 0
trafo_rr(trafo1) 1.0

trafo_operation(trafo2) uncontrolled
trafo_bus1(trafo2) bus2
trafo_bus2(trafo2) bus3
trafo_V1n(trafo2) 138000
trafo_V2n(trafo2) 69000
trafo_Sn(trafo2) 10000000
trafo_R1(trafo2) 0.0
trafo_X1(trafo2) 152.3520
trafo_R2(trafo2) 0.0
trafo_X2(trafo2) 0.0
trafo_Rfe(trafo2) 1000000000000.0
trafo_Xmu(trafo2) 1000000000000.0
trafo_desfase(trafo2) 0
trafo_rr(trafo2) 1.0

************************************************** ************************************************** ***************************
As it can be seen they are all a lot of loose coupled variables.


************************************************** ************************************************** ***************************
As it is intended to apply some optimization method, it is necessary
to have "arrays" (array as in "array of whatever", not as in "tcl
associative array"), so the optimization method can be run something
like:

set fitness {}
foreach nwk "electrical_networks {
incr i +1
lappend fitness [calculate_fitness-function $nwk]

}

And electrical_networks is a list containing all the variants of the
electrical networks:
electrical_networks {e_net_1 e_net_2 e_net_3 ... e_net_N}

************************************************** ************************************************** ***************************
So it is necessary to have some kind of "data structure" which joins
it all.
And here it is a C-like pseudo-tcl-code of what I need to get (I hope
it be understood):

struct electrical_network {
#
buses;
array buses_type;

#
lines {}

array line_bus1;
array line_bus2;
array line_length;
array line_cable;
array line_build;

#loads
load {}

array load_bus;
array load_Pn;
array load_Qn;
array load_Vn;

#generators
generator {}

array gen_operation;
array gen_bus;
array gen_Sn;
array gen_Vn;
array gen_Qmax;
array gen_Qmin;
array gen_Pmax;
array gen_Pmin;

#transformers
transformer {}

array trafo_operation;
array trafo_bus1;
array trafo_bus2;
array trafo_V1n;
array trafo_V2n;
array trafo_Sn;
array trafo_R1;
array trafo_X1;
array trafo_R2;
array trafo_X2;
array trafo_Rfe;
array trafo_Xmu;
array trafo_desfase;
array trafo_rr;
}

this is a data struct which aglutinates all the disperse variables of
a network.

The problem is that it seems that tcl has no support for this kind of
structuration in the data variables, and, as I said in other posts, I
cannot find a way to fit the struct or dict data structures as a
solution. Maybe it can be done, but I don't see how.






************************************************** ************************************************** ***************************
The only solution I see is to make a "list of lists", something like:

network1 {
#buses
{bus0 bus1 bus2 bus3}
{
S
PQ
PQ
PQ
}

#lines
{line12}
{
{
bus1
bus2
1.0
cable_10_100
S
}
}

#loads
{load1}
{
{
bus3
11456000
0
69000
}
}

#generators
{gen0}
{
{
uncontrolled
bus0
90000000
13200
40000000
-50000000
400000000
0.0
}
}

#transformers
{trafo1 trafo2}
{
{
uncontrolled
bus0
bus1
13200
132000
5000000
0.0
3.4848
0.0
0.0
1000000000000.0
1000000000000.0
0
1.0
}

{
uncontrolled
bus2
bus3
138000
69000
10000000
0.0
152.3520
0.0
0.0
1000000000000.0
1000000000000.0
0
1.0
}
}
}




Let's se the diferences between the two models when trafo2.R1 be
requested
trafo2search is a variable in which we pass the trafo we are looking
for

Implementation with associative arrays:
foreach trafo $trafos {
if {$trafo == $trafo2search} {
set R1 [trafo_R1($trafo)]
}
}

Implementation with list of lists:
electrical_networks {eN_1 e_n_2 ... e_n_N}
for {set i 0} { $i < [expr [llength $electrical_networks] - 1] } {incr
i +1} {
set network [lindex $electrical_networks $i]
set trafos [lindex $network 8]

set trafoindex -1
foreach trafo $trafos {
incr trafoindex +1
if {$trafo == $trafo2search} {
set trafos_values [lindex $network 9]
set trafo_value [lindex $trafos_values $trafoindex]
set R1 [lindex $trafo_value 6]
}
}
}

A lot more code and more convoluted. And I think a lot more of
operations.

That's why I really need some way to group all that data sctructs into
one "whatever".

I did choose tcl over C by its simplicity for dealing with parsing
configuration files, and I would like to stick to tcl, but I reall y
don't know how to handle this.

I ow this is a looong post, but I thought it was need to clarify the
situation.

Thanks in advance
Reply With Quote
  #13 (permalink)  
Old 08-25-2009, 04:56 AM
tom.rmadilo
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

On Aug 24, 8:44*pm, fjval <fj...@unizar.es> wrote:
> I'm going to put more info about the problem.

....
> this is a data struct which aglutinates all the disperse variables of
> a network.
>
> The problem is that it seems that tcl has no support for this kind of
> structuration in the data variables, and, as I said in other posts, I
> cannot find a way to fit the struct or dict data structures as a
> solution. Maybe it can be done, but I don't see how.


You have not looked at tcl namespaces! Tcl namespaces allow the exact
same structure as a C struct, just replace . with ::. Of course you
can do a lot more with namespaces than with a C struct, but I use them
all the time as pure data containers.

The only real drawback is that they take up a more space than a pure
data structure. If you want to store tiny bits of data, an object
system would be more efficient.

As an example, I use nested tcl namespaces to fully represent XML
documents, including comments, attributes and "complex content".

In contrast, C structs are very simple, yet work very well for generic
functions. But in C you don't have a choice really.

The shortcoming of C is that usually developers just use the raw data
structure and never build an API around it to protect it and to
generalize the concepts. A tcl dict somewhat forces you to use the API
and the examples I have pointed to (as well as the tcllib struct and
OO stuff) use an access API. This is a little more time consuming to
setup, but should pay off in the long run.

BTW, last week I converted a brute force sudoku solver (on wikipedia)
to Tcl. It was really almost a line by line translation of the data
structures and algorithm. I've also looked at the source of sudokut,
which implements the Dancing links algorithm. Not exactly a simple
data structure.
Reply With Quote
  #14 (permalink)  
Old 08-25-2009, 02:15 PM
Glenn Jackman
Guest
 
Posts: n/a
Default Re: Need help with grouping some data into only one data sctructure

At 2009-08-24 11:44PM, "fjval" wrote:
> I'm going to put more info about the problem.
>
>
> ************************************************** ************************************************** ***************************
> The electrical network is defined with the next data structures.
>
> This is is a real network example.
>
>
> #--------------------------------------------------------------
> #buses
> buses {bus0 bus1 bus2 bus3}
>
> buses_type(bus0) S
> buses_type(bus1) PQ
> buses_type(bus2) PQ
> buses_type(bus3) PQ
>
> #--------------------------------------------------------------
> #lines
> lines {line12}
>
> line_bus1(line12) bus1
> line_bus2(line12) bus2
> line_length(line12) 1.0
> line_cable(line12) cable_10_100
> line_build(line12) S
>
> #--------------------------------------------------------------
> #loads
> load {load1}
> load_bus(load1) bus3
> load_Pn(load1) 11456000
> load_Qn(load1) 0
> load_Vn(load1) 69000
>
> #--------------------------------------------------------------
> #generators
> generator {gen0}
>
> gen_operation(gen0) uncontrolled
> gen_bus(gen0) bus0
> gen_Sn(gen0) 90000000
> gen_Vn(gen0) 13200
> gen_Qmax(gen0) 40000000
> gen_Qmin(gen0) -50000000
> gen_Pmax(gen0) 400000000
> gen_Pmin(gen0) 0.0
>
> #--------------------------------------------------------------
> #transformers
> transformer {trafo1 trafo2}
>
> trafo_operation(trafo1) uncontrolled
> trafo_bus1(trafo1) bus0
> trafo_bus2(trafo1) bus1
> trafo_V1n(trafo1) 13200
> trafo_V2n(trafo1) 132000
> trafo_Sn(trafo1) 5000000
> trafo_R1(trafo1) 0.0
> trafo_X1(trafo1) 3.4848
> trafo_R2(trafo1) 0.0
> trafo_X2(trafo1) 0.0
> trafo_Rfe(trafo1) 1000000000000.0
> trafo_Xmu(trafo1) 1000000000000.0
> trafo_desfase(trafo1) 0
> trafo_rr(trafo1) 1.0
>
> trafo_operation(trafo2) uncontrolled
> trafo_bus1(trafo2) bus2
> trafo_bus2(trafo2) bus3
> trafo_V1n(trafo2) 138000
> trafo_V2n(trafo2) 69000
> trafo_Sn(trafo2) 10000000
> trafo_R1(trafo2) 0.0
> trafo_X1(trafo2) 152.3520
> trafo_R2(trafo2) 0.0
> trafo_X2(trafo2) 0.0
> trafo_Rfe(trafo2) 1000000000000.0
> trafo_Xmu(trafo2) 1000000000000.0
> trafo_desfase(trafo2) 0
> trafo_rr(trafo2) 1.0

[...]
> The problem is that it seems that tcl has no support for this kind of
> structuration in the data variables, and, as I said in other posts, I
> cannot find a way to fit the struct or dict data structures as a
> solution. Maybe it can be done, but I don't see how.



This kind of data lends itself well to be treated as a domain specific
language. This program:

rename unknown _tcl_unknown
rename load _tcl_load

proc set_first_level {key1 values} {
foreach item $values {
dict set ::data $key1 $item {}
}
}
proc set_second_level {key1 item1 key2 value2} {
dict set ::data $key1 $item1 $key2 $value2
}

proc buses args { set_first_level buses {*}$args }
proc lines args { set_first_level line {*}$args }
proc load args { set_first_level load {*}$args }
proc generator args { set_first_level gen {*}$args }
proc transformer args { set_first_level trafo {*}$args }

proc unknown {cmdname args} {
if {[regexp {^(\w+?)_(\w+)\((.+)\)} $cmdname -> key1 key2 item1]} {
set_second_level $key1 $item1 $key2 {*}$args
} else {
puts stderr "don't know what to do with command '$cmdname' args '$args'"
}
}

set data [dict create]
source filename.data ;# the file that holds the above data
puts $data


creates this data structure in $data:

{
buses {
bus0 {
type S
}
bus1 {
type PQ
}
bus2 {
type PQ
}
bus3 {
type PQ
}
}
line {
line12 {
bus1 bus1
bus2 bus2
length 1.0
cable cable_10_100
build S
}
}
load {
load1 {
bus bus3
Pn 11456000
Qn 0
Vn 69000
}
}
gen {
gen0 {
operation uncontrolled
bus bus0
Sn 90000000
Vn 13200
Qmax 40000000
Qmin -50000000
Pmax 400000000
Pmin 0.0
}
}
trafo {
trafo1 {
operation uncontrolled
bus1 bus0
bus2 bus1
V1n 13200
V2n 132000
Sn 5000000
R1 0.0
X1 3.4848
R2 0.0
X2 0.0
Rfe 1000000000000.0
Xmu 1000000000000.0
desfase 0
rr 1.0
}
trafo2 {
operation uncontrolled
bus1 bus2
bus2 bus3
V1n 138000
V2n 69000
Sn 10000000
R1 0.0
X1 152.3520
R2 0.0
X2 0.0
Rfe 1000000000000.0
Xmu 1000000000000.0
desfase 0
rr 1.0
}
}
}


To extract information, you can say

puts [dict get $data gen gen0 Vn] ;# ==> 13200

--
Glenn Jackman
Write a wise saying and your name will live forever. -- Anonymous
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 02:39 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.