I have a really simple problem but can't get it done.
I want to produce a linspaced sequence between two values of an anonymous function. If I do it with values its no problem and looks like this
n = 5;
left = 1;
right = 3;
y = zeros(n, 1);
x = linspace(left, right, n)';
q = zeros(2*n, 1);
q(1:2:end) = x
q(2:2:end) = y
But the same thing is not possible with anonymous functions as boundaries. My attempt looks like this but I would really appreciate a better solution
n = 5;
left = #(t) 0.5 * t;
right = #(t) 2 * t^2 + 5;
diff = #(t) right(t) - left(t);
q = #(t) [];
for i = 1:n
q = #(t) [q(t) i*diff(t)/n 0*t];
end
q(0.5)
I hope you can help me, thanks in advance!
Thanks to #Adiel I made the following answer
function [Q] = reference_configuration(left, right, n, t)
l = left(t);
r = right(t);
diff = r - l;
x = linspace(0, diff, n);
y = zeros(1, n);
q = zeros(1, 2*n);
q(1:2:end) = x;
q(2:2:end) = y;
end
Maybe it helps someone. Thank you!
Related
What is the issue with my code? It only passes 6 of my testcases and I am sure I am making some mistake but I am not able to figure it out. Also if someone could help me understand the space and time complexity of this code I would be more than grateful. Thank You.
def arrayManipulation(n, queries):
arr = [0]*(n+2)
for q in queries:
print(q)
a = q[0]
b = q[1]
k = q[-1]
arr[a] += k
arr[b+1] -= k
print(arr)
max_sum = temp = 0
for i in arr:
print(i)
temp += i
print("TEMP:",temp)
max_sum = max(max_sum,temp)
print("MAXSUM:",max_sum)
return max_sum
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
nm = input().split()
n = int(nm[0])
m = int(nm[1])
queries = []
for _ in range(m):
queries.append(list(map(int, input().rstrip().split())))
result = arrayManipulation(n, queries)
fptr.write(str(result) + '\n')
fptr.close()
The problem is within following part of your code:
max_sum = temp = 0
for i in arr:
print(i)
temp += i
print("TEMP:",temp)
max_sum = max(max_sum,temp)
print("MAXSUM:",max_sum)
return max_sum
max_sum and temp are both integer type which can only handle number up to 2147483647 before overflow. But the question specify that k is within range of 0 to 10^9, when those number adds up it will easily overflow. Try to use long instead of int.
I often struggle with slow Matlab processing due to high numbers of for loops.
Maybe you can help me with this example, which would help me in other cases as well: Is it possible to completely transfer it to matrices?
R = [1 2 3; 1 2 3; 1 2 3];
u1 = 200; u2 = 300; v1 = 100; v2 = 222; w1 = 123; w2 = 312;
px = 20; py = 30; pz = 25;
a = 20; b = 30; c = 25;
Ellipse = zeros(500,600,500)
for i=u1:u2
for j=v1:v2
for k=w1:w2
x=[i-px;j-py;k-pz];
x=R*x;
if (x(1)/a)^2+(x(2)/b)^2+(x(3)/c)^2<1
Ellipse(i,j,k)=1;
end
end
end
end
Here's one approach that runs about 2 orders of magnitude faster
R = [1 2 3; 1 2 3; 1 2 3];
u1 = 200; u2 = 300; v1 = 100; v2 = 222; w1 = 123; w2 = 312;
px = 20; py = 30; pz = 25;
a = 20; b = 30; c = 25;
Ellipse = zeros(500,600,500);
% Create mesh of points to process
vx = (u1:u2) - px;
vy = (v1:v2) - py;
vz = (w1:w2) - pz;
[X,Y,Z] = meshgrid(vx, vy, vz);
% Compute R*x
V = [X(:)'; Y(:)'; Z(:)'];
V = R * V;
% Divide by ellipse axes
M = diag([1/a, 1/b, 1/c]);
V = M * V;
% Determine if norm criteria is met
index = norm(V') < 1;
Ellipse(X(index), Y(index), Z(index)) = 1;
Agree with #Dan, a smaller working example would make it easier to test.
If you are doing more than simple mathematical operations matrices can be tricky.
Here you can (should) reduce the size of Ellipse because you are not using most of its entries.
All you need is (101,123,190) and things will be much faster, especially the way you are accessing the matrix entries, remember MATLAB will eventually store the matrix as just an array.
#dpmcmlxxvi Thank you very much for the answer. At first, sorry for the large example. I used your answer with some modification as norm(XY) did not work for me.(smaller example and valueas adapted to run properly)
R = [1 2 3; 1 2 3; 1 2 3];
u1 = 50; u2 = 90; v1 = 20; v2 = 50; w1 = 30; w2 = 60;
px = 60; py = 25; pz = 50;
a = 10; b = 20; c = 15;
Ellipse = zeros(100,200,100);
% Create mesh of points to process
vx = (u1:u2) - px;
vy = (v1:v2) - py;
vz = (w1:w2) - pz;
[X,Y,Z] = meshgrid(vx, vy, vz);
% Compute R*x
V = [X(:)'; Y(:)'; Z(:)'];
V = R * V;
% Divide by ellipse axes
M = diag([1/a, 1/b, 1/c]);
V = M * V;
% Apply criteria
Vsq = V.*V;
crit = Vsq(1,:)+Vsq(2,:)+Vsq(3,:);
% Look for indices in the meshgrid fullfilling criteria
xe = X(find(crit<1));
ye = Y(find(crit<1));
ze = Z(find(crit<1));
xi = ceil(abs(xe+px));
yi = ceil(abs(ye+py));
zi = ceil(abs(ze+pz));
% Set values at correpsonding indices to 1
linind = sub2ind(size(Ellipse),xi,yi,zi);
Ellipse(linind) = 1;
It works fine and all for loops have been removed.
b_k = 1;
while (b_k <= iv0[1]) {
h = vplus_data[0];
u1 = vmax->data[(int)((1.0 + (double)k) + 1.0) - 1];
if ((h <= u1) || rtIsNaN(u1)) {
minval_data_idx_0 = h;
} else {
minval_data_idx_0 = u1;
}
b_k = 2;
}
b_k = 1;
while (b_k <= iv0[1]) {
h = vmin->data[(int)((1.0 + (double)k) + 1.0) - 1];
if ((h >= minval_data_idx_0) || rtIsNaN(minval_data_idx_0)) {
} else {
h = minval_data_idx_0;
}
vplus_data[0] = h;
b_k = 2;
}
this code is compared to min function to get the minimum value for h or u1,
can anyone tell me why matlab generate such syntax? why is the while loop, although I dont see any changes inside the while block!
matlab code
v(k+1) = max(vmin(k+1), min(vplus, vmax(k+1)));
notice there are two loops for max min function
I can't explain why the generated code ends up like that, but it must have something to do with how you wrote your Matlab code. It looks strange, but if it works then it probably doesn't matter.
If you're curious about the generator, start from something very simple and watch how the generated code changes as your code gets more complex. Try variations like these:
z = min(x, y);
z = max(w, min(x, y));
for i = 1:length(v)
z(i) = max(w, min(v(i), y));
end
Keep on modifying the test code a bit at a time to make it like the code that prompted this question and maybe you'll discover exactly what triggers the result you're seeing.
I'm trying to implement a simple script performing a PI control for a cruise control application, but I'm founding some problems with the integral part. Here is my code:
function [] = PI_cruisecontrol()
clc; close all;
t0 = 0; tfinal = 50; dt = 0.001; % time parameters
r = 10; % reference of 10 m/s
m = 1000; % mass
b = 50; % friction coeff. (depends on v)
yp = zeros(tfinal/dt,1); t = yp; % initialize speed and time array
Ki = 40; % integrarl constant
Kp = 800; % proportional constant
int = 0; % itinialize int error
% CONTROL LOOP (Forward-Euler integrator is used to solve the ODE)
for i=t0+2:tfinal/dt
err = r-yp(i-1); % update error
int = int+err; % integral term
u = (Kp*err)+(Ki*int*dt); % action of control
yp(i) = yp(i-1)+((-b*yp(i)/m) + (u/m))*dt; % solve ode for speed
t(i) = t(i)+dt*i; % log the time
end
% Results
figure(1)
plot(t,yp)
title ('Step Response')
xlabel('Time (seconds)')
ylabel('Amplitud')
axis([0 20 0 12])
hold on
reference = ones(tfinal/dt,1)*10;
plot(t,reference,':')
end
And this is how it should be, using predefinided matlab functions:
function [] = PI_cruisecontrol2()
m = 1000;
b = 50;
r = 10;
s = tf('s');
P_cruise = 1/(m*s + b);
Kp = 800;
Ki = 40;
C = pid(Kp,Ki);
T = feedback(C*P_cruise,1);
t = 0:0.1:20;
step(r*T,t)
axis([0 20 0 12])
end
What am I doing wrong in my code?
Thanks!
I managed to fix the problem, working with float variables instead of arrays. Moreover, I added the derivative term (although for this first order problem was not necessary)
Here I left the code:
function [] = aFortran_PI()
clc; close all;
r = 10; % reference of 10 m/s
m = 1000; % mass
b = 50; % friction coeff. (depends on v)
yp = 0; % init response
Kp = 800; % proportional constant
Ki = 40; % proportional constant
Kd = 0; % derivative term is not necessary in this problem
previous_error = 0;
integral = 0;
dt = 0.001;
% CONTROL LOOP
for i=1:20000
error = r-yp; % update error
integral = integral + error*dt; % integral term
derivative = (error-previous_error)/dt; % derivative term
u = Kp*error+Ki*integral+Kd*derivative; % action of control
yp = yp+(-b*yp/m + u/m)*dt % solve ode for velocity
end
end
Instead of
cardNumber = j+1;
deck[i][j] = cardNumber;
theDeck[k] = cardNumber;
is it valid to just say
deck[i][j] = theDeck[k] = cardNumber;
to assign cardNumber to both deck and theDeck at the same time??
Yes, it is. The assignment operator returns a value.
Yes, it's an expression and its value is the right side of the assignment. Note that this comes also from the associativity of = (right-to-left), which makes this:
x = y = z
Equivalent to:
x = (y = z)
But not:
(x = y) = z /* wouldn't work */
So you can go even further and write:
theDeck[k] = deck[i][j] = cardNumber = j+1;
Yes it is; it is like this:
deck[i][j] = (theDeck[k] = cardNumber);