How to increase time by 1s and replace old DT_i with the new one - matlab

I'm trying to calculate the DT value from a model I set up on Sim4Life. Firstly, i'd like to say that I am a complete beginner and I am trying to understand how programming works in general.
Now, I have a function with some constants and two variables, the one being time Dt (starting from 1 sec to 900 secs) and the other being the initial DT_i value. I want to calculate the increase of temperature for every second and create a loop that replaces the DT_i value with the DT_1_i value and also calculates the increased temperature DT_i_1. The function looks like this: DT_1_i=DT_i+Dt.
I know it is a very simple problem but I couldn't work my way through other similar questions. Any help would be appreciated.

Temperature variation:
You need initial temperature variation , I used 0
T(i+1) stands for Next temperature variation
T(i) stands for present temperature variation
i stands for time step, dt
Read through comment in my code
Time
Use for loop to set the time for i = 1 : 900 %Temperature increase end
i =1:900 just means
first run use time = 1s,
second run time = 1+1 = 2
so on till 900
The code is as follow
% Initial Temperature variation is set to zero, unless you have some data
d = 1.3;
c = 3.7;
S_i = 3*10^3;
t_reg = 900;
%Time
t = 1:900;
% Length oftime to help me know the size of the variable needed to
% initialize
l = length(t);
% Initialize variable that used to store DT it helps speed up
% comutation
% Initial Temperature variation is set to zero, unless you have some data
DT = zeros(1, l);
for i = 1:900
% the value of i represent dt, first run i = 1, dt = 1, second run
% i = 2 and dt = 2 so on
if i == 900
%do nothing already reached the last index 900, i+1 = 901 will be
%out of range
else
DT(i+1) = DT(i) + (i./t_reg).*(d.*sqrt(c*S_i)-DT(i+1));
end
end

Related

Velocity per second for a free falling object

