Pyomo:How to define parameters related to variables - pyomo

I'm new to Pyomo. I would like to know how to define parameters related to variables? In the following code, i want to express the parameter M.hd[i] is associated with variable M.p_dynamic[i] and other params.Because the M.hd[i] affects the following parameters. Is there any way to solve it? Thanks in advance.
from pyomo.environ import *
# Create a new model
M = ConcreteModel()
M.N = RangeSet(1,96)
M.p_real = Param(M.N,within=NonNegativeReals,initialize=2.0)
M.p_max = Param(M.N,within=NonNegativeReals,initialize=5.0)
M.p_dynamic = Var(M.N,within=NonNegativeReals)
d_base=[5, 8, 10, 9, 9, 5, 9, 4, 5, 4, 8, 3, 5, 2, 3, 3, 3, 1, 0, 19, 4, 0, 0, 0, 0, 1,
3, 5, 8, 14, 26, 28, 70, 84, 130, 145, 144, 71, 77, 76, 84, 60, 100, 55, 46, 42,
52, 50, 53, 44, 77, 55, 66, 39, 63, 67, 71, 41, 62, 62, 67, 47, 64, 62, 69, 50,
75, 47, 43, 26, 38, 36, 42, 36, 52, 24, 24, 22, 23, 14, 16, 7, 11, 5, 7, 7, 4,
4, 4, 0, 1, 0, 1, 0, 1, 0]
M.hd = Param(M.N, within=Integers)
def hd_rule(M,i):
return M.hd[i] == floor(d_base[i-1] * (M.p_max[i] - M.p_dynamic[i]) / (M.p_max[i] - M.p_real[i] ) )
M.hd_rule = Constraint(M.N,rule=hd_rule)

You can replace
M.hd = Param(M.N, within=Integers)
with
M.hd = Var(M.N, within=Integers)
This makes it possible to create the constraints using the hd_rule.

Related

How to concat a tensor in pytorch?

What I want to do is something like this:
import torch
a = torch.arange(120).reshape(2, 3, 4, 5)
b = torch.cat(list(a), dim=2)
I want to know:
I have to convert tensor to a list, will this cause performance not good?
Even performance is OK, can I do this just with tensor?
You want to:
Reduce the number of copies: in this specific scenario, copies need to be made since we are rearranging the layout of our underlying data.
Reduce or remove any torch.Tensor -> non-torch.Tensor conversions: this will be a pain point when working with a GPU since you're transferring data in and out of the device.
You can perform the same operation by permuting the axes such that axis=0 goes to axis=-2 (the before the last axis), then flattening the last two axes:
>>> a.permute(1,2,0,3).flatten(-2)
tensor([[[ 0, 1, 2, 3, 4, 60, 61, 62, 63, 64],
[ 5, 6, 7, 8, 9, 65, 66, 67, 68, 69],
[ 10, 11, 12, 13, 14, 70, 71, 72, 73, 74],
[ 15, 16, 17, 18, 19, 75, 76, 77, 78, 79]],
[[ 20, 21, 22, 23, 24, 80, 81, 82, 83, 84],
[ 25, 26, 27, 28, 29, 85, 86, 87, 88, 89],
[ 30, 31, 32, 33, 34, 90, 91, 92, 93, 94],
[ 35, 36, 37, 38, 39, 95, 96, 97, 98, 99]],
[[ 40, 41, 42, 43, 44, 100, 101, 102, 103, 104],
[ 45, 46, 47, 48, 49, 105, 106, 107, 108, 109],
[ 50, 51, 52, 53, 54, 110, 111, 112, 113, 114],
[ 55, 56, 57, 58, 59, 115, 116, 117, 118, 119]]])

Copy selected values (via view) from boost::multi_array to another array (C++)

