|
|||
|
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__ {} } |
|
|
||||
|
||||
|
|
|
|||
|
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 |
|
|||
|
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 |
|
|||
|
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. |
|
|||
|
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| +------------------------------------------------------------------------+ |
|
|||
|
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 ...]. |
|
|||
|
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| +------------------------------------------------------------------------+ |
|
|||
|
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. |
|
|||
|
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. ![]() |
|
|||
|
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. |
|
|||
|
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" } } |
|
|||
|
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 |
|
|||
|
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. |
|
|||
|
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 |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|