Why am I getting an error of subscripted assignment dimension mismatch

Can anyone tell me how to fix the problem?
% creating a multidimensional array
files = dir('*txt') ; % you are in the folder with text files
N = length(files) ;
names = {files(:).name}' ;
iwant = cell(N,1) ;
for i = 1:N
iwant{i} = importdata(files(i).name) ;
end
A = input('Please enter an element in form of iwant{i}:');
% find the number of samples
n = length (A(:,1));
% step change for the wavelength
step = 0.02;
ss=100;
zn=ss+1;
% wavelength which is at the centre
p = A(:,1);
% to make new wavelength for each of wavelength in the samples
for j=1:n
new_wavelength(j,:) = p(j)-step*ss:step:p(j)+step*ss;
end
format shortG
jj = input('Please input the row:');
jj = jj.';
i = input('Please input number for element:');
Delta_lambda=0.2;
int_fact= iwant{i}(jj,2);
K=2*ss+1;
denominator = Delta_lambda/2;
for m = 1:length(new_wavelength(:,1))
for K = 1:length(new_wavelength(1,:)) % the upper limit of the loop magic number
numerator(m,K) = new_wavelength(m,zn)-new_wavelength(m,K);
end
Peak(m,K) = int_fact.*(1./(1+(numerator(m,K)/denominator).^2));
hold on
end
plot(new_wavelength(j,:).',Peak(m,K).','g')
hold on
I will attached the file as well Thanks

9 Comments

What line is throwing the error? And what is on the right hand side of that line? A scalar, or something else?
With which element, value of jj and value of i, do you get an error? I've just tried with aluminium, jj = 4, i = 2, and got no error.
Note that there are a lot of things that don't make sense in your code, in particular there are a few transpose (.') on scalars (including in your plot call),
with copper it has an error. what do you mean? is there a problem with my code? im quite new to matlab so i just throw it in everything that i know. not sure how to tidy the code to make it neat
Just tried with copper (iwant{25}), row 4, element 2 and got no error.
What I mean is that you have:
jj = jj.';
yet jj is scalar. So the above line won't do anything.
Similarly, in your plot you have Peak(m,K).'. Again, the transpose won't do anything since peak(m,K) is scalar.
Also, you create a names cell array that you never use.
You also have
format shortG
which won't do anything. format only affects the way numbers are displayed on the command line. Nothing else.
Finally, you have hold on in your loop, yet never plot anything in the loop.
Note that Peak is a matrix, not a vector. Peak(m,K) is of course scalar.
edit: Another, more critical problem with your code is you never preallocate or reset any of the matrices that you fill so if you call your script several time, you'll end up using values for a different element. While it is a bug it shouldn't cause the error you state.
how do i preallocate the matrices? I got the new_wavelength which is a matrix and so i need Peak(m,K) to be a matrix as well. If you try iwant{25}, row=1:length(new_wavelength(:,1)), element:25. Thats where the error come
"i need Peak(m,K) to be a matrix as well"
That makes no sense. If Peak is a matrix, then a single element of that matrix, Peak(m, K) is scalar.
Looking in more detail at your code, there are more things that don't make sense. Is the element you chose for your question Please input number for element supposed to be te same as for your question Please enter an element in form of iwant{i}. If so, why do you ask for it twice?
Then, shouldn't the calculation of Peak(m, K) inside the K loop. As it is, you're calculating a lot of numerator(m, K) that you don't use and only fill the last column of Peak.
To be honest, it would be easier if you explained what your code is supposed to do and we rewrite it all.
The thing that I supposed to do is:
I need to create a multidimensonal array of the element textfile to make it easier for the user the choose what element they want to read
From the element they chose, it need to create 201 new wavelength where the wavelength from the textfile which is in first column need to be in the center
From that, each of the wavelength need to go through the equation of the peak to calculate the peak and multiply it with int_fact where in the textfile(element in multidimensional array) is in the second column.
Lastly, all the peak created need to be added to create one spectral line and display it.
Thats how that code supposed to be. I learned it a bit from youtube and just throw it in to create this code. Sorry for the trouble. Hope you can help me with this. Thanks
Do you think that from what i explained of what should i do the code is wrong? then how should I do it?