How can I copy (deep-copy) a selcted range (view) from a boost::multi_array to another array?
The values can be copied via =operator.
#include <iostream>
#include <string>
#include <boost/multi_array.hpp>
template<typename T>
void initArray(T& to_initialize)
{
int value = 0;
for(size_t i=0;i<to_initialize.shape()[0];++i){
for(size_t j=0;j<to_initialize.shape()[1];++j){
to_initialize[i][j]=value;
++value;
}
}
}
template<typename T>
void printArray(T& to_print, std::string additional_text)
{
std::cout<<"**************"<<additional_text<<"*****************"<<std::endl;
for(size_t i=0;i<to_print.shape()[0];++i){
for(size_t j=0;j<to_print.shape()[1];++j){
std::cout<<to_print[i][j]<<", ";
}
std::cout<<std::endl;
}
std::cout<<"*******************************"<<std::endl;
}
int main()
{
auto big_array = boost::multi_array<double, 2>(boost::extents[10][10]);
initArray(big_array);
printArray(big_array, "initial big array");
using range = boost::multi_array_types::index_range;
boost::multi_array<double, 2>::index_gen indices;
boost::multi_array<double, 2>::array_view<2>::type big_array_view = big_array[ indices[range(0,2)][range(0,4)] ];
auto small_array = boost::multi_array<double, 2>(boost::extents[2][4]);
small_array = big_array_view; //Deep Copy
printArray(small_array, "small array after copy");
big_array_view[0][0]=999; // Does not affect small_array
printArray(big_array, "big array after modifying");
printArray(small_array, "small array is not affected after modifying big array");
}
Output is:
**************initial big array*****************
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
*******************************
**************small array after copy*****************
0, 1, 2, 3,
10, 11, 12, 13,
*******************************
**************big array after modifying*****************
999, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
*******************************
**************small array is not affected after modifying big array*****************
0, 1, 2, 3,
10, 11, 12, 13,
*******************************

Distributing uneven workload using MPI

I've got an Array
A(1:n_max)
which I would like to scatter with MPI in order to evaluate some f(A(j)). However the evaluation of f(A(1)) takes 0.35s and the evaluation of f(A(n_max)) takes 15s. I have different ideas on how to tackle it, but I'm not sure which is the best:
Some Master/Slave work load distributing.
Along the lines of this: http://www.hpc.cam.ac.uk/using-clusters/compiling-and-development/parallel-programming-mpi-example
I reorder A with Reshape(Transpose(Reshape(A)), which would turn
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98])
into
array([[ 0, 33, 66, 1, 34, 67, 2, 35, 68, 3, 36, 69, 4, 37, 70, 5, 38,
71, 6, 39, 72, 7, 40, 73, 8, 41, 74, 9, 42, 75, 10, 43, 76, 11,
44, 77, 12, 45, 78, 13, 46, 79, 14, 47, 80, 15, 48, 81, 16, 49, 82,
17, 50, 83, 18, 51, 84, 19, 52, 85, 20, 53, 86, 21, 54, 87, 22, 55,
88, 23, 56, 89, 24, 57, 90, 25, 58, 91, 26, 59, 92, 27, 60, 93, 28,
61, 94, 29, 62, 95, 30, 63, 96, 31, 64, 97, 32, 65, 98]])
which I then could distribute using scatter and gather. The problem is, that one process would have to run f(A(0)), f(A(33)) and f(A(66)), while another has to run f(A(32)), f(A(65)) and f(A(98)).
Sadly the run times in between rise monotonic, but not linear.
I'm hoping for some of your Ideas
What do you recommend?
If the order of execution is important (e.g. caches) you could split the array in contiguous groups of different sizes but almost equal workloads and distribute them with MPI_SCATTERV.
If the end of the array is to heavy (in case of work load) you could also split the array and use the same approach twice.
If the order of execution is not important and you have reordering doesn't take to much time I would prefer your second approach.
If you have always an array like this, you should think about the first solution but only send the interval limits instead of all numbers inside the interval. This makes especially sense if you are bandwidth-bound in your communication.

ofstream writing everything to my file twice

