# Only scalar quadratic forms can be specified in CVX toolbox

Here is my code:

cvx_begin

variable W(N,I) complex

maximize(a1’Wa1)

subject to

trace(W’*W) <= P;

cvx_end

The error says “Only scalar quadratic forms can be specified in CVX” and it happens at this line “trace(W’*W) <= P;”. I know W is a matrix and this makes this error happens, but i have no good idea how to replace it by a simple and correct code. Do i have to extract each column W(:,l) of W and use “for loop” to sum the W(:,l)'*W(:,l) together?

I will presume you actually mean `trace(W'*W)`. Otherwise, `W*W` is not conformal unless `J = N`. Or if `J` does equal `N`, and you actually do mean `trace(W*W)`, I will assume that `W` is hermitian, otherwise I believe the constraint is non-convex.

`trace(W'*W) = square_pos(norm(W,'fro'))`

But it is numerically better not to square, so use the constraint
`norm(W,'fro') <= sqrt(P)`

Yes, it really works. In my simulation, W is a complex matrix with dimension N*J and N is not equal to J, so only W’*W is well-defined. I have another question. I want to use diag(W’*W) in cvx, so how to write it as a compact form? (since W’W is a JJ matrix, and diag is to extract all the diagonal elements of W’*W and put it as a column vector)

I now see that you did have `W'*W` in your original post.

As for `diag(W'*W)`, that can be formulated as
`square_pos(norms(W',2,2))`
or
`square_pos(norms(W))'`
+++++++++++++++
help norms

norms Computation of multiple vector norms.
norms( X ) provides a means to compute the norms of multiple vectors
packed into a matrix or N-D array. This is useful for performing
max-of-norms or sum-of-norms calculations.

``````All of the vector norms, including the false "-inf" norm, supported
by NORM() have been implemented in the norms() command.
norms(X,P)           = sum(abs(X).^P).^(1/P)
norms(X)             = norms(X,2).
norms(X,inf)         = max(abs(X)).
norms(X,-inf)        = min(abs(X)).
If X is a vector, these computations are completely identical to
their NORM equivalents. If X is a matrix, a row vector is returned
of the norms of each column of X. If X is an N-D matrix, the norms
are computed along the first non-singleton dimension.

norms( X, [], DIM ) or norms( X, 2, DIM ) computes Euclidean norms
along the dimension DIM. norms( X, P, DIM ) computes its norms
along the dimension DIM.

Disciplined convex programming information:
norms is convex, except when P<1, so an error will result if these
non-convex "norms" are used within CVX expressions. norms is
nonmonotonic, so its input must be affine.
``````

Thanks! I have tried norms(W), it really gives me a row vector which is indeed the norm-2 of each column of W. But i test the square_pos function in Matlab (without cvx), for example, square_pos(b). It is not the square of each element in b. Let me show your my test code and result

I also test this square_pos function in cvx (I set a breakpoint when my codes run into cvx), it still gives me the same answer. Here is the result

So i am wondering whether square_pos(norms(W))’ will return the same result as diag(W’*W)

The variable name is “a”, not “b”, sorry bro.

My guess is that you have the `square` from the Signal Processing Toolbox installed, and that is getting called by CVX’s `square_pos` instead of CVX’s `square` (see 2nd to last paragraph below for explanation).

On my machine,
which -all square_pos
C:\cvx_2.2.2\functions\square_pos.m
C:\cvx_2.2.2\functions@cvx\square_pos.m % cvx method

The first of these is supposed to be called when called with a numeric argument, whether or not interspersed between other CVX statements. You can look at the source code and see that it is basically returning `square( max( x, 0 ) )`, which would explain your results if the “wrong” `square` is being called.

The second of these is called for CVX expression (or CVX variable) argument. This does not use `square`, and perhaps is doing the “correct” thing for CVX, despite your having a non-CVX `square`. The code I suggested in my preceding post would be using this version of `square_pos`, because its argument is a CVX expression.

I use “help square_pos”, it returns this thing,

it is max( x, 0 ).^2.
Besides, i use “which” to search the position of the square_pos function, it returns this thing

On the other hand, i use “help square”, it says this function is introduced into the Signal Processing Toolbox, and this “square function” generates a square wave.

So do i need to remove the Signal Processing Toolbox to make the square_pos work properly?

i think, but am not 100% sure, `square_pos` when applied to a CVX expression or variable argument will work correctly.

To get `square_pos` to work correctly when applied to a numeric argument, you could change the line
`y = square( max( x, 0 ) ); `
to
`y = max(x,0).^2;`
in
`cvx\functions\square_pos.m`

It really works after i replace this code y = square( max( x, 0 ) ); by y = max(x,0).^2;. Thank you very much!