How do i create a program that, depending on the input value would create more or less variables

I have the following code i did for calculating location of earthquakes based on the information of different stations, it isn't complete yet but it's something. How do i create an index or array structure in which i don't have to manually insert da,db,dc or dtax0, dtay0 and so on, but give a number and the code creates the variables depending on how high the number is, so for example if i put a for k=1:1 it just creates da,dtat0,dtax0,dtay0 and dtaz0 but if i put an 'if p=2' it creates da,db,dtax0,dtbx0 and so on.
da=((A(1,1)-m0(2))^2+(A(2,1)-m0(3))^2+(A(3,1)-m0(4))^2)^(1/2);
db=((A(1,2)-m0(2))^2+(A(2,2)-m0(3))^2+(A(3,2)-m0(4))^2)^(1/2);
dc=((A(1,3)-m0(2))^2+(A(2,3)-m0(3))^2+(A(3,3)-m0(4))^2)^(1/2);
dd=((A(1,4)-m0(2))^2+(A(2,4)-m0(3))^2+(A(3,4)-m0(4))^2)^(1/2);
dtat0=1;
dtax0=-(A(1,1)-m0(2))/v*da;
dtay0=-(A(2,1)-m0(3))/v*da;
dtaz0=-(A(3,1)-m0(4))/v*da;
dtbt0=1;
dtbx0=-(A(1,2)-m0(2))/v*db;
dtby0=-(A(2,2)-m0(3))/v*db;
dtbz0=-(A(3,2)-m0(4))/v*db;
dtct0=1;
dtcx0=-(A(1,3)-m0(2))/v*dc;
dtcy0=-(A(2,3)-m0(3))/v*dc;
dtcz0=-(A(3,3)-m0(4))/v*dc;
dtdt0=1;
dtdx0=-(A(1,4)-m0(2))/v*dd;
dtdy0=-(A(2,4)-m0(3))/v*dd;
dtdz0=-(A(3,4)-m0(4))/v*dd;
The da,db,dc,dd are the distances and the rest are the partial derivates

6 Comments

This is likely more than possible to do, but I'm a bit confused as to what exactly you're trying to create, and what your creation condition is. Would you be willing to restate it in a different manner for me?
In particular, I'm confused how k and p relate.
Ok, im sorry, i am just starting, and don't know the ins and outs. k and p are just two variables im using to set an example, what I want to do is, insert a number into the program and depending on the number i input it generates the variables
"but give a number and the code creates the variables depending on how high the number is..."
Don't do this. Dynamically creating and accessing variable names is how beginners force themselves into writing slow, complex, buggy code that is hard to debug. The MATLAB documentation specifically advises against what you are trying to do: "A frequent use of the eval function is to create sets of variables such as A1, A2, ..., An, but this approach does not use the array processing power of MATLAB and is not recommended. The preferred method is to store related data in a single array"
As the MATLAB help clearly states, you would be much better off putting the data into one array. In your case you could probably easily vectorize this code anyway, so loops are not required at all. Or use indexing: indexing is neat, simple, easy to debug, and very efficient. Read more here:
Yes, i read about dynamically creating and accessing variables a bit, that is why i wanted to know how i could index it or what the best way would be to do it.
It's fairly easy to have a user defined variable that can be a condition for the creation of other values. The simplest way is to hard code the value somewhere near the top of your code so it is relatively accessible. Alternatively you can use the input() function to prompt the user for an input.
I'm still not sure how you want to use this value, however, so I'm not entirely sure how to help you create more values with it. In the instance of a for loop, it is perfectly valid to use variables for the ranges (of k in your example) such as the following:
number = input('Enter the number of values to create: ');
for k = 1:number;
values(k) = k;
end
Similarly, you could use an if statement if you have a more broad range to consider:
number = input('Enter the number of values to create: ');
if number >= 1 && number < 6;
values = rand(3);
elseif number >= 6 && number < 100;
values = rand(10);
else
values = rand(1);
end
A useful tip for writing code: computers are only actually good at doing one thing: simple operations really quickly in loop. This means that anytime you find yourself copy-and-pasting code, you are just doing the computers job for it. Instead, put your data into vectors/matrices/arrays, do operations on the complete vector/matrices/arrays, and MATLAB will process your data quickly and efficiently. MATLAB has fast internal loops that do everything, exactly so that you do not have to write slow, complex code changing variable names...
Keep data together as much as possible, rather than splitting it apart, and you will make your code simpler and more efficient.

Sign in to comment.

 Accepted Answer