So I have a short program to generate a cost matrix to a file but when I run it everything is showing up in the file twice.
Here's what I have:
#include <cstdlib>
#include <fstream>
using namespace std;
int main(){
int V = rand() % 15 + 5;
int graph[V][V];
for( int i = 0; i < V; i++ ){
for( int j = 0; j < V; j++ ){
graph[i][j] = rand() % 50;
}
}
for( int i = 0; i < V; i++ ){
graph[i][i] = 0;
}
ofstream fout;
fout.open( "graphTest.txt", ios::app );
fout << V << endl;
for( int i = 0; i < V; i++ ){
for( int j = 0; j < V; j++ ){
fout << graph[i][j] << ", ";
}
fout << endl;
}
fout.close();
return 0;
}
And here's what the file shows:
18
0, 27, 15, 43, 35, 36, 42, 49, 21, 12, 27, 40, 9, 13, 26, 40, 26, 22,
36, 0, 18, 17, 29, 32, 30, 12, 23, 17, 35, 29, 2, 22, 8, 19, 17, 43,
6, 11, 0, 29, 23, 21, 19, 34, 37, 48, 24, 15, 20, 13, 26, 41, 30, 6,
23, 12, 20, 0, 31, 5, 25, 34, 27, 36, 5, 46, 29, 13, 7, 24, 45, 32,
45, 14, 17, 34, 0, 43, 0, 37, 8, 26, 28, 38, 34, 3, 1, 4, 49, 32,
10, 26, 18, 39, 12, 0, 36, 44, 39, 45, 20, 34, 28, 17, 1, 47, 2, 17,
42, 2, 6, 1, 30, 36, 0, 15, 39, 44, 19, 40, 29, 31, 17, 47, 21, 31,
25, 9, 27, 17, 6, 47, 3, 0, 15, 6, 33, 19, 24, 28, 21, 32, 29, 3,
19, 20, 18, 8, 15, 40, 49, 46, 0, 18, 45, 46, 1, 21, 5, 29, 38, 14,
28, 41, 0, 43, 0, 34, 14, 24, 14, 0, 6, 43, 41, 27, 15, 9, 36, 32,
1, 37, 28, 25, 7, 24, 21, 8, 45, 29, 0, 35, 43, 18, 28, 43, 11, 28,
29, 26, 4, 43, 13, 13, 38, 6, 40, 4, 18, 0, 38, 19, 17, 17, 46, 24,
43, 20, 33, 40, 49, 22, 25, 44, 40, 5, 39, 4, 0, 19, 32, 42, 14, 47,
7, 5, 4, 48, 11, 22, 28, 49, 43, 46, 18, 40, 22, 0, 10, 5, 1, 11,
30, 28, 5, 20, 36, 44, 26, 22, 15, 8, 16, 32, 8, 24, 0, 12, 24, 0,
36, 2, 49, 29, 0, 18, 21, 23, 31, 31, 30, 33, 44, 10, 13, 0, 31, 49,
46, 9, 23, 13, 18, 40, 45, 26, 16, 34, 40, 40, 34, 26, 42, 36, 0, 45,
6, 29, 18, 37, 12, 48, 22, 9, 9, 36, 10, 42, 37, 6, 1, 13, 22, 0,
18
0, 27, 15, 43, 35, 36, 42, 49, 21, 12, 27, 40, 9, 13, 26, 40, 26, 22,
36, 0, 18, 17, 29, 32, 30, 12, 23, 17, 35, 29, 2, 22, 8, 19, 17, 43,
6, 11, 0, 29, 23, 21, 19, 34, 37, 48, 24, 15, 20, 13, 26, 41, 30, 6,
23, 12, 20, 0, 31, 5, 25, 34, 27, 36, 5, 46, 29, 13, 7, 24, 45, 32,
45, 14, 17, 34, 0, 43, 0, 37, 8, 26, 28, 38, 34, 3, 1, 4, 49, 32,
10, 26, 18, 39, 12, 0, 36, 44, 39, 45, 20, 34, 28, 17, 1, 47, 2, 17,
42, 2, 6, 1, 30, 36, 0, 15, 39, 44, 19, 40, 29, 31, 17, 47, 21, 31,
25, 9, 27, 17, 6, 47, 3, 0, 15, 6, 33, 19, 24, 28, 21, 32, 29, 3,
19, 20, 18, 8, 15, 40, 49, 46, 0, 18, 45, 46, 1, 21, 5, 29, 38, 14,
28, 41, 0, 43, 0, 34, 14, 24, 14, 0, 6, 43, 41, 27, 15, 9, 36, 32,
1, 37, 28, 25, 7, 24, 21, 8, 45, 29, 0, 35, 43, 18, 28, 43, 11, 28,
29, 26, 4, 43, 13, 13, 38, 6, 40, 4, 18, 0, 38, 19, 17, 17, 46, 24,
43, 20, 33, 40, 49, 22, 25, 44, 40, 5, 39, 4, 0, 19, 32, 42, 14, 47,
7, 5, 4, 48, 11, 22, 28, 49, 43, 46, 18, 40, 22, 0, 10, 5, 1, 11,
30, 28, 5, 20, 36, 44, 26, 22, 15, 8, 16, 32, 8, 24, 0, 12, 24, 0,
36, 2, 49, 29, 0, 18, 21, 23, 31, 31, 30, 33, 44, 10, 13, 0, 31, 49,
46, 9, 23, 13, 18, 40, 45, 26, 16, 34, 40, 40, 34, 26, 42, 36, 0, 45,
6, 29, 18, 37, 12, 48, 22, 9, 9, 36, 10, 42, 37, 6, 1, 13, 22, 0,
I'm not sure why it's looping through twice
You opened your file with ios::app flags, such it appends the data to an existing file from a former run:
fout.open( "graphTest.txt", ios::app );
// ^^^^^^^^
Open your file using the ios::trunc flag to overwrite the data from previous runs:
fout.open( "graphTest.txt", ios::trunc );
// ^^^^^^^^^^
As a side note:
The reason why you are seeing the same sequence in the file as the product of subsequent runs your program is because you missed to initialize the random generator. You have to call e.g.
seed(time(NULL));
once in the beginning of main().