Edit: MATLAB.
I'm trying to create a function which returns an array of the velocity per second for a free falling object. The input argument for the function is the height h. Also, if the object hits the ground before 1 second, it should return the velocity for the time it hits the ground.
Example: If the object falls from 80 meters, the function should return
v =
9.8 19.6 29.4 39.2
My attempt looks like this:
function freefall(h)
g = 9.8; % gravity acceleration
h_t = linspace(0,h); % the height should start from 0 to input height h
t = sqrt(2.*h_t/g); % time for the free fall
n=0;
if t < 1
velocity = sqrt(2*g*h)
disp(velocity)
else
for time = n+1 % An attempt to try making t into integers(tried floor(t) but didn't work)
v = g.*time
while time <= t % Don't want the time to exceed the amount of time it takes for object to land
disp(v)
end
end
end
end
The output just becomes v = 9.82, and I'm out of ideas to try and make this work.
Is this all you are trying to do?
tfinal = sqrt(2*h/g); % time to fall to ground
if tfinal < 1
velocity = g*tfinal; % velocity when hitting ground is less than 1 sec
else
velocity = g*(1:tfinal); % velocities at 1 sec intervals, not including hitting ground
end
If you always wanted to include the final velocity in the output, you could do this instead:
tfinal = sqrt(2*h/g); % time to fall to ground
t = 1:tfinal; % range of integer times spaced by 1 sec
if tfinal ~= fix(tfinal) % if final time is not an integer
t = [t,tfinal]; % append final time to time array
end
velocity = g*t; % velocities at integer times plus final time
I don't have matlab or scilab at the moment so I fiddled around using online scilab to write some test code. Here what I came up with:
function freefall(h)
g = 9.8;
t = floor(sqrt(2*h/g));
if t < 1
t = 1;
t_mat = linspace(1, t, t);
t_mat = g * t_mat;
return t_mat;
end
You can then call that function this way:
disp(freefall(80));
What's missing on your code is rather to limit the increments of linspace, for some odd reason you tried to compare a vector to a scalar (that if t < 1 on your code), and finally your function did not return an answer, instead it prints it.
¯\(ツ)/¯ correct me if I'm wrong, I haven't write any matlab code for like 6 years.
Note: that online scilab doesn't seem to support function so, you have to use bare code without the function block. You can replace that return with disp(t_mat).

Repeated option pricing with Sobol Sequence (Matlab)

Trying to calculate the variance of a European option using repeated trial (instead of 1 trial). I want to compare the variance using the standard randn function and the sobolset. I'm not quite sure how to draw repeated samples from the latter.
Generating from randn is easy:
num_steps = 100;
num_paths = 10;
z = rand(num_steps, mum_paths); % 100 paths, for 10 trials
Once I have this, I can loop through all the 10 columns of the z matrix, and can also repeat the experiment many times, as the randn function will provide a new random variable set everytime.
for exp_num = 1: 20
for col = 1: 10
price_vec = z(:, col);
end
end
I'm not quite sure how to do this with the sobolset. I understand I can create a matrix of dimensions to start with (say 100* 10). I can loop through as above through all the columns for the first experiment. However, when I try the next experiment (#2), the loop starts from the beginning and all the numbers are the same. Meaning I don't get any variation in my pricing. It seems I will need to find a way to randomize the column selection at the start of every experiment number. Is there a better way to do this??
data1 = sobolset(1000, 'Skip', 1000, 'Leap', 100)
data2 = net(test1, 10)
for exp_num = 1: 20
% how do I change the start of the column selection here, so that the next data3 is different from %the one in the previous exp_num?
for col = 1:10
data3(:, col) = data(2:, col)
% perform calculations
end
end
I hope this is making sense....
Thanks for the help!
Update: 8/21
I tried the following:
num_runs = 100
num_samples = 1000
for j = 1: num_runs
for i = 1 : num_samples
sobol_set = sobolset(num_samples,'Skip',j*50,'Leap',1e2);
sobol_set = net(sobol_set, 5);
sobol_seq = sobol_set(:, i)';
z_uncorr = norminv(sobol_seq, 0, 1)
% do pricing with z_uncorr through some function F
end
end
After generating 100 prices (through some function F, mentioned above), I find that the variance of the 100 prices is higher than that I get from the standard pseudo random numbers. This should not be the case. I think I'm still not sampling correctly from the sobolset. Any advice would be appreciated.

Getting the correct output units from the PLOMB (Lomb-scargle periodogram) function

I am trying to analyze timeseries of wheel turns that were sampled at 1 minute intervals for 10 days. t is a 1 x 14000 array that goes from .1666 hours to 240 hours. analysis.timeseries.(grp).(chs) is a 1 x 14000 array for each of my groups of interest and their specific channels that specifize activity at each minute sampled. I'm interested in collecting the maximum power and the frequency it occurs at. My problem is I'm not sure what units f is coming out in. I would like to have it return in cycles per hour and span to a maximum period of 30 hours. I tried to use the Galileo example in the documentation as a guide, but it didn't seem to work.
Below is my code:
groups = {'GFF' 'GMF' 'SFF' 'SMF'};
chgroups = {chnamesGF chnamesGM chnamesSF chnamesSM};
t1 = (t * 3600); %matlab treats this as seconds so convert it to an hour form
onehour = seconds(hours(1));
for i = 1:4
grp = groups{1,i};
chn = chgroups{1,i};
for channel = 1:length(chn)
chs = chn{channel,1};
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t, 30/onehour,'normalized');
analysis.pxx.(grp).(chs) = pxx;
analysis.f.(grp).(chs) = f;
analysis.lsp.power.(grp).(chs) = max(pxx);
[row,col,v] = find(analysis.pxx.(grp).(chs) == analysis.lsp.power.(grp).(chs));
analysis.lsp.tau.(grp).(chs) = analysis.f.(grp).(chs)(row);
end
end
Not really an answer but it is hard to put a image in a comment.
Judging by this (plomb manual matlab),
I think that pxx is without dimension as for f is is the frequency so 1/(dimension of t) dimension. If your t is in hours I would say h^-1.
So I'd rather say try
[pxx,f]= plomb(analysis.timeseries.(grp).(chs),t*30.0/onehour,'normalized');

How can I rearrange a list of numbers so that every N numbers is nonrepeating?

