Grouping like terms in MATLAB - matlab

I'm trying to code a program that solves systems of equations in MATLAB. I was wondering if there is a way to get MATLAB to group like terms and put their coefficients into a matrix? I realize that I can just enter the coefficients in by hand but I want to hopefully repurpose this small program to perform nodal analysis.

You could always use my sympoly tools to do much of the work for you. Since this set of tools will give you direct access to the parsed result, this will make your life easier, as well as do much symbolic manipulation of an expression. For example...
>>sympoly x y z
>> P = 3*x + 2*x*y - 2.75*z^2
P =
-2.75*z^2 + 3*x + 2*x*y
>> struct(P)
ans =
Var: {'x' 'y' 'z'}
Exponent: [3x3 double]
Coefficient: [3x1 double]
>> P.Exponent
ans =
0 0 2
1 0 0
1 1 0
>> P.Coefficient
ans =
-2.75
3
2
Find sympoly on the file exchange.

It would be easy enough to write a parser in order to do this functionality yourself. Parse out the number and then the variable with its power. Good luck.

Related

Matlabs "splitapply" used on functions with multiple parameters

I don't understand matlabs splitapply function:
>> f=#(t,x) sum(sum(t),sum(x))
f =
function_handle with value:
#(t,x)sum(sum(t),sum(x))
>> splitapply(f,[1,0;0,0],[1,1;2,2],1:2)
ans =
1 0
I expected the two matrices to be split into columns and the two first columns fed to f, resulting in a total sum of 4=(1+0)+(1+2). Then both the second columns should be fed to f, resulting in the number 3=(0+0)+(1+2).
So I expected
ans =
4 3
But quite obviously that is not what happend. And I am not sure why. If I use splitapply on functions with only one argument, it seems to do what I expect:
>> splitapply(#sum,[1,1;2,3],1:2)
ans =
3 4
I would be glad if someone could point out what is happening. This is the documentation if someone else can understand it better than me: https://de.mathworks.com/help/matlab/ref/splitapply.html
You probably want
f = #(t,x) sum([sum(t) sum(x)])
or
f = #(t,x) sum(t)+sum(x)
rather than
f = #(t,x) sum(sum(t), sum(x))
The latter is interpreted as compute the sum of sum(t) along the dimension given by sum(x).
With this correction,
>> f = #(t,x) sum([sum(t) sum(x)]);
>> splitapply(f,[1,0;0,0],[1,1;2,2],1:2)
ans =
4 3

Why are multiple, consecutive plusses allowable syntax in MATLAB?

Does anyone know why this works in MATLAB?
>> 1 ++ 2
ans =
3
Coming from coding in C, python, Java etc, I find it most counterintuitive that this should work at all. Presumably there's something important about the parser that I don't understand?
There's a difference between plus and uplus. I suspect MATLAB takes the first + as plus, and all the others as uplus. Since uplus is by default just "return what's behind", you add 1 and 2, and use a lot of "return what's behind" in between.
a=2;
c=+a % unitary plus
c =
2
1+2 % addition
ans =
3
1+++2 % addition and two uplusses
ans =
3
The reason uplus exists is to allow operator overloading in classes. The same works in other languages, e.g. in C#, to allow for operator overloading in confined classes.
The other reason mentioned in that C# thread is that is changes unsigned shorts to integers, which is not the case for MATLAB:
d=uint8(1)
d =
uint8
1
+d
ans =
uint8
1
a=+d
a =
uint8
1
It does, however, convert a boolean to a double, thanks to Cris Lunego for pointing that out:
+true
ans =
1
+false
ans =
0
The following however remains a mystery to me, inspired by Sanjay Manohar's comment:
>> [1 ++ 2]
ans =
1 2 % Two unary plusses
>> [1 + + 2]
ans =
3 % A normal plus and a unary one
>> [1++2]
ans =
3 % A normal plus and a unary one
The same works with multiple plusses, [1 +++..+++ 2], so with all plusses consecutively in the middle generates [1 2], all other combinations (as far as I tested) result in 3. I asked a separate question about this: Why do the plus and unary plus behave strange in array syntax?

How to assign values to variables in a handle function?

This is simplified but take as an example the following MATLAB function handle:
F = #(x)[x(1)-x(2);x(2)-x(3)]
The system has of course has many solutions. Is it possible to obtain a solution for a function like this one after substituting at least one variable? For example, substituting x(3)=1 the function would become:
G = #(x)[x(1)-x(2);x(2)-1]
And a solution for the other variables can be obtained. I use fsolve and it works quite well for the system of equations I have. Of course what I need to do can be done using the Symbolic Toolbox, but calling it in a big for loop makes it too slow to use for my code.
I'm trying to come up with some code that can return G given F and a set of indices in x to replace with given values.
What you're basically asking to do is have G call F with values in x reassigned based on a logical replacement index index and a set of replacement values values, which is doable but messy since anonymous functions can only have a single executable statement.
The solution is similar to what is done in this answer, but instead of using the functional form for subscripted reference we'll need to use the functional form for subscripted assignment: subsasgn. Here's what it would look like:
F = #(x)[x(1)-x(2); x(2)-x(3)];
values = [3 2 1];
index = logical([0 0 1]);
G = #(x) F(subsasgn(x, struct('type', '()', 'subs', {{index}}), values(index)));
And here's a test:
>> F([3 2 3])
ans =
1
-1
>> F([3 2 1]) % Replace the last element by 1
ans =
1
1
>> G([3 2 3]) % G handles replacing the last element by 1
ans =
1
1

[Octave]Trouble visualising how to write a row vector of exponents

as the title states, I was following a guideline on coding a polynomial regression function but I am currently stuck on what it means to write a row vector of exponents. I need to initialise two variables, one being 'vector1', a column vector of a variable 'X', and 'vector2' which is meant to be a row vector of exponents from 1 to 'p'. Once that's done, I'm supposed to fill it in the bsxfun as such "X_poly = bsxfun(#power, vector1, vector2)".
Now the problem arises when I try to write in vector2. I have trouble visualising how to write this code. I've tried "vector2 = X(1:p,:)", "vector2 = X*p", "vector2 = X'(1:p,:)". Obviously none of these worked and I just feel this strong sense of defeat everytime I get it wrong. I've tried googling but the results have yielded no fruition.
I feel very lost and I'm grasping at straws at this point.
You don't need to use bsxfun here, the power function (and its equivalent operator .^) is vectorised (i.e. it can accept arrays process them in an element-wise manner).
octave:1> v1 = 1:10;
octave:2> v2 = 1:10;
octave:3> v1 .^ v2
ans =
1 4 27 256 3125 46656 8.2354e+05 1.6777e+07 3.8742e+08 1e+10
octave:4> power(v1,v2)
ans =
1 4 27 256 3125 46656 8.2354e+05 1.6777e+07 3.8742e+08 1e+10
octave:5> bsxfun(#power, v1, v2)
ans =
1 4 27 256 3125 46656 8.2354e+05 1.6777e+07 3.8742e+08 1e+10

Large matrix for surface plot?

I'm somewhat new to MATLAB and I'm trying to make a large matrix structured very much like the following example:
C=[1,2,3]
n=[-3,0,3]
X=[f(1,-3),f(1,0),f(1,3);f(2,-3),f(2,0),f(2,3);f(3,-3),f(3,0),f(3,3)]
where f is some function of the values in C and n. I need this sort of matrix, X, so that I can make a surface graph of surf(C,n,X). The issue is that, in my real problem, I need a 51x51 matrix, and I don't know how to make such a matrix without typing out everything (which would be a horrific task).
Could someone please help me understand how to make such a plot? Thank you so much!
Have a look at ndgrid:
>> [ii,jj] = ndgrid(C,n)
ii =
1 1 1
2 2 2
3 3 3
jj =
-3 0 3
-3 0 3
-3 0 3
Then you can get X very easily if f operates element-wise on non-scalar inputs:
X = f(ii,jj);
If f can only take a pair of scalars, try arrayfun:
X = arrayfun(#(x,y)f(x,y),ii,jj);
(Or modify f!)
X = f(C'*ones(1, 51), ones(51, 1)*n))