NvTriStripe: Generates stripes with duplicate indices

Using NvTriStrip library from Nvidia,
http://www.nvidia.in/object/nvtristrip_library.html
I was trying to use NVTriStriper for creating triangle stripes from triangle indices. But, seems it does not work perfectly.
The following is the input indices,
PrimitiveGroup *pPrimitiveGroup = NULL;
uint16 NbGroups;
uint16 ind[] = {1, 2, 3, 1, 3, 4, 0, 1, 4, 5, 0, 4, 61, 0, 5, 60, 61, 5, 59, 60, 5, 59, 5, 6, 6, 58, 59, 57, 58, 6, 7, 57, 6, 56, 57, 7, 8, 56, 7, 21, 56, 8, 21, 8, 9, 9, 20, 21, 19, 20, 9, 18, 19, 9, 18, 9, 10, 18, 10, 17, 11, 17, 10, 16, 17, 11, 16, 11, 15, 15, 11, 12, 15, 12, 14, 14, 12, 13, 21, 22, 56, 22, 55, 56, 22, 54, 55, 23, 54, 22, 53, 54, 23, 53, 23, 24, 52, 53, 24, 36, 52, 24, 36, 24, 25, 35, 36, 25, 25, 26, 35, 27, 35, 26, 27, 34, 35, 34, 27, 33, 33, 27, 28, 32, 33, 28, 31, 32, 28, 28, 30, 31, 30, 28, 29, 51, 52, 36, 37, 51, 36, 37, 50, 51, 37, 49, 50, 37, 48, 49, 48, 37, 38, 48, 38, 47, 39, 47, 38, 47, 39, 46, 46, 39, 45, 45, 39, 40, 44, 45, 40, 44, 40, 41, 43, 44, 41, 43, 41, 42};
uint16 count=180;
GenerateStrips(ind, count, &pPrimitiveGroup, &NbGroups, true);
The output generated is,
NbGroups = 1
(*pPrimitiveGroup).numIndices = 101
And stripe indices as follows,
outputIndices={10, 10, 17, 11, 16, 11, 15, 12, 14, 13, 13, 54, 54, 54, 22, 55, 22, 56, 21, 8, 21, 9, 20, 9, 19, 9, 18, 10, 17, 17, 2, 2, 2, 3, 1, 4, 0, 5, 61, 5, 60, 5, 59, 6, 58, 6, 57, 7, 56, 8, 8, 24, 24, 24, 36, 25, 35, 26, 35, 27, 34, 27, 33, 28, 32, 28, 31, 28, 30, 29, 29, 42, 42, 43, 41, 44, 40, 45, 39, 46, 39, 47, 38, 48, 37, 37, 48, 48, 37, 49, 37, 50, 37, 51, 36, 52, 24, 53, 23, 54, 22}
Now, with this out as you can see, there are triangles with indices such as (56, 8, 8), this results in rendering lines and not triangles.
Anyone aware of such problems in NVTriStrip?
there are triangles with indices such as (56, 8, 8), this results in rendering lines and not triangles.
No, they result in rendering nothing. The triangle rasterizer renders the area of a triangle; a triangle composed of 2 points has no area and therefore is not rendered.
And yes, this is expected. That's how NVTriStrip works. This is a common technique called "stitching": multiple triangle strips are tied together with degenerate triangles (triangles with no area). This is what allows you to draw the entire model with a single glDrawElements call (or DrawIndexedPrimitive, if you use that).