Forget about dynamically accessing variable names, simply vectorize your code and you will immediately be on the way to writing simpler, more efficient MATLAB code. Rather than these:
da=((A(1,1)-m0(2))^2+(A(2,1)-m0(3))^2+(A(3,1)-m0(4))^2)^(1/2);
db=((A(1,2)-m0(2))^2+(A(2,2)-m0(3))^2+(A(3,2)-m0(4))^2)^(1/2);
dc=((A(1,3)-m0(2))^2+(A(2,3)-m0(3))^2+(A(3,3)-m0(4))^2)^(1/2);
dd=((A(1,4)-m0(2))^2+(A(2,4)-m0(3))^2+(A(3,4)-m0(4))^2)^(1/2);
Just write this:
dV = sqrt((A(1,:)-m0(2)).^2+(A(2,:)-m0(3)).^2+(A(3,:)-m0(4)).^2);
And rather than these:
dtax0=-(A(1,1)-m0(2))/v*da;
dtbx0=-(A(1,2)-m0(2))/v*db;
dtcx0=-(A(1,3)-m0(2))/v*dc;
...
do something like this (the exact code you need depends on the size of v):
dtx0 = -(A(1,:)-m0(2))./v.*d;
or even do all of x, y and z at once, something like:
dt0 = -bsxfun(@minus,A(1,:),m0(:))./v.*d;
The actual operations you require depend on the sizes and classes of the arrays.
Knowing how to manipulate matrices/arrays is fundamental to using MATLAB. The name MATLAB comes from "MATrix LABoratory" and not from "puts the data into lots of separate variable and make it difficult to work with". The introductory tutorials are a good place to start learning how to use matrices effectively:
You should also read these:
Experiment! The more you practice, the more it will make sense and the better you can use matrices.

12 Comments

@Miro Feliciano Doring dos Santos: I hope that it helps. We are always happy to help if something is confusing, or does not work as you expect. Come and ask us anytime!
One more thing i wrote it wrong, it is actually
dtax0=-(A(1,1)-m0(2))/(v*da)
with parenthesis on everything ((v*db),(v*dc) and so on) does that change anything?
Perhaps
dtx0 = -(A(1,:)-m0(2))./(v.*d);
Writing code does not mean trusting random strangers on the internet if your code is correct. Writing code means that you need to test your code. If you are not sure if the brackets and operation produce the correct result then check it yourself. Test the code on some small data matrices, and check that you get the correct values as a result. Compare these against values that you worked out by hand/some other method. Also, read the documentation carefully for every operation that you are using, and try them with some small examples so that you understand what they are doing.
I tested it, trying to put the parenthesis before actually asking and it didn't work out, well now i'm gonna study a bit to see what's wrong, thanks for the tips!
@Miro Feliciano Doring dos Santos: good luck with the studying. If you want more help with this you will need to tell us the exact sizes and classes of A, m0, and v, or (better) simply upload them here in a .mat file.
here it is, the problem is when i put the parenthesis dtx goes to NaN
Perhaps something like this:
>> load matrix.mat
>> dV = sqrt((A(1,:)-m0(2)).^2 + (A(2,:)-m0(3)).^2 + (A(3,:)-m0(4)).^2)
dV =
4.2467 4.8651 5.0484 5.0484 7.4775
>> dt = bsxfun(@minus,m0(2:4),A);
>> dt = bsxfun(@rdivide,dt,v*dV)
dt =
-0.016034 -0.082512 -0.046502 -0.079516 -0.031395
-0.016034 -0.013996 -0.079516 -0.046502 -0.031395
0.165117 0.144131 0.138898 0.138898 0.160644
I have tested it and my problem is not with those variables, they are functioning alright, it's further down the program where i have to some iterations
for k=1:1
dn = sqrt((A(1,:)-m0(2)).^2+(A(2,:)-m0(3)).^2+(A(3,:)-m0(4)).^2);
dt0=[1 1 1 1];
dtx = -(A(1,:)-m0(2))./(v.*dn);
dty = -(A(2,:)-m0(2))./(v.*dn);
dtz = -(A(3,:)-m0(2))./(v.*dn);
dtnx=dtx(1:4);
dtny=dty(1:4);
dtnz=dtz(1:4);
d0=(m0(1)+[norm(m0(2:4)-A(:,1)); norm(m0(2:4)-A(:,2)); norm(m0(2:4)-A(:,3)); norm(m0(2:4)-A(:,4))]./v);
dd=d-d0;
Gn=[dt0; dtnx; dtny; dtnz];
Gt=Gn';
[U,S,V]=svd(Gt);
Gp=V*S^-1*(U');
dm=Gp*dd;
m0=m0+dm;
end
where for each iteration that i do past 3(so anything beyond 'for k=1:3') the number just is so low that the program stops working where as how i used it before without generalizing it, it worked fine.
@Miro Feliciano Doring dos Santos: so check the calculations. If the final value is not correct then check the output of each line, and every intermediate value against one that you calculate by hand. Sometimes that is how bug fixing works. Writing code does not mean writing lots of lines and not knowing what the are doing: you have to check them.
I have no idea what algorithm you are trying to implement, but you know this. This means that you can check your code too. There is no magic shortcut.
One last thing, how would i generalize the following:
dat=norm(A(:,5)-A(:,1));
dbt=norm(A(:,5)-A(:,2));
dct=norm(A(:,5)-A(:,3));
ddt=norm(A(:,5)-A(:,4));
i tried writing it as
dt=norm(A(:,5)-A(:,1:4));
but i want for the code to calculate for each element.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!