Ιn two Vectors V1(x11, x12) και V2(x21,x22) we can compute their inner product as V1 • V2.= (x11* x21 + x12 * x22 ).
I try to compute minimum inner product as (x1ix2j|i-j|, i.j the places of coordinates at V1, V2.
Every cooedinate is used once in a sum condition.
I TRIED THIS:
int : vlen;
set of int : LEN = 1..vlen;
set of int : VECS = 1..2;
array[VECS,LEN] of -25..25 : vector;
var -600..700 : sumTotal;
constraint exists(i,j,k,l in LEN where i!=k \/ j!=l)(
exists(v,v2 in VECS)(sumTotal=(vector[v,i] * vector[v2,j] * abs(i-j)+vector[v,k] * vector[v2,l] * abs(k-l)
)));
solve minimize sumTotal;
output ["vector1=["]++[" \(vector[1,j])"|j in LEN]++[" ];\nvector2=["]++[" \(vector[2,j])"|j in LEN]++[" ];\nsumTotal=\(sumTotal);"]
for
vlen = 2;
vector = [|-2,3|-4,5|];
i expect:
vector1 = [-2, 3];
vector2 = [-4, 5];
sumTotal = -22;
----------
==========
but i take:
vector1=[ -2 3 ];
vector2=[ -4 5 ];
sumTotal=-40;
----------
==========
I'm afraid I don't understand the meaning of your model, but it does contain some errors in the constraint that should be easy to fix:
If an array is indexed by VEC, LEN, then the second index should always be part of that set.
sum is it's own looping structure; it doesn't need an forall expression.
The resulting constraint would be:
constraint sumTotal = sum(i,j in LEN)(
vector[1,i] * vector[2,j] * abs(i,j)
);
This still leaves a rather strange model, so you might want to take a look at the following:
sumTotal is your only variable, but it's defined by parameters. It cannot be optimised as it only has 1 solution.
Should i and j be able to take the same value? If not, then you should use i,j in LEN where i < j.
Do you expect any results other than sumTotal?
Related
Assume I have a 50x1 cell(say Q) with column matrices of varying dimensions (say 1568936x1 , 88x1,5040x1 ) etc
losing values isn't an issue. I need all the matrices inside the cell to be divisible by said number (say 500) so like 1568500x1 , 5000x1 skipping over 88x1 etc.
Currently I have:
z=cell(length(Q),1)
for p=1:length(z)
n=length(Q{p})
for w=1:length(z)
if n-mod(length(Q{w}),500)<500
w=w+1;
else
o=length(Q{w}-mod(length(Q{w}),500));
for k=1:length(z)
z=Q{w}((1:o));
end
end
end
end
but when I reach the 88x1 matrix it throws a dimensions exceeded error although I think I have covered that with the if condition where it should skip the matrix and move on to the next cell.
This should work fine:
Q = {
rand(58,1);
rand(168,1);
rand(33,1);
rand(199,1);
rand(100,1)
};
Q_len = numel(Q);
K = 50;
Z = cell(Q_len,1);
for i = 1:Q_len
Qi = Q{i};
Qi_len = numel(Qi);
k = floor(Qi_len / K) * K
Z{i} = Qi(1:k);
end
Given the starting vectors (shortened down in order to avoid excessive overloads), the final output Z is:
>> cellfun(#numel,Z)
ans =
50
150
0
150
100
If you want a shorter, one-liner version, here is one:
Q = {
rand(58,1);
rand(168,1);
rand(33,1);
rand(199,1);
rand(100,1)
};
K = 50;
Z = cellfun(#(x)x(1:(floor(numel(x)/K)*K)),Q,'UniformOutput',false);
I have a Python-Code and want to rewrite it in Octave, but I meet so many problems during the converting. I found a solution for some of them and some of them still need your help. Now i would start with this part of the code :
INVOLUTE_FI = 0
INVOLUTE_FO = 1
INVOLUTE_OI = 2
INVOLUTE_OO = 3
def coords_inv(phi, geo, theta, inv):
"""
Coordinates of the involutes
Parameters
----------
phi : float
The involute angle
geo : struct
The structure with the geometry obtained from get_geo()
theta : float
The crank angle, between 0 and 2*pi
inv : int
The key for the involute to be considered
"""
rb = geo.rb
ro = rb*(pi - geo.phi_fi0 + geo.phi_oo0)
Theta = geo.phi_fie - theta - pi/2.0
if inv == INVOLUTE_FI:
x = rb*cos(phi)+rb*(phi-geo.phi_fi0)*sin(phi)
y = rb*sin(phi)-rb*(phi-geo.phi_fi0)*cos(phi)
elif inv == INVOLUTE_FO:
x = rb*cos(phi)+rb*(phi-geo.phi_fo0)*sin(phi)
y = rb*sin(phi)-rb*(phi-geo.phi_fo0)*cos(phi)
elif inv == INVOLUTE_OI:
x = -rb*cos(phi)-rb*(phi-geo.phi_oi0)*sin(phi)+ro*cos(Theta)
y = -rb*sin(phi)+rb*(phi-geo.phi_oi0)*cos(phi)+ro*sin(Theta)
elif inv == INVOLUTE_OO:
x = -rb*cos(phi)-rb*(phi-geo.phi_oo0)*sin(phi)+ro*cos(Theta)
y = -rb*sin(phi)+rb*(phi-geo.phi_oo0)*cos(phi)+ro*sin(Theta)
else:
raise ValueError('flag not valid')
return x,y
def CVcoords(CVkey, geo, theta, N = 1000):
"""
Return a tuple of numpy arrays for x,y coordinates for the lines which
determine the boundary of the control volume
Parameters
----------
CVkey : string
The key for the control volume for which the polygon is desired
geo : struct
The structure with the geometry obtained from get_geo()
theta : float
The crank angle, between 0 and 2*pi
N : int
How many elements to include in each entry in the polygon
Returns
-------
x : numpy array
X-coordinates of the outline of the control volume
y : numpy array
Y-coordinates of the outline of the control volume
"""
Nc1 = Nc(theta, geo, 1)
Nc2 = Nc(theta, geo, 2)
if CVkey == 'sa':
r = (2*pi*geo.rb-geo.t)/2.0
xee,yee = coords_inv(geo.phi_fie,geo,0.0,'fi')
xse,yse = coords_inv(geo.phi_foe-2*pi,geo,0.0,'fo')
xoie,yoie = coords_inv(geo.phi_oie,geo,theta,'oi')
xooe,yooe = coords_inv(geo.phi_ooe,geo,theta,'oo')
x0,y0 = (xee+xse)/2,(yee+yse)/2
beta = atan2(yee-y0,xee-x0)
t = np.linspace(beta,beta+pi,1000)
x,y = x0+r*np.cos(t),y0+r*np.sin(t)
return np.r_[x,xoie,xooe,x[0]],np.r_[y,yoie,yooe,y[0]]
https://docs.scipy.org/doc/numpy/reference/generated/numpy.r_.html I just don´t understand the last Output, and I am still confuse what´s mean _r here, and how can I write it by Octave?....I read what is written in the link, but it still not clear for me.
return np.r_[x,xoie,xooe,x[0]], np.r_[y,yoie,yooe,y[0]]
The function returns 2 values, both arrays created by np.r_.
np.r_[....] has indexing syntax, and ends up being translated into a function call to the np.r_ object. The result is just the concatenation of the arguments:
In [355]: np.r_[1, 3, 6:8, np.array([3,2,1])]
Out[355]: array([1, 3, 6, 7, 3, 2, 1])
With the [] notation it can accept slice like objects (6:8) though I don't see any of those here. I'd have to study the rest of the code to identify whether the other arguments are scalars (single values) or arrays.
My Octave is rusty (though I could experiment with the conversion).
t = np.lispace... # I think that exists in Octave, a 1000 values
x = x0+r*np.cos(t) # a derived array of 1000 values
xoie one of the values returned by coords_inv; may be scalar or array. x[0] the first value of x. So the r_ probably produces a 1d array made up of x, and the subsequent values.
I've noticed that matlab builtin functions can handle either scalar or vector parameters. Example:
sin(pi/2)
ans =
1
sin([0:pi/5:pi])
ans =
0 0.5878 0.9511 0.9511 0.5878 0.0000
If I write my own function, for example, a piecewise periodic function:
function v = foo(t)
t = mod( t, 2 ) ;
if ( t < 0.1 )
v = 0 ;
elseif ( t < 0.2 )
v = 10 * t - 1 ;
else
v = 1 ;
end
I can call this on individual values:
[foo(0.1) foo(0.15) foo(0.2)]
ans =
0 0.5000 1.0000
however, if the input for the function is a vector, it is not auto-vectorized like the builtin function:
foo([0.1:0.05:0.2])
ans =
1
Is there a syntax that can be used in the definition of the function that indicates that if a vector is provided, a vector should be produced? Or do builtin functions like sin, cos, ... check for the types of their input, and if the input is a vector produce the same result?
You need to change your syntax slightly to be able to handle data of any size. I typically use logical filters to vectorise if-statements, as you're trying to do:
function v = foo(t)
v = zeros(size(t));
t = mod( t, 2 ) ;
filt1 = t<0.1;
filt2 = ~filt1 & t<0.2;
filt3 = ~filt1 & ~filt2;
v(filt1) = 0;
v(filt2) = 10*t(filt2)-1;
v(filt3) = 1;
In this code, we've got three logical filters. The first picks out all elements such that t<0.1. The second picks out all of the elements such that t<0.2 that weren't in the first filter. The final filter gets everything else.
We then use this to set the vector v. We set every element of v that matches the first filter to 0. We set everything in v which matches the second filter to 10*t-1. We set every element of v which matches the third filter to 1.
For a more comprehensive coverage of vectorisation, check the MATLAB help page on it.
A simple approach that minimizes the number of operations is:
function v = foo(t)
t = mod(t, 2);
v = ones(size(t)) .* (t > 0.1);
v(t < 0.2) = 10*t(t < 0.2) - 1;
end
If the vectors are large, it might be faster to do ind = t < 0.2, and use that in the last line. That way you only search through the array once. Also, the multiplication might be substituted by an extra line with logical indices.
I repeatedly hit the same problem, thus I was looking for a more generic solution and came up with this:
%your function definition
c={#(t)(mod(t,2))<0.1,0,...
#(t)(mod(t,2))<0.2,#(t)(10 * t - 1),...
true,1};
%call pw which returns the function
foo=pw(c{:});
%example evaluation
foo([0.1:0.05:0.2])
Now the code for pw
function f=pw(varargin)
for ip=1:numel(varargin)
switch class(varargin{ip})
case {'double','logical'}
varargin{ip}=#(x)(repmat(varargin{ip},size(x)));
case 'function_handle'
%do nothing
otherwise
error('wrong input class')
end
end
c=struct('cnd',varargin(1:2:end),'fcn',varargin(2:2:end));
f=#(x)pweval(x,c);
end
function y=pweval(x,p)
todo=true(size(x));
y=x.*0;
for segment=1:numel(p)
mask=todo;
mask(mask)=logical(p(segment).cnd(x(mask)));
y(mask)=p(segment).fcn(x(mask));
todo(mask)=false;
end
assert(~any(todo));
end
I'm trying to convert fortran code to matlab, I was wondering if someone could help me with this subroutine.
I'm specifically asking what does the colon mean in these lines?
SUB Taper (a(), co(), Re(), Im())
FOR nd = 0 TO 31
n1 = 8 * nd: n2 = a(n1 + 4): n1 = a(n1): n0 = 255 - nd
a = .5 * (1 - co(n1)): b = .5 * (1 - co(n2))
Re(nd) = a * Re(nd): Im(nd) = b * Im(nd)
Re(n0) = b * Re(n0): Im(n0) = a * Im(n0)
NEXT
END SUB
The code fragment in your question has not a valid Fortran syntax. It is VB and colon is used as statement separator
Fortran90 and up allow you to access a single array value given an index, and access a subarray given a range of indices separated by a colon.
Fortran = Beginning : End : Increment
MatLab = Beginning : Increment : End
There is a table at the bottom of page 5 in this doc that shows the Fortran and MatLab equivalents.
The code is for MATLAB and i want to understand what exactly they are trying to do. I m new to matlab so need some advice. Please Help
function [key] = keyGen(n)
n = n*8;
% n = 2048*2048*16;
% n = 24 * 24 * 8;
bin_x = zeros(n,1,'uint8');
r = 3.9999998;
bin_x_N_Minus_1 = 0.300001;
x_N = 0;
tic
for ind = 2 : n
x_N = 1 - 2* bin_x_N_Minus_1 * bin_x_N_Minus_1;
if (x_N > 0.0)
bin_x(ind-1) = 1;
end
bin_x_N_Minus_1 = x_N;
end
toc
%save bin_sec bin_x;
t = uint8(0);
key = zeros(n/8,1,'uint8');
for ind1 = 1 : n/8
for ind2 = 1 : 8
key(ind1) = key(ind1) + bin_x(ind2*ind1)* 2 ^ (ind2-1);
end
end
The parameter n is the number of bytes in the key. n*8 is to convert that into a number of bits. bin_x is used to store the binary representation of the key. bin_x_N_Minus_1 is the value which we use to calculate the next bit.
In the first for loop, we loop through the bits in the key (the first bit is always a 0). We calculate x_N using that formula (bin_x_N_Minus_1 is the previous value of x_N). If x_N is positive, the corresponding bit in the key is 1, otherwise it is a zero.
tic and toc are used to time how long this for loop takes.
The second for loop converts the bits of the key into bytes, and stores them in output array, key. The Kth entry in key is the 8 bit number represented by taking every (N/8)th entry in bin_x, starting from K.
The variables r and t are unused.