Some time ago I was told, that the usual pattern to implement two-ary operators needs a final move in the return.
Matrix operator+(const Matrix &a, Matrix &&b) {
b += a;
return std::move(b);
}
But now there is the special rule that in a return the compiler may treat the return value as a temporary, and then this would not be necessary -- a simple return b would suffice.
But then again, b has a name in this function, therefore, its an LValue -- which hinders the compiler to m consider it being a temp, and the move is required.
Is this still the case in the most recent version of the C++0x Standard? We need the move to implement the above pattern?
You need the explicit std::move in this example because b is not the name of a non-volatile automatic object. Reference 12.8 [class.copy] /p31/b1:
in a return statement in a function with a class return type, when
the expression is the name of a non-volatile automatic object (other
than a function or catch-clause parameter) with the same cv-
unqualified type as the function return type, the copy/move operation
can be omitted by constructing the automatic object directly into the
function’s return value
I'm not sure why this function returns by value. Shouldn't this function return a Matrix&& like the following?
Matrix&& operator+(const Matrix &a, Matrix &&b) {
b += a;
return std::move(b);
}
This has the added advantage that x1 + x2 + x3 + ... + xn creates at most one temporary, which is important if Matrix happens to be stack allocated (as it then gains nothing from moves).
I think the signatures should be like the following:
Matrix&& operator+(Matrix &&a, Matrix &&b );
Matrix&& operator+(const Matrix &a, Matrix &&b );
Matrix&& operator+(Matrix &&a, const Matrix &b);
Matrix operator+(const Matrix &a, const Matrix &b);
Related
I am new to Matlab, so there is a lot I do not understand; I have three questions, as followed:
The biggest issue I have revolves around function B= upper_triang(A) where it states that it is 'a function unused'. Reading through the Matlab tooltip, and I am guessing that it has to do with a value that has not been defined? ANd B of course being unset, but I thought I defined B as a function, so why is it unset? I am assuming that B is U, but in the math part that is ahh, so I am not sure what it would be.
To give context to my code I sent the part of the homework code I have a question on.
%%%This is for part a for problem 1.
A=zeros(8,8);%%%For the size column and row size of matrix A.
for j=1:8
for k=1:8
if j==k
A(j,k)=-2;
end
if abs(j-k)==1
A(j,k)=1;
end
end
end
[L,U]=lu(A); %%%Proving L and U.
L*U; %%%Proving that L*U=A, thus it is correct.
%%%This is for part b for problem 1
function B= upper_triang(A)
%%%Input A--> Matrix for m*n for the size
%%%Output B--> Is the upper triangular matrix of the same size
[m,n]=size(A);
for k=1:m-1
for i=k+1:m
u=A(i,k)/A(k,k);
for j=(k):n
A(i,j)=A(i,j)-u*A(k,j);
end
end
end
B-A;
end
Function being unused
The problem here is that you've only created a function, but you've never used it. Everything after the function B = upper_triang(A) just tells Matlab what to do in case that function is ever called, but your never do.
I'm guessing that, after your LU decomposition but before the declaration of your function, you should add a line
B = upper_triang(A);
Output unset
There is a second problem which is that, while you declared that B should be the output of your function upper_triang(), it it not "created" anywhere in the function itself.
There should be a line somewhere with
B = something;
Now, my linear algebra is quite rusty but I think that what you're trying to do should rather be:
%%%This is for part b for problem 1
function B= upper_triang(A)
%%%Input A--> Matrix for m*n for the size
%%%Output B--> Is the upper triangular matrix of the same size
[m,n]=size(A);
B = A; % copy the input matrix in B, and work with it from now on
for k=1:m-1
for i=k+1:m
u=B(i,k)/B(k,k);
for j=(k):n
B(i,j)=B(i,j)-u*B(k,j);
end
end
end
B = B - A; % not really sure about this
end
I have written a function called "tension.m" in which I have used if else condition as shown below.
function [T,T_earlyvalues,T_latervalues] = tension(u,sigma,G,N,K)
%the values of sigma,G,N,K can be taken arbitrary.
sigma=2; G=3;N=8;K=1; v=1;
w=2.2;
if u<w
T =v*sqrt(sigma+G^2/(N-K));
T_earlyvalues=T;
else
T=(2*v)*sqrt(sigma+G^2/(N+K));
T_latervalues=T;
end
Now in another script "myvalues.m" I need to call T_earlyvalues and T_latervalues separately.
%have some coding before this part
sigma0=2400; lambda=1.3; v=2; sigma=2; G=3;N=8;K=1;
u=0:0.01:5;
T=tension(u,sigma,G,N,K);
T_earlyvalues=tension(u,sigma,G,N,K);
T_latervalues=tension(u,sigma,G,N,K);
deltaA=T_earlyvalues*sigma0*pi;
deltaB=T_latervalue*lambda*pi/2;
%have some coding after this part
How could I call the said values which are under if-else statement from tension.m function to myvalues.m script?
You have defined the tension function such that it returns three outputs.
If you call that function by requiring only one output, the function returns the first value, in your case, T
This implies that
T=tension(u,sigma,G,N,K);
shoud work since T is the first output parameter
T_earlyvalues=tension(u,sigma,G,N,K);
T_latervalues=tension(u,sigma,G,N,K);
are not working, since, actually tension returns the first value (T, whjikle you are expecting the second and the third respectively.)
You can cahnge the two above calls this way:
[~,T_earlyvalues,~]=tension(u,sigma,G,N,K);
[~,~,T_latervalues]=tension(u,sigma,G,N,K);
The ~ allows to avoid the function return the output paraemter.
You can find additional information here
Notice that in your function T_earlyvalue is not set in the else block, same for T_latervalue in the if block.
This will generate an error such as
Output argument T_earlyvalue (and maybe others) not assigned during call to tension
or
Output argument T_latervalues (and maybe others) not assigned during call to tension
You can initialize the output values to default values, at the beginning of the function, for example:
T=NaN
T_earlyvalue=NaN
T_latervalues=NaN
You can then use these special values (or any other you want to use) to trace, for example, if the if block has been executed or the else.
There seem to be a number of issues here, not the least of which is some confusion about how output argument lists work when defining or calling functions. I suggest starting with this documentation to better understand how to create and call functions. However, this issue is somewhat moot because the larger problem is how you are using your conditional statement...
You are trying to pass a vector u to your function tension, and from what I can tell you want to return a vector T, where the values of T for u < w are computed with a different formula than the values of T for u >= w. Your conditional statement will not accomplish this for you. Instead, you will want to use logical indexing to write your function like so:
function [T, index] = tension(u, sigma, G, N, K)
T = zeros(size(u)); % Initialize T to a vector of zeroes
w = 2.2;
index = (u < w); % A logical vector, with true where u < w, false where u >= w
T(index) = u(index)*v*sqrt(sigma+G^2/(N-K)); % Formula for u < w
T(~index) = 2*(u(~index)-v)*sqrt(sigma+G^2/(N+K)); % Formula for u >= w
end
Now you can call this function, capturing the second output argument to use for identifying "early" versus "late" values:
sigma0 = 2400; lambda = 1.3; v = 2; sigma = 2; G = 3; N = 8; K = 1;
u = 0:0.01:5;
[T, earlyIndex] = tension(u, sigma, G, N, K); % Call function
T_earlyvalues = T(earlyIndex); % Use logical index to get early T values
T_latervalues = T(~earlyIndex); % Use negated logical index to get later T values
And you can then use the subvectors T_earlyvalues and T_latervalues however you like.
I have a problem with integrating nested function handles in Matlab:
fun = #(x,y) 2*x*y;
y = #(x,a) 5*a*x;
int = integral(#(x)fun(x,y(x,5)),0,2)
The actual nesting goes deeper and the actual functions are more complex but this example pretty much describes my problem which throws 'Error using *
Inner matrix dimensions must agree.'
The reason of this problem is that MATLAB tried to pass you a vector expecting that your function would return a vector of values. Try this one (notice the use of point-wise product):
fun = #(x,y) 2*x.*y;
y = #(x,a) 5*a.*x;
int = integral(#(x)fun(x,y(x,5)),0,2)
This this the excerpt from relevant MATLAB documentation:
For scalar-valued problems, the function y = fun(x) must accept a vector argument, x, and return a vector result, y. This generally means that fun must use array operators instead of matrix operators. For example, use .* (times) rather than * (mtimes). If you set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.
As a toy example, I have a class that simply wraps a vector or matrix in an object and includes a timestamp of when it was created. I'm trying to overload subsref so that
() referencing works exactly as it does with the standard vector and matrix types
{} referencing works in exactly the same way as () referencing (nothing to do with cells in other words)
. referencing allows me to access the private properties of the object and other fields that aren't technically properties.
Code:
classdef TimeStampValue
properties (Access = private)
time;
values;
end
methods
%% Constructor
function x = TimeStampValue(values)
x.time = now();
x.values = values;
end
%% Subscripted reference
function x = subsref(B, S)
switch S.type
case '()'
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '{}'
S.type = '()';
v = builtin('subsref', B.values, S);
x = TimeStampValue(v);
case '.'
switch S.subs
case 'time'
x = B.time;
case 'values'
x = B.values;
case 'datestr'
x = datestr(B.time);
end
end
end
function disp(x)
fprintf('\t%d\n', x.time)
disp(x.values)
end
end
end
However brace {} referencing doesn't work. I run this code
clear all
x = TimeStampValue(magic(3));
x{1:2}
and I get this error:
Error using TimeStampValue/subsref
Too many output arguments.
Error in main (line 3)
x{1:2}
MException.last gives me this info:
identifier: 'MATLAB:maxlhs'
message: 'Too many output arguments.'
cause: {0x1 cell}
stack: [1x1 struct]
which isn't helpful because the only thing in the exception stack is the file containing three lines of code that I ran above.
I placed a breakpoint on the first line of the switch statement in subsref but MATLAB never reaches it.
Whats the deal here? Both () and . referencing work as you would expect, so why doesn't {} referencing work?
When overloading the curly braces {} to return a different number of output arguments than usual, it is also necessary to overload numel to return the intended number (1, in this case). UPDATE: As of R2015b, the new function numArgumentsFromSubscript was created to be overloaded instead of numel. The issue remains the same, but this function should be overloaded instead of numel as I describe in the original answer below. See also the page "Modify nargout and nargin for Indexing Methods". Excerpt:
When a class overloads numArgumentsFromSubscript, MATLAB calls this method instead of numel to compute the number of arguments expected for subsref nargout and subsasgn nargin.
If classes do not overload numArgumentsFromSubscript, MATLAB calls numel to compute the values of nargout or nargin.
More explanation of the underlying issue (need to specify number of output arguments) follows.
Original answer (use numArgumentsFromSubscript instead of numel for R2015b+)
To handle the possibility of a comma separated list of output arguments when indexing with curly braces, MATLAB calls numel to determine the number of output arguments from the size of the input indexes (according to this MathWorks answer). If the number of output arguments in the definition of overloaded subsref is inconsistent with (i.e. less than) the number provided by numel, you get the "Too many output arguments" error. As stated by MathWorks:
Therefore, to allow curly brace indexing into your object while returning a number of arguments INCONSISTENT with the size of the input, you will need to overload the NUMEL function inside your class directory.
Since x{1:2} normally provides two outputs (X{1},X{2}), the definition function x = subsref(B, S) is incompatible for this input. The solution is to include in the class a simple numel method to overload the builtin function, as follows:
function n = numel(varargin)
n = 1;
end
Now the {} indexing works as intended, mimicking ():
>> clear all % needed to reset the class definition
>> x = TimeStampValue(magic(3));
>> x(1:2)
ans =
7.355996e+05
8 3
>> x{1:2}
ans =
7.355996e+05
8 3
However, overloading curly braces in this manner is apparently a "specific type of code that we [MathWorks] did not expect customers to be writing". MathWorks recommends:
If you are designing your class to output only one argument, it is not recommended that you use curly brace indexing that requires you to overload NUMEL. Instead, it is recommended you use smooth brace () indexing.
UPDATE: Interestingly, the R2015b release notes state:
Before MATLAB release R2015b, MATLAB incorrectly computed the number of arguments expected for outputs from subsref and inputs to subsasgn for some indexing expressions that return or assign to a comma-separated list.
With release R2015b, MATLAB correctly computes the values of nargout and nargin according to the number of arguments required by the indexing expression.
So perhaps this is now fixed?
An alternative solution that comes to mind is to change function x = subsref(B, S) to function varargout = subsref(B, S) and adding varargout=cell(1,numel(B)); varargout{1} = x;. As Amro noted in comments, pre-allocating the cell is necessary to avoid an error about an unassigned argument.
I just ran into the same problem. What's even worse, is that the number of output arguments is enforced to be equal to what numel() returns not only for the curly braces {}, but also for the dot . operation.
This means that if numel() is overridden to return the usual prod(size(obj)), it becomes impossible to access any properties of the underlying object (such as x.time in the above example), as subsref() is then expected to return multiple outputs.
But if numel() just returns 1 instead, it does not match prod(size(obj)), which is what most code working with numeric values or based on reshape() expects. In fact, the MATLAB editor's balloon help immediately suggests that 'NUMEL(x) is usually faster than PROD(SIZE(x))', which suggest that they are equivalent, but apparently are not.
A possible solution would be to make numel() return prod(size(obj)) and write explicit getter/setter functions for all these properties, e.g.,
x.get_time()
in the example above. This seems to work, because method calls apparently get resolved before subsref() gets called. But then if one of the properties is a matrix it cannot be directly indexed any more because Matlab doesn't understand chained indexing, i.e., instead of writing
x.matrix(1,:)
one would have to write
m = x.get_matrix();
m(1,:)
which is ugly to say the least.
This is starting to get a bit frustrating. I still hope I've just overlooked something obvious, I can't believe that this is how it's supposed to work.
This solution seems to work in 2014b (but not entirely certain why)
classdef TestClass < handle
methods
function n = numel(~,varargin)
n = 1;
end
function varargout = subsref(input,S)
varargout = builtin('subsref',input,S);
end
function out = twoOutputs(~)
out = {}; out{1} = 2; out{2} = 3;
end
end
end
Then via the command window
>> testClass = TestClass();
>> [a,b] = testClass.twoOutouts()
a =
2
b =
3
I am working on a class to handle polynomials and polynomial matrices. I was having the same dificulty because I want different behaviors for the '.' indexing in the cases of scalar polynomials and polynomial matrices.
In my case I want P.coef to return a vector of coefficients if P is a scalar polynomial. If P is a polynomial matrix, P.coef must return a cell array of the same size of P, in which the cell {i,j} contains the coefficient vector of the polynomial P(i,j).
The problem appeared when P.coef was used with a matrix. My desired behavior returns only one object as an answer, but Matlab is expecting the function to return numel(P) objects.
I found a very simple solution. When declaring subsref, I used one mandatory output and a varargout:
function [R,varargout] = subsref(P,S)
The body of the function defines R as needed, according to my design. And at the very end of the function I added:
varargout(1:nargout-1) = cell(1,nargout-1);
To just return empty matrices as the extra outputs that Matlab wants.
This should create no problem if the function is always called with a single output argument, e.g., as in R = P.coef. If the function is called without assigning, the user will see numel(P)-1 empty matrices, which is really not a big deal. Anyway, the user is warned about this in the function help.
I am writing a program in Matlab and I have a function defined this way.
sum (i=1...100) (a*x(i) + b*y(i) + c)
x and y are known, while a, b and c are not: I need to find values for them such that the total value of the function is minimized. There is no additional constraint for the problem.
I thought of using fminsearch to solve this minimization problem, but from Mathworks I get that functions which are suitable inputs for fminsearch are defined like this (an example):
square = #(x) x.^2
So in my case I could use a vector p=[a, b, c] as the value to minimize, but then I don't know how to define the remaining part of the function. As you can see the number of possible values for the index i is huge, so I cannot simply sum everything together explicitly, but I need to represent the summation in some way. If I write the function somewhere else then I am forced to use symbolic calculus for a, b and c (declaring them with syms) and I'm not sure fminsearch would accept that.
What can I do? Of course if fminsearch turns out to be unfeasible for my situation I accept links to use something else.
The most general solution is to use x and y in the definition of the objective function:
>> objfun = #(p) sum( p(1).*x + p(2).*y + p(3) );
>> optp = fminsearch( objfun, po, ... );