I'm using arrayfun to plot the result of a custom function, which does some logic, look-ups, and calculations. My original call looked similar to this:
plot(x, arrayfun(#Q, x.^2, someNumericVariable));
This worked great. However, in addition to the someNumericVariable parameter, I also wanted to add another parameter, someStringVariable, so I changed it to this:
plot(x, arrayfun(#Q, x.^2, someNumericVariable, someStringVariable));
However, when trying to use this, I get an error:
error: arrayfun: dimensions mismatch
I'm guessing that this happens due to this line in the GNU Octave documentation:
If given more than one array input argument then all input arguments must have the same sizes
(https://www.gnu.org/software/octave/doc/interpreter/Function-Application.html)
So I assume that the string I'm trying to pass is being treated as an array, which has different dimensions than the numeric constant value?
If this is so, are there any workarounds that I can do while keeping the code syntactically concise?
One workaround that would work in MATLAB would be:
plot(x, arrayfun(#(u,v) Q(u,v,someStringVariable), x.^2, someNumericVariable));
Related
I want to make symbolic functions theta1(t), theta2(t), theta3(t),...,thetaN(t) where N is some parameter I can define in MATLAB. I know that I can use something like sym('theta',[1 N]) to get [theta1, theta2, theta3,..., thetaN]. However, how can I do the same thing with theta being a function of t? The way to hard-code it would be like syms theta1(t) theta2(t) theta3(t) ... thetaN(t), but I want to make this general.
I do not want to directly use the sym command here because "support of character vectors that are not valid variable names and do not define a number will be removed in a future release", meaning something like sym('theta1(t)') would not be valid in future releases.
Any suggestions?
Figured part of it out. I could do something like the following
for i = 1:N
syms(strcat('theta',num2str(i),'(t)'))
end
However, if I want to assign a variable that contains all the symbolic expressions I'm still stuck. If I try
for i = 1:N
my_array(i) = syms(strcat('theta',num2str(i),'(t)'))
end
I get Error using syms (line 133). Using input and output arguments simultaneously is not supported. It works if I use sym instead of syms, but this leads to the warning I mentioned in my original post.
In Matlab I wanted to pass arguments to the plot function by using a struct. This was going well until I wanted to include the DurationTickFormat argument.
In the minimal example below, I get the following error message when trying to plot the second figure:
Error using duration/plot There is no DurationTickFormat property on
the Line class.
clear;
t_dur = days(0);
t_dur(2) = 2;
t_duration = linspace(t_dur(1),t_dur(2),11);
figure;
plot(t_duration,0:10,'Color','k','LineWidth',2,'DurationTickFormat','hh:mm:ss');
% using a struct to pass arguments to the plot function
plotOptions.LineWidth = 2;
plotOptions.DurationTickFormat = 'hh:mm:ss';
figure;
plot(t_duration,0:10,'Color','k',plotOptions);
Any ideas why using a struct to pass arguments doesn't work in this case?
Thanks.
I'm not familiar with R2015a, but I have a good guess. I think when you pass a structure, you explicitly add line properties (lineseries properties in older matlab, I guess with HG1, chartline properties in the newest ones, I'm guessing with HG2). The chartline properties do not include 'DurationTickFormat'. So when you are calling it directly, you are actually telling the plot function to do some stuff (like changing the xlabel accordingly, which is obviously invisible to a line object).
I hope someone familiar with R2015a can either verify or disprove my hypothesis.
Update: from plot options > DurationTickFormat:
DurationTickFormat is not a chart line property. You must set the tick format using the name-value pair argument when creating a plot.
As part of a group project we have a system of 2 non linear differential equations and we have to draw the S=S(t) , I=I(t) graphic using the midpoint method.
And I'm getting the following error when trying to insert the matrix with the corresponding differential equations:
"Error in inline expression ==> matrix([[-(IS)/1000], [(IS)/1000 - (3*I)/10]])
Undefined function 'matrix' for input arguments of type 'double'.
Error in inline/subsref (line 23)
INLINE_OUT_ = inlineeval(INLINE_INPUTS_, INLINE_OBJ_.inputExpr, INLINE_OBJ_.expr);"
The code I have done is the following:
syms I S
u=[S;I];
F=[-0.001*S*I;0.001*S*I-0.3*I];
F1=inline(char(F),'I','S');
h=100; %Valores aleatórios
T=100000;
ni=(T/h);
u0=[799;1];
f=zeros(1,2);
k=zeros(1,2);
i=1;
while i<=ni
f(1)=F1(u0(1));
f(2)=F1(u0(2));
dx=h*f;
k(1)=F1((u0(1)+h*(1/2)),(u0(2)+h*(1/2)));
k(2)=F1((u0(1)+h*(1/2)),(u0(2)+h*(1/2)));
u1=u0+h*k;
disp('i:'),disp(i)
disp('u= '),disp(u1)
u0=u1;
i=i+1;
end
I'm new to this so the algorithm it's very likely to be wrong but if someone could help me with that error I'd apreciate it. Thank you!
The problem that specifically creates the error is that you are putting two symbolic functions into a matrix and then calling char (which outputs matrix([[-(IS)/1000], [(IS)/1000 - (3*I)/10]]) rather than converting nicely to string).
The secondary problem is that you are trying to pass two functions simultaneously to inline. inline creates a single function from a string (and using anonymous functions instead of inline is preferred anyway). You cannot put multiple functions in it.
You don't need sym here. In fact, avoid it (more trouble than it's worth) if you don't need to manipulate the equations at all. A common method is to create a cell array:
F{1} = #(I,S) -0.001*S*I;
F{2} = #(I,S) 0.001*S*I-0.3*I;
You can then pass in I and S as so:
F{1}(500,500)
Note that both your functions include both I and S, so they are always necessary. Reconsider what you were expecting when passing only one variable like this: f(1)=F1(u0(1));, because that will also give an error.
Trying to find a way to call the exponentiation function ( ^ ) used in a custom function for every item in a matrix in GNU Octave.
I am quite a beginner, and I suppose that this is very simple, but I can't get it to work.
The code looks like this:
function result = the_function(the_val)
result = (the_val - 5) ^ 2
endfunction
I have tried to call it like this:
>> A = [1,2,3];
>> the_function(A);
>> arrayfun(#the_function, A);
>> A .#the_function 2;
None of these have worked (the last one I believe is simply not correct syntax), throwing the error:
error: for A^b, A must be a square matrix
This, I guess, means it is trying to square the matrix, not the elements inside of it.
How should I do this?
Thanks very much!
It is correct to call the function as the_function(A), but you have to make sure the function can handle a vector input. As you say, (the_val - 5)^2 tries to square the matrix (and it thus gives an error if the_val is not square). To compute an element-wise power you use .^ instead of ^.
So: in the definition of your function, you need to change
result = (the_val-5)^2;
to
result = (the_val-5).^2;
As an additional note, since your code as it stands does work with scalar inputs, you could also use the arrayfun approach. The correct syntax would be (remove the #):
arrayfun(the_function, A)
However, using arrayfun is usually slower than defining your function such that it works directly with vector inputs (or "vectorizing" it). So, whenever possible, vectorize your function. That's what my .^suggestion above does.
This is simple, but for some reason I can't find the solution anywhere on the Internet. I have a vector function in Matlab:
E(s) = [E_1(s),E_2(s),E_3(s)]
I want to be able to index it, so normally in Matlab you would use E(1), for the first element. However this just evaluates the vector at s equals 2. E(s)(1) also gives an error.
Here's my code for reference.
You have a symbolic function that returns a vector. Type whos and you'll see that the class of E is symfun. Unfortunately, I don't think that you can directly index into a symbolic function. However, you can convert it into a symbolic expression (class sym) simply by setting it equal to a new variable and passing in your symbolic variable s
Es = E(s);
Now you should be able to evaluate Es(1), Es(2), and Es(3) as you wanted.
If I understand you correctly, your only hope is to use the command "eval." Type "help eval" and see if that's what you need.