I am trying to run the following code:
%% Getting Stocks
stocks = hist_stock_data('01012013','07112014','GDXJ', 'SPY','GOOGL', 'QQQ', 'AAPL');
%% Loop to get the stocks in order by date
while i <= 5
stocks(1,i).Date=datenum(stocks(1,i).Date);
stocks(1,i).Date = stocks(1,i).Date(end:-1:1);
stocks(1,i).AdjClose = stocks(1,i).AdjClose(end:-1:1);
stocks(1,i).Ticker =stocks(1,i).AdjClose;
end
However I am getting the following error:
Subscript indices must either be real positive integers or logicals.
I have searched the web but do not really understand why I am getting this error?
First off, you must have mentioned that hist_stock_data is a function that you got from an external source and isn't a MATLAB builtin function or variable. Well, I googled for it and found it on MATLAB File Exchange.
Next up looking at the code, here's some advice - Try to avoid using i as an iterator because when uninitialized MATLAB would consider it as the imaginary unit. Read more about it here. That's why you were getting that error - Subscript indices must either be real positive integers or logicals., because the index being used was the imaginary unit that can't be used as an index.
So, we could change i to something like ii -
while ii <= 2
stocks(1,ii).Date=datenum(stocks(1,ii).Date);
stocks(1,ii).Date = stocks(1,ii).Date(end:-1:1);
stocks(1,ii).AdjClose = stocks(1,ii).AdjClose(end:-1:1);
stocks(1,ii).Tiicker =stocks(1,ii).AdjClose;
end
Then, we run the code and see this error -
Undefined function or variable 'ii'.
Now, I made some guesswork and replaced that while-loop with a for-loop that iterates for all the elements in the struct stocks. So, it becomes -
for ii = 1:numel(stocks)
stocks(1,ii).Date=datenum(stocks(1,ii).Date);
stocks(1,ii).Date = stocks(1,ii).Date(end:-1:1);
stocks(1,ii).AdjClose = stocks(1,ii).AdjClose(end:-1:1);
stocks(1,ii).Tiicker =stocks(1,ii).AdjClose;
end
This runs fine, but make sure the results are what you were looking to have in stocks.
If you were looking to run the loop for the first 5 elements only, then do this -
for ii = 1:5
Related
Essentially I want to have fminsearch run over a variety or parameters.
So I have the following snipet of code running:
%Setting up the changeable WIRX parameters:
L = 0.15; %Length along the electrodes in meters
I = 3000; %Current in amps
%Running the fminsearch:
TeNe = fminsearch(#(params) TeNe(params,L,I),[5,1.5e21],optimset('MaxFunEvals', 100000,'MaxIter', 100000));
What I want to do is be able to run this in a for loop with an array of values for L and I. However what i noticed is that I cannot even run this piece of code twice in a row with out getting the error:
Subscript indices must either be real positive integers or logicals.
Any insight would be much appreciated!
I assume that TeNe is a function which you call with the following inputs: (params,L,I).
However, the output of fminsearch is also assigned to TeNe.
That is why, after the first loop iteration you get the error you see. L has been set to 0.15, however, this makes no sense as an index to an array called TeNe - which you end up with after running fminsearch.
Consider changing the name of the output variable.
I am using a while loop with an index t starting from 1 and increasing with each loop.
I'm having problems with this index in the following bit of code within the loop:
dt = 100000^(-1);
t = 1;
equi = false;
while equi==false
***some code that populates the arrays S(t) and I(t)***
t=t+1;
if (t>2/dt)
n = [S(t) I(t)];
np = [S(t-1/dt) I(t-1/dt)];
if sum((n-np).^2)<1e-5
equi=true;
end
end
First, the code in the "if" statement is accessed at t==200000 instead of at t==200001.
Second, the expression S(t-1/dt) results in the error message "Subscript indices must either be real positive integers or logicals", even though (t-1/dt) is whole and equals 1.0000e+005 .
I guess I can solve this using "round", but this worked before and suddenly doesn't work and I'd like to figure out why.
Thanks!
the expression S(t-1/dt) results in the error message "Subscript indices must either be real positive integers or logicals", even though (t-1/dt) is whole and equals 1.0000e+005
Is it really? ;)
mod(200000 - 1/dt, 1)
%ans = 1.455191522836685e-11
Your index is not an integer. This is one of the things to be aware of when working with floating point arithmetic. I suggest reading this excellent resource: "What every computer scientist should know about floating-point Arithmetic".
You can either use round as you did, or store 1/dt as a separate variable (many options exist).
Matlab is lying to you. You're running into floating point inaccuracies and Matlab does not have an honest printing policy. Try printing the numbers with full precision:
dt = 100000^(-1);
t = 200000;
fprintf('2/dt == %.12f\n',2/dt) % 199999.999999999971
fprintf('t - 1/dt == %.12f\n',t - 1/dt) % 100000.000000000015
While powers of 10 are very nice for us to type and read, 1e-5 (your dt) cannot be represented exactly as a floating point number. That's why your resulting calculations aren't coming out as even integers.
The statement
S(t-1/dt)
can be replaced by
S(uint32(t-1/dt))
And similarly for I.
Also you might want to save 1/dt hardcoded as 100000 as suggested above.
I reckon this will improve the comparison.
In my project I need a function which returns the index of the largest element of a given vector. Just like max. For more than one entry with the same maximum value (which occurs frequently) the function should choose one randomly. Unlike max.
The function is a subfunction in a MATLAB Function Block in Simulink. And the whole Simulink model is compiled.
My basic idea was:
function ind = findOpt(vector)
index_max = find(vector == max(vector));
random = randi([1,length(index_max)],1);
ind = index_max(random);
end
But I got problems with the comparison in find and with randi.
I found out about safe comparison here: Problem using the find function in MATLAB. Also I found a way to replace randi([1,imax],1): Implement 'randi' using 'rand' in MATLAB.
My Code now looks like this:
function ind = findOpt(vector)
tolerance = 0.00001;
index_max = find(abs(vector - max(vector)) < tolerance);
random = ceil(length(index_max)*rand(1));
ind = index_max(random);
end
Still doesn't work. I understand that the length of index_max is unclear and causes problems. But I can not think of any way to know it before. Any ideas how to solve this?
Also, I'm shocked that ceil doesn't work when the code gets executed?? In debug mode there is no change to the input visible.
I thought about creating an array like: index_max = abs(vector - max(vector)) < tolerance; But not sure how that could help. Also, it doesn't solve my problem with the random selection.
Hopefully somebody has more ideas or at least could give me some hints!
I am using MATLAB R2012b (32bit) on a Windows7-64bit PC, with the Lcc-win32 C 2.4.1 compiler.
Edit:
Vector usually is of size 5x1 and contains values between -2000 and zero which are of type double, e.g. vector = [-1000 -1200 -1000 -1100 -1550]'. But I think such a simple function should work with any kind of input vector.
The call of length(index_max) causes an system error in MATLAB and forces me to shut it down. I guess this is due to the strange return I get from find. For a vector with all the same values the return from find is something like [1.000 2.000 1.000 2.000 0.000]' which doesn't make any sense to me at all.
function v= findOpt(v)
if isempty(v)
return;
end
v = find((max(v) - v) < 0.00001);
v = v(ceil(rand(1)*end));
end
I was indeed overloading, just like user664303 suggested! Since I can not use objects in my project, I wanted an function that behaves similar, so I wrote:
function varargout = table(mode, varargin)
persistent table;
if isempty(table) && ~strcmp(mode,'writeTable')
error(...)
end
switch mode
case 'getValue'
...
case 'writeTable'
table = ...
...
end
end
Wanted to avoid passing the dimensions for the table in every call and thought it would be enough if the first call initializes the Table with mode='writeTable'. Looks like this caused my problem.
No problems after changing to:
if isempty(table)
table = zeros(dim1,dim2,...)
end
I've looked around on the internet a bit and cannot seem to find the answer to this question. I want to declare a vector in matlab and then have a for loop that will add an element to the vector each time I go through the for loop.
This is what I've tried and it doesn't seem to be working
vector[];
for k = 1 ; 10
%calculate some value
%calculated value stored in temp variable
vector(k) = temp;
end
This does not work. Does anybody know how to solve this issue?
As ypnos said, you don't need to declare the vector variable upfront. For example if you did:
vector(50) = 1;
MATLAB would make a vector of length 50 with the 50th value being 1. If you want to improve performance and want to create a vector of the proper size beforehand then do the following:
vector = zeros(10, 1);
The code as you have it (as long as you fix the loop as ypnos said) will work, except for how you declare vector, which is not correct. I bet you are getting the error message: "Error: Unbalanced or unexpected parenthesis or bracket." You do not specify whether a variable is a matrix/vector in MATLAB.
vector = [vector; temp];
or
vector(end+1) = temp;
I have recently started learning MatLab, and wrote the following script today as part of my practice to see how we can generate a vector:
x = [];
n = 4;
for i = i:n
x = [x,i^2];
end
x
When I run this script I get what I expect, namely the following vector:
x = 0 1 4 9 16
However, if I run the script a second time right afterwards I only get the following output:
x = 16
What is the reason for this? How come I only get the last vector entry as output the second time I run the script, and not the vector in its entirety? If anyone can explain this to me, I would greatly appreciate it.
Beginning with a fresh workspace, i will simply be the complex number 1i (as in x^2=-1). I imagine you got this warning on the first run:
Warning: Colon operands must be real scalars.
So the for statement basically loops over for i = real(1i):4. Note that real(1i)=0.
When you rerun the script again with the variables already initialized (assuming you didn't clear the workspace), i will refer to a variable containing the last value of 4, shadowing the builtin function i with the same name, and the for-loop executes:
x=[];
for i=4:4
x = [x, i^2]
end
which iterates only one time, thus you end up with x=16
you forget to initialize i.
after first execution i is 4 and remains 4.
then you initialize x as an empty vector but because i is 4 the loop runs only once.
clear your workspace and inspect it before and after first execution.
Is it possibly a simple typo?
for i = i:n
and should actually mean
for i = 1:n
as i is (probably) uninitialized in the first run, and therefore 0, it works just fine.
The second time, i is still n (=4), and only runs once.
Also, as a performance-tip: in every iteration of your loop you increase the size of your vector, the more efficient (and more matlaboid) way would be to create the vector with the basevalues first, for example with
x = 1:n
and then square each value by
x = x^2
In Matlab, using vector-operations (or matrix-operations on higher dimensions) should be prefered over iterative loop approaches, as it gives matlab the opportunity to do optimised operations. It is also often more readable that way.