As I am new to optimization toolbox in MATLAB I am struggling with the right code on how to optimize my objective function. At the beginning I have the following data:
a = [3 3 1 1];
c = [2 5 5 10];
My objective function along with the equality and inequality constraints are:
F=∑(k=1..4){[0.2.*a(k)]+[0.16.*x_1(k)]+[b(k).*x_2 (k)]}
The objective function F is a sum of series from k = 1..4
Equality Constraints:
a(k)+x_1 (k)+x_2 (k)=c(k) AND d(k)=x_1 (k)+d(k-1)
Inequality Constraints
x_1 (k)≤d(k)≤10
The variables that optimize the above function are x1(k) and x2(k). Is there a method how can I do that?
Image of the equations:
Since your constraints are linear, you can use linear programming:
clear all;
n_k = 4; % number of k
n_v = 3; % number of variables
a = [3 3 1 1];
b = [0.19 0.19 0.19 0.19];
c = [2 5 5 10];
d0 = 0;
% Objective x1 x2 d
f = zeros(1, n_k * n_v);
f(1:n_v:end) = 0.16; % x1 coefficient
f(2:n_v:end) = b; % x2 coefficient (b(k))
% Equality 1
eq1 = [1 1 0]; % x1 + x2 + 0 * d = c(k) - a(k)
Aeq = zeros(2 * n_k, n_v * n_k);
for i = 1:1:n_k
Aeq(i, :) = cat(2, eq1, zeros(1, n_k * n_v - length(eq1)));
eq1 = cat(2, zeros(1, n_v), eq1);
end
eq2 = [1 1 0 -1]; % d(k-1) + x1(k) + 0 * x2(k) - d(k) = 0
Aeq(n_k + 1, :) = [1 0 -1 0 0 0 0 0 0 0 0 0];
Aeq(n_k + 2, :) = [0 0 1 1 0 -1 0 0 0 0 0 0];
Aeq(n_k + 3, :) = [0 0 0 0 0 1 1 0 -1 0 0 0];
Aeq(n_k + 4, :) = [0 0 0 0 0 0 0 0 1 1 0 -1];
beq = zeros(1, 8);
beq(1:n_k) = c - a;
beq(5) = -d0;
% Inequality
le1 = [1 0 -1];
A = zeros(n_k, n_v * n_k);
for i = 1:1:n_k
A(i, :) = cat(2, le1, zeros(1, n_k * n_v - length(le1)));
le1 = cat(2, zeros(1, n_v), le1);
end
b = zeros(1, 4);
ub = inf(1, n_k * n_v);
ub(3:n_v:end) = 10;
lb = -inf(1, n_k * n_v);
And to solve:
X = linprog(f, A, b, Aeq, beq, lb, ub);
Output:
>> reshape(X, 3, 4)
ans =
5.8261 1.1680 -4.1562 7.1621
-6.8261 0.8320 8.1562 1.8379
5.8261 6.9941 2.8379 10.0000
You can check:
>> [X(1:3:end), X(2:3:end), transpose(a),
X(1:3:end) + X(2:3:end) + transpose(a), transpose(c)]
ans =
5.8261 -6.8261 3.0000 2.0000 2.0000
1.1680 0.8320 3.0000 5.0000 5.0000
-4.1562 8.1562 1.0000 5.0000 5.0000
7.1621 1.8379 1.0000 10.0000 10.0000
>> [X(3:3:end), X(1:3:end), X(3:3:end) - X(1:3:end), [0; X(3:3:11)]]
ans =
5.8261 5.8261 -0.0000 0
6.9941 1.1680 5.8261 5.8261
2.8379 -4.1562 6.9941 6.9941
10.0000 7.1621 2.8379 2.8379
>> [X(1:3:end), X(3:3:end)]
ans =
5.8261 5.8261
1.1680 6.9941
-4.1562 2.8379
7.1621 10.0000
Old answer (before comment)
% Objective a c d x1 x2
f = [.2 0 0 .16 .19];
f = repmat(f, 1, 4);
% Equality 1
eq1 = [1 -1 0 1 1]; % a c d x1 x1
eq2 = [1 0 0 0 0 -1 1 0]; % d(k-1) x1(k-1) x2(k-1) a(k) c(k) d(k) x1(k) x2(k)
Aeq = [cat(2, eq1, zeros(1, 15));
cat(2, zeros(1, 5), eq1, zeros(1, 10));
cat(2, zeros(1, 10), eq1, zeros(1, 5));
cat(2, zeros(1, 15), eq1);
cat(2, zeros(1, 2), eq2, zeros(1, 10));
cat(2, zeros(1, 7), eq2, zeros(1, 5));
cat(2, zeros(1, 12), eq2)];
beq = zeros(1, 7);
% Inequality
le1 = [0 0 -1 1 0];
A = [cat(2, le1, zeros(1, 15));
cat(2, zeros(1, 5), le1, zeros(1, 10));
cat(2, zeros(1, 10), le1, zeros(1, 5));
cat(2, zeros(1, 15), le1)];
b = zeros(1, 4);
ub = [inf inf 10 inf inf];
ub = repmat(ub, 1, 4);
lb = ones(1, 5) * (-inf);
lb = repmat(lb, 1, 4);
ub(3) = d0;
lb(3) = d0;
And to solve:
linprog(f, A, b, Aeq, beq, lb, ub)
Note that there are probably some information missing in your original post since it looks like this problem is unbounded.
Related
I'm not much familiar with this programming language and I just need to run one function to compute some coeficients.
f[x] = x^2 - 2 x + 2
g[x] = x^3 - 2 x^2 - 2 x - 2
f1 = Root[f[x], 1];
f2 = Root[f[x], 2];
g1 = Root[g[x], 1];
g2 = Root[g[x], 2];
g3 = Root[g[x], 3];
foo[rootList, alpha, beta] :=
(
res = {};
For[i = 1, i <= Length[rootList], i++, alphaI = rootList[[i]];
For[j = 1, j <= Length[rootList], j++, betaJ = rootList[[j]];
If[betaJ != beta,
(
kor = Simplify [(alphaI - alpha) / (beta - betaJ)];
res = Append[res, N[kor, 5]];
),
]
]
]
Return[res];
)
roots = [f1, f2, g1, g2, g3];
cs = foo[roots, f1, g1]
this piece of code gives me this error:
Syntax::tsntxi: "For[i=1,i<=Length[rootList],i++,alphaI=rootList[[i]];" is incomplete; more input is needed.
And don't see what is wrong. I'm using mathematica 10.4
Fixing the syntax errors.
f[x_] := x^2 - 2 x + 2
g[x_] := x^3 - 2 x^2 - 2 x - 2
f1 = Root[f[x], 1];
f2 = Root[f[x], 2];
g1 = Root[g[x], 1];
g2 = Root[g[x], 2];
g3 = Root[g[x], 3];
foo[rootList_, alpha_, beta_] :=
(
res = {};
For[i = 1, i <= Length[rootList], i++, alphaI = rootList[[i]];
For[j = 1, j <= Length[rootList], j++, betaJ = rootList[[j]];
If[betaJ != beta,
(
kor = Simplify[(alphaI - alpha)/(beta - betaJ)];
res = Append[res, N[kor, 5]];
)
]
]
];
res
)
roots = {f1, f2, g1, g2, g3};
cs = foo[roots, f1, g1]
I'm trying to implement a zero padding zoom using fourier.
I'm using octave and I can't add zeros around my matrix.
The result (after inverse fourier transformation) is very dark.
My goal:
My code:
I=double(imread('montagne.jpeg'));
I = I/255;
%%scaling factor
facteur = 4;
[m,n,r] = size(I);
H=fft2(I);
H = fftshift(H);
%%the new image
B = zeros(facteur*m,facteur*n,3);
%%try to add zeros around my matrix
%% r : rgb channels
for r=1:3
for i=1:m
for j=1:n
B(i+((facteur*m)/4),j+((facteur*n)/4),r) = H(i,j,r);
end
end
end
%% show the image
B= ifftshift(B);
final = ifft2(B);
figure;
imshow(final);
Any suggestions ?
Don't use for-loops to copy matrices. I would try something like:
I = im2double (imread ('IMG_2793.JPG'));
facteur = 4; %%scaling factor
[m, n, r] = size (I);
H = fftshift (fft2 (I));
B = zeros(facteur*m, facteur*n, 3);
ms = round (m * (facteur/2 - 0.5));
ns = round (n * (facteur/2 - 0.5));
B(ms:(m+ms-1), ns:(n+ns-1), :) = H;
final = abs (ifft2 (ifftshift (B)));
figure;
imshow(final * facteur^2);
EDIT:
Btw, there is also the function padarray which does what you want:
octave:1> padarray (magic(3), [1, 1])
ans =
0 0 0 0 0
0 8 1 6 0
0 3 5 7 0
0 4 9 2 0
0 0 0 0 0
I used
library('cubature')
adaptIntegrate(doubleintegral, lowerLimit = c(-2.5, -2), upperLimit = c(0, 2), x=x,r=r,m=m,n=n)$integral
to integrate the following function:
doubleintegral <- function(y,x,r,n,m){
max(((-y[1])^(n-1)*(y[2]-y[1])^(m-1)*exp((x[7]+x[4])*y[1]))*
exp(-x[4]*y[2] - (r[v]-y[2]-x[5]*x[3]+0.5*x[6]^2*x[3])^2/(2*x[6]^2*x[3])),0)}
I used this Example Parameters
x <- numeric()
x[1] = 42
x[2] = 21
x[3] = 1
x[4] = 72.9
x[5] = 0.0332
x[6] = 0.0311
x[7] = 16.8
r <- numeric()
r = 0.0006
v = 1
r[v] = -0.036
w = 1
n = 2
i = 1
m = 2
I don't understand how the following output is possible:
> adaptIntegrate(doubleintegral, lowerLimit = c(-130, -4), upperLimit = c(0, 4), x=x,r=r,m=m,n=n)$integral
[1] 1.12184e-07
> adaptIntegrate(doubleintegral, lowerLimit = c(-2.5, -2), upperLimit = c(0, 2), x=x,r=r,m=m,n=n)$integral
[1] 2.516489e-07
By widening the limits i get a smaller value. I faced the same problem with the function "integrate" which i applied to another function. How is this possible?
Does someone has another idea for this doubleintegral?
thanks for your help!
i want to translate my C++ code to wolfram, to improve my calcs.
C++ code
for(int i = 0; i < N - 1; ++i){
matrix[i][i] += L / 3 * uCoef - duCoef / 2 - (double)du2Coef/L;
matrix[i][i+1] += L / 6 * uCoef + duCoef / 2 + (double)du2Coef/L;
matrix[i+1][i] += L / 6 * uCoef - duCoef / 2 + (double)du2Coef/L;
matrix[i+1][i+1] += L / 3 * uCoef + duCoef / 2- (double)du2Coef/L;
}
all this coef are const, N - size of my matrix.
In[1]:= n = 4; uCoef = 2; duCoef = 3; du2Coef = 7; L = 11.;
matrix = Table[0, {n}, {n}];
For[i = 1, i < n, ++i,
matrix[[i, i]] += L/3*uCoef - duCoef/2 - du2Coef/L;
matrix[[i, i+1]] += L/6*uCoef - duCoef/2 - du2Coef/L;
matrix[[i+1, i]] += L/6*uCoef + duCoef/2 + du2Coef/L;
matrix[[i+1, i+1]] += L/3*uCoef - duCoef/2 + du2Coef/L];
matrix
Out[4]= {
{5.19697, 1.5303, 0, 0},
{5.80303, 11.6667, 1.5303, 0},
{0, 5.80303, 11.6667, 1.5303},
{0, 0, 5.80303, 6.4697}}
Each character that has been changed from your original is hinting there is a fundamental difference between C++ and Mathematica
You should use SparseArray for such banded arrays in mathematica:
n = 5; uCoef = 2; duCoef = 3; du2Coef = 7; L = 11.;
matrix = SparseArray[
{{1, 1} -> L/3*uCoef - duCoef/2 - du2Coef/L,
{i_ /; 1 < i < n, i_} -> -duCoef + 2 L uCoef/3 ,
{n, n} -> ( L/3 uCoef - duCoef/2 + du2Coef/L ),
Band[{1, 2}] -> L/6 uCoef - duCoef/2 - du2Coef/L,
Band[{2, 1}] -> L/6 uCoef + duCoef/2 + du2Coef/L}, {n, n}];
MatrixForm#matrix
Even if you insist on the For loop, initialize the matrix as :
matrix = SparseArray[{{_, _} -> 0}, {n, n}];
I am having an difficult time conceptualizing how to implement Strassen's version of this algorithm.
For background, I have the following pseudocode for the iterative version:
def Matrix(a,b):
result = []
for i in range(0,len(a)):
new_array = []
result.extend(new_array)
for j in range(0,len(b[0])):
ssum = 0
for k in range(0,len(a[0])):
ssum += a[i][k] * b[k][j]
result[i][j] = ssum
return result
I also have the following pseudocode for the initial divide and conquer version:
def recMatrix(x,y):
if(len(x) == 1):
return x[0] * y[0]
z = []
z[0] = recMatrix(x[0], y[0]) + recMatrix(x[1], y[2])
z[1] = recMatrix(x[0], y[1]) + recMatrix(x[1], y[3])
z[2] = recMatrix(x[2], y[0]) + recMatrix(x[3], y[2])
z[3] = recMatrix(x[2], y[1]) + recMatrix(x[3], y[3])
return z
So my question is, is my understanding of the divide and conquer method even correct, and if so, how can I modify to allow for Strassen's method? (This is not homework.)
(Specifically where I am having a hard time conceptualizing it is in the math on the entity itself prior (or after) the recursion. I.e. where P1 = A(F-H). If the recursion is actively multiplying the base elements, how is the strassen recursion taking care of the arithmetic (add and subtract) on the matrices? I have the following pseudocode to show where my brain is at:
def recMatrix(x,y):
if(len(x) == 1):
return x[0] * y[0]
z = []
p1 = recMatrix2(x[0], (y[1] - y[3]));
p2 = recMatrix2(y[3], (x[0] + x[1]));
p3 = recMatrix2(y[0], (x[2] + x[3]));
p4 = recMatrix2(x[3], (y[2] - y[0]));
p5 = recMatrix2((x[0] + x[3]), (y[0] + y[3]));
p6 = recMatrix2((x[1] - x[3]), (y[2] + y[3]));
p7 = recMatrix2((x[0] - x[3]), (y[0] + y[3]));
z[0] = p5 + p4 - p2 + p6;
z[1] = p1 + p2;
z[2] = p3 + p4;
z[3] = p1 + p5 - p3 - p7;
return z
The problem with the last piece of code is that it doesn't take the right submatrix. For example in p1 you want to take the upper left submatrix of x but you are using x[0] which is just the first row of x. You need some code that splits a matrix in 4 smaller ones. Or you can use a math library like numpy:
In [14]: from numpy import *
In [15]: x=range(16)
In [16]: x=reshape(x,(4,4))
In [17]: x
Out[17]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [18]: x[0:2,0:2]
Out[18]:
array([[0, 1],
[4, 5]])
In [19]: x[2:4,2:4]
Out[19]:
array([[10, 11],
[14, 15]])
Found an implementation that does what I'm looking for... namely, it specifically shows how/when to recurse: https://github.com/MartinThoma/matrix-multiplication/blob/master/Python/strassen-algorithm.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from optparse import OptionParser
from math import ceil, log
def read(filename):
lines = open(filename, 'r').read().splitlines()
A = []
B = []
matrix = A
for line in lines:
if line != "":
matrix.append(map(int, line.split("\t")))
else:
matrix = B
return A, B
def printMatrix(matrix):
for line in matrix:
print "\t".join(map(str,line))
def add(A, B):
n = len(A)
C = [[0 for j in xrange(0, n)] for i in xrange(0, n)]
for i in xrange(0, n):
for j in xrange(0, n):
C[i][j] = A[i][j] + B[i][j]
return C
def subtract(A, B):
n = len(A)
C = [[0 for j in xrange(0, n)] for i in xrange(0, n)]
for i in xrange(0, n):
for j in xrange(0, n):
C[i][j] = A[i][j] - B[i][j]
return C
def strassenR(A, B):
""" Implementation of the strassen algorithm, similar to
http://en.wikipedia.org/w/index.php?title=Strassen_algorithm&oldid=498910018#Source_code_of_the_Strassen_algorithm_in_C_language
"""
n = len(A)
# Trivial Case: 1x1 Matrices
if n == 1:
return [[A[0][0]*B[0][0]]]
else:
# initializing the new sub-matrices
newSize = n/2
a11 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
a12 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
a21 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
a22 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
b11 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
b12 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
b21 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
b22 = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
aResult = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
bResult = [[0 for j in xrange(0, newSize)] for i in xrange(0, newSize)]
# dividing the matrices in 4 sub-matrices:
for i in xrange(0, newSize):
for j in xrange(0, newSize):
a11[i][j] = A[i][j]; # top left
a12[i][j] = A[i][j + newSize]; # top right
a21[i][j] = A[i + newSize][j]; # bottom left
a22[i][j] = A[i + newSize][j + newSize]; # bottom right
b11[i][j] = B[i][j]; # top left
b12[i][j] = B[i][j + newSize]; # top right
b21[i][j] = B[i + newSize][j]; # bottom left
b22[i][j] = B[i + newSize][j + newSize]; # bottom right
# Calculating p1 to p7:
aResult = add(a11, a22)
bResult = add(b11, b22)
p1 = strassen(aResult, bResult) # p1 = (a11+a22) * (b11+b22)
aResult = add(a21, a22) # a21 + a22
p2 = strassen(aResult, b11) # p2 = (a21+a22) * (b11)
bResult = subtract(b12, b22) # b12 - b22
p3 = strassen(a11, bResult) # p3 = (a11) * (b12 - b22)
bResult = subtract(b21, b11) # b21 - b11
p4 =strassen(a22, bResult) # p4 = (a22) * (b21 - b11)
aResult = add(a11, a12) # a11 + a12
p5 = strassen(aResult, b22) # p5 = (a11+a12) * (b22)
aResult = subtract(a21, a11) # a21 - a11
bResult = add(b11, b12) # b11 + b12
p6 = strassen(aResult, bResult) # p6 = (a21-a11) * (b11+b12)
aResult = subtract(a12, a22) # a12 - a22
bResult = add(b21, b22) # b21 + b22
p7 = strassen(aResult, bResult) # p7 = (a12-a22) * (b21+b22)
# calculating c21, c21, c11 e c22:
c12 = add(p3, p5) # c12 = p3 + p5
c21 = add(p2, p4) # c21 = p2 + p4
aResult = add(p1, p4) # p1 + p4
bResult = add(aResult, p7) # p1 + p4 + p7
c11 = subtract(bResult, p5) # c11 = p1 + p4 - p5 + p7
aResult = add(p1, p3) # p1 + p3
bResult = add(aResult, p6) # p1 + p3 + p6
c22 = subtract(bResult, p2) # c22 = p1 + p3 - p2 + p6
# Grouping the results obtained in a single matrix:
C = [[0 for j in xrange(0, n)] for i in xrange(0, n)]
for i in xrange(0, newSize):
for j in xrange(0, newSize):
C[i][j] = c11[i][j]
C[i][j + newSize] = c12[i][j]
C[i + newSize][j] = c21[i][j]
C[i + newSize][j + newSize] = c22[i][j]
return C
def strassen(A, B):
assert type(A) == list and type(B) == list
assert len(A) == len(A[0]) == len(B) == len(B[0])
nextPowerOfTwo = lambda n: 2**int(ceil(log(n,2)))
n = len(A)
m = nextPowerOfTwo(n)
APrep = [[0 for i in xrange(m)] for j in xrange(m)]
BPrep = [[0 for i in xrange(m)] for j in xrange(m)]
for i in xrange(n):
for j in xrange(n):
APrep[i][j] = A[i][j]
BPrep[i][j] = B[i][j]
CPrep = strassenR(APrep, BPrep)
C = [[0 for i in xrange(n)] for j in xrange(n)]
for i in xrange(n):
for j in xrange(n):
C[i][j] = CPrep[i][j]
return C
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-i", dest="filename", default="2000.in",
help="input file with two matrices", metavar="FILE")
(options, args) = parser.parse_args()
A, B = read(options.filename)
C = strassen(A, B)
printMatrix(C)