Why doesn't this function declaration work?

5 views (last 30 days)
Andrew Morris on 27 Oct 2021
Commented: Walter Roberson on 30 Oct 2021
I'm sorry that this is an extremely basic question that people might get irritated by, but I am new and I am trying to do some scripting. I want to declare a function that makes an array for concentration values of a serial dilution. As far as I can tell, I am following the syntax matlab gives for function EXACTLY, but it still gives an error when i call the function with what should be valid parameters.
For example, this should return a 24 by 1 array that is [ 25, 15, 9, ... ]
input:
a = serialdilution(25, 1.6666, 24)
output:
Error: File: serialdilution.m Line: 1 Column: 28
Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To construct matrices, use brackets instead of parentheses.
with this function definition in the \MATLAB path named serialdilution.m
function concentrations = serialdilution(maxconc, factor, n)
%returns an n by 1 array whose last element is maxconc
%and each previous value is equal to the next element divided
%by factor
for i=1:n
concentrations(n-i-1) = maxconc*(1/factor^(i-1);
end
concentrations = concentrations.';
end

Stephen on 27 Oct 2021
Edited: Stephen on 27 Oct 2021
You are missing a closing parenthesis here:
concentrations(n-i-1) = maxconc*(1/factor^(i-1);
% ^ missing closing parenthesis
Once you fix that syntax error you will get another error message due to your indexing (n-1-i), because as soon as i = n-1 then your index will be zero.
As far as I can tell, your task does not require a loop anyway:
x = 25;
f = 5/3;
n = 24;
x./f.^(0:n-1)
ans = 1×24
25.0000 15.0000 9.0000 5.4000 3.2400 1.9440 1.1664 0.6998 0.4199 0.2519 0.1512 0.0907 0.0544 0.0327 0.0196 0.0118 0.0071 0.0042 0.0025 0.0015 0.0009 0.0005 0.0003 0.0002
Walter Roberson on 30 Oct 2021
Given a starting address for an array, base, and an index that is 0 based, you can find the in-memory address of the element by calculating base + (index * size_of_element) .
On some architectures, that might even be a single addressing mode, potentially. For example, one of the x64 addressing modes is Base + (Index * Scale) where Scale has a value of 1, 2, 4, or 8 .
Now, if you have a starting address for an array, base, and an index that is 1 based, you can find the in-memory address by calcuating |base + ((index - 1) * size_of_element) . Which certainly looks more complicated.
But... the difference compared to the other form is subtracting off size_of_element -- base + (index * size_of_element) - size_of_element and x64 also has an addressing mode Base + (Index * Scale) + Displacement and if you set Displacement to have a value equal to size_of_element then you have not used any more instructions... but you might have used a longer instruction word. Does the longer instruction word take enough longer to decode in microcode to matter? That isn't clear.
And if it does take enough longer to decode with the Displacement to be meaningful... then reduce the base by that value and suddenly it takes the same length of time. You can even pass around the pre-decremented base address, adjusting it if you ever typecast the pointer to refer to a different data type, but easier if you just pass around the original base and decrement it when you load it into the register to start your indexing loop.
Thus, even if you have hardware assistance on indexing, there is probably little hardware penalty for doing 1-based indexing in a loop. Maybe a one-time adjustment when you load the base address.