Sign in to comment.

 Accepted Answer

Do you think that from what i explained of what should i do the code is wrong? then how should I do it?
The code you have written is probably wrong but as your explanation is not very clear I'm not sure. In particular, I don't really understand whether you're supposed to calculate something for all wavelengths, or just for the one the user select. I'm also not sure you've got your peak calculation right, your 2D numerator array is identical for all rows.
Here is an attempt at much cleaner code than you have written. As I'm not sure what it is exactly you want to do, the final result, the plot in particular, may not be correct.
%get list of element, prompt user to select one, and get content of element file
filelist = dir('*.txt');
[~, elementlist] = arrayfun(@(f) fileparts(f.name), filelist, 'UniformOutput', false);
[elementindex, ok] = listdlg('ListString', elementlist, 'PromptString', 'Select an element', 'SelectionMode', 'single');
if ~ok, return; end %terminate if user click cancel
elementdata = importdata(filelist(elementindex).name);
assert(isnumeric(elementdata), 'Element does not have data'); %abort if the file does not contain a matrix
%build wavelength array
step = 0.02;
ss = 100;
steparray = -step*ss : step : step*ss;
new_wavelength = elementdata(:, 1) + steparray; %no loop needed. Requires R2016b or latter
%get row selection
[selectedrow, ok] = listdlg('ListString', compose('%f', elementdata(:, 1)), 'PromptString', 'Select a wavelength', 'SelectionMode', 'single');
if ~ok, return; end %terminate if user click cancel
%build Peak vector for selected row
Delta_lambda = 0.2;
int_fact = elementdata(selectedrow, 2);
Peak = int_fact.*(1./(1+(steparray/Delta_lambda*2).^2));
plot(new_wavelength(selectedrow, :), Peak);
This is also a lot more user friendly than what you have written.

8 Comments

Thanks for the help. Yup it should be identical for all row bcs thats how the equation work. From the previous code, I usually need to make more than 1 Peak or usually all peak and combined it to form a spectral line. How do I combined the more than one peak to form a spectral line?

From the previous code, I usually need to make more than 1 Peak

I don't know what more than 1 Peak mean. The Peak generated by my code is a vector, hence it has more than one values. If you mean you want a matrix, you need to explain how the other rows are generated.

and combined it to form a spectral line. No idea what combine mean. It's not a mathematical operation.

Because for each row of wavelength it will create one peak, if i want to choose more than one wavelength, it will have more than one peak. Because of the wavelength will overlap with each other so does the peak. The overlap peak is where I need to add up to become one line instead of overlapping. Im not sure how to explain it but do you like sort of get what im trying to do?

but do you like sort of get what im trying to do?

Not at all.

Im trying to do something like this. Im able to create more than one peak based on your code but I still cant figure out on how to add up the overlap part. Is it possible to make something like that picture?

I got this picture from findpeaks but im not sure how to apply it here. In the example, they just sum(Peak) and then it comes up with the graph. I have try to do the same thing, but it doesnt work for me. Not sure why. Sorry for the trouble of helping me.

So does that mean that when prompted to select a row, you want to be able to select a row? Your original code certainly did not work like that.

If that is the case, it's easy to change in part. First allow selection of multiple rows by changing the 'SelectionMode' to 'multiple':

%get row selection
[selectedrow, ok] = listdlg('ListString', compose('%f', elementdata(:, 1)), 'PromptString', 'Select wavelength(s)', 'SelectionMode', 'multiple');
if ~ok, return; end  %terminate if user click cancel

The rest of the code after that will work even if selectedrow is a vector (which will happen when you select multiple wavelengths).

As it is, the plot will have a line for each wavelength selected.

For your combined plot, you can't just sum the rows of Peak because the columns of each row correspond to different wavelengths. You first have to resample each row to the same wavelengths (with interp1 for example) before you can sum them. I don't have the time now to write that code for you.

Okay then! you can write it later thats fine. I can try it first and see if it works. Thank you so much for the help! Much appreciated!

Sign in to comment.

More Answers (1)

The Peak(m,K) line (line 35). It is a vector
Well, then I think you've answered your own question. You cannot stick a vector into a scalar location Peak(m,K).

Categories

Tags

Community Treasure Hunt

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

Start Hunting!