So I have a list of 190 numbers ranging from 1:19 (each number is repeated 10 times) that I need to sample 10 at a time. Within each sample of 10, I don't want the numbers to repeat, I tried incorporating a while loop, but computation time was way too long. So far I'm at the point where I can generate the numbers and see if there are repetitions within each subset. Any ideas?
N=[];
for i=1:10
N=[N randperm(19)];
end
B=[];
for j=1:10
if length(unique(N(j*10-9:j*10)))<10
B=[B 1];
end
end
sum(B)
Below is an updated version of the code. this might be a little more clear in showing what I want. (19 targets taken 10 at a time without repetition until all 19 targets have been repeated 10 times)
nTargs = 19;
pairs = nchoosek(1:nTargs, 10);
nPairs = size(pairs, 1);
order = randperm(nPairs);
values=randsample(order,19);
targs=pairs(values,:);
Alltargs=false;
while ~Alltargs
targs=pairs(randsample(order,19),:);
B=[];
for i=1:19
G=length(find(targs==i))==10;
B=[B G];
end
if sum(B)==19
Alltargs=true;
end
end
Here are some very simple steps to do this, basically you just shuffle the vector once, and then you grab the last 10 unique values:
v = repmat(1:19,1,10);
v = v(randperm(numel(v)));
[a idx]=unique(v);
result = unique(v);
v(idx)=[];
The algorithm should be fairly efficient, if you want to do the next 10, just run the last part again and combine the results into a totalResult
You want to sample the numbers 1:19 randomly in blocks of 10 without repetitions. The Matlab function 'randsample' has an optional 'replacement' argument which you can set to 'false' if you do not want repetitions. For example:
N = [];
replacement = false;
for i = 1:19
N = [N randsample(19,10,replacement)];
end
This generates a 19 x 10 matrix of random integers in the range [1,..,19] without repetitions within each column.
Edit: Here is a solution that addresses the requirement that each of the integers [1,..,19] occurs exactly 10 times, in addition to no repetition within each column / sample:
nRange = 19; nRep = 10;
valueRep = true; % true while there are repetitions
nLoops = 0; % count the number of iterations
while valueRep
l = zeros(1,nRep);
v = [];
for m = 1:nRep
v = [v, randperm(nRange,nRange)];
end
m1 = reshape(v,nRep,nRange);
for n = 1:nRep
l(n) = length(unique(m1(:,n)));
end
if all(l == nRep)
valueRep = false;
end
nLoops = nLoops + 1;
end
result = m1;
For the parameters in the question it takes about 300 iterations to find a result.
I think you should approach this constructively.
It's easy to initially find a 19 groups that fulfill your conditions just by rearranging the series 1:19: series1 = repmat(1:19,1,10); and rearranged= reshape(series1,10,19)
then shuffle the values
I would select two random columns copy them and switch the values at two random positions
then make a test if it fulfills your condition - like: test = #(x) numel(unique(x))==10 - if yes replace your columns
just keep shuffling till your time runs out or you are happy
of course you might come up with more efficient shuffling or testing
I was given another solution through the MATLAB forum that works pretty well (Credit to Niklas Nylen over on the MATLAB forum). Computation time is pretty low too. It basically shuffles the numbers until there are no repetitions within every 10 values. Thanks all for your help.
y = repmat(1:19,1,10);
% Run enough iterations to get the output random enough, I selected 100000
for ii = 1:100000
% Select random index
index = randi(length(y)-1);
% Check if it is allowed to switch places
if y(index)~=y(min(index+10, length(y))) && y(index+1)~=y(max(1,index-9))
% Make the switch
yTmp = y(index);
y(index)=y(index+1);
y(index+1)=yTmp;
end
end

Five dimensional matrix manipulation

I have made the following changes to the code but still get the "Index exceeds matrix dimensions" error on the line where the "if statement" is called and I am for looping the "h" starting from 2:25. I still have net figured out how I can use an element from the previous dimension in the current dimension equation expression
number_of_days = 3;
number_of_hours = 24*number_of_days;
number_panels = 1:5;
for idx_number_panels = 1:length(number_panels) % range of PV panel units examined
for number_turbines = 0:1 % range of wind turbine units examined
for number_batteries = 1:2 % range of battery units examined
for h=2:25 %# hours
battery_capacity(:,:,:,1,1) = max_battery_capacity*number_batteries;
for d = 1:number_of_days %# which day
n = h + 24*(d-1);
if (max_battery_capacity*number_batteries) - (battery_capacity(idx_number_panels, number_turbines+1 ,number_batteries, h-1,d)*number_batteries) >0
storage_availability(idx_number_panels, number_turbines+1 ,number_batteries, h,d) = (max_battery_capacity*number_batteries) - (battery_capacity(idx_number_panels, number_turbines+1 ,number_batteries, h-1,d)) ;
else
storage_availability(idx_number_panels, number_turbines+1 ,number_batteries, h,d) = 0;
end
Let's look at this just by hours.
for h = 1:24
battery_capacity(1) = initial_battery_capacity*number_batteries
if hourly_total_RES(h) > hourly_annual_demand(n), % battery charging
battery_capacity(h) = battery_capacity(h-1);
else
battery_capacity(h) = battery_capacity(h-1);
end
end
First off, the both sides of the if statement are the same as written. I assume that your actual code does some sort of work with the previous data. If not, that's a problem.
It also might make the code a little easier to think about if you switch the order of the day and hour loops. To me, looking through all the hours of one day at a time makes better sense than looking at the first hour of each day, then the second hour of each day...
As for the indexing, one definite error is that you index battery_capacity(h-1) on the first iteration of the loop. That is, when h is 1, you define battery_capacity(1) and then try to look at battery_capacity(0), which is probably what's throwing the error.
To fix this, you could check to see if h == 1, but I think a more elegant way would be to loop through h = 2:24 and set battery_capacity(1) before entering that loop. See if this code works:
for d = 1:number_of_days
battery_capacity(1) = initial_battery_capacity*number_batteries
for h = 2:24
if hourly_total_RES(h) > hourly_annual_demand(n), % battery charging
battery_capacity(h) = battery_capacity(h-1);
else
battery_capacity(h) = battery_capacity(h-1);
end
end
end
From what I understand, the last two dimensions store the hour and day respectively. So to set the value for first day at hour=1 (I assume this means midnight start of day):
battery_capacity(:,:,:,1,1) = 2; %# 2kWh
This will set the value 2 for all "panels" and all "turbines" and all "batteries".
I assume you have the matrix already pre-allocated somewhere in your code.
For what its worth, I think you have a typo where you first mention battery_capacity in the code (there is a missing h parameter)