Enforcing a rule in a symbolic expression in Matlab - matlab

I have already asked the same question in the Matlab user community.
I have the following symbolic expression:
(3*s11)/2 + (3*s12)/2 + (3*s13)/2 + (3*s14)/2 + (3*s15)/2 + (s11*s12)/2 + (s11*s13)/2 + (s11*s14)/2 + (s12*s13)/2 + (s11*s15)/2 + (s12*s14)/2 + (s12*s15)/2 + (s13*s14)/2 + (s13*s15)/2 + (s14*s15)/2 + s11^2/4 + s12^2/4 + s13^2/4 + s14^2/4 + s15^2/4 + 9/4
It is stored as a symbolic expression variable. I would like to enforce the rule sij^2 = 1 i.e. the variables can be either -1 or +1. If I enforce the rule in the expression mentioned above, the expression will be as follows.
(3*s11)/2 + (3*s12)/2 + (3*s13)/2 + (3*s14)/2 + (3*s15)/2 + (s11*s12)/2 + (s11*s13)/2 + (s11*s14)/2 + (s12*s13)/2 + (s11*s15)/2 + (s12*s14)/2 + (s12*s15)/2 + (s13*s14)/2 + (s13*s15)/2 + (s14*s15)/2 + 1/4 + 1/4 + 1/4 + 1/4 + 1/4 + 9/4
How can I do this in Matlab?

Set assumptions e.g. assume(s14^2==1), then use simplify.

Related

HTML String on Object Property Won't Update

I have an object constructor that sets some properties, and later uses them to concatenate a string to write to the DOM. I can see that this works in some cases, but not in others.
function Fighter(name, level, attackPts, defencePts, imgSource) {
// TRUNCATED PROPERTY ASSIGNMENTS AREA:
this.attackPts = attackPts;
this.defencePts = defencePts;
// DOM ELEMENT CONSTRUCTORS:
this.img = "style='background: #444 url(" + imgSource + ") no-repeat center'";
this.char_card_name = "<h3>" + this.name + "</h3>";
this.char_card_hitdef = "<h4>" + this.attackPts + "/" + this.defencePts + "</h4>";
this.char_card = "<div class='fighter " + faction + "' " + "id='" + this.name + "'>" + this.img + this.char_card_name + this.char_card_hitdef + "</div>";
In a game function later on I modify the attack and defense points for this "Fighter" object, and that works as expected, and my console.log() tests verify that the concatenated properties also update . . . . up until the final string to pull it all together and display:
this.char_card = "<div class='fighter " + faction + "' " + "id='" + this.name + "'>" + this.img + this.char_card_name + this.char_card_hitdef + "</div>";
When I log this property, those attack and defense numbers don't budge, even though they update successfully in the previous property, this.char_card_hitdef
What could I be overlooking here? I crawled all over the web looking for scope or variable reference issues, but my log statements bring me right back to this one pinching point.
Because you are still in the constructor, you need to refer to the variables without this. that are a parameter AND property of the Object Fighter.
So change
this.char_card = "<div class='fighter " + faction + "' " + "id='" + this.name + "'>" + this.img + this.char_card_name + this.char_card_hitdef + "</div>";
to
this.char_card = "<div class='fighter " + faction + "' " + "id='" + name + "'>" + this.img + this.char_card_name + this.char_card_hitdef + "</div>"
And all other properties that refer to properties above them.
You can read more about constructors here

Find fit with custom equation in Matlab

I'm trying to find a fit with a custom equation, but I keep getting errors and don't know why. The custom equation is really big. I'm using what I found here.
This is the code (sorry about the length of the custom equation):
myfittype = fittype('a + (b*2*y) + (c*2*x+dsqrt(6)(2*xy)) + (esqrt(3)*(2*x^2+2*y^2-1)) + (fsqrt(6)(x^2-y^2)) + (gsqrt(8)(3*x^2*y-y^3)) + (hsqrt(8)(3*x^2*y+3*y^3-2*y)) + (ipsqrt(8)(x^3+3*x*y^2-2*x)) + (jpsqrt(8)(x^3-3*xy^2)) + (ksqrt(10)*(4*x^3*y-4*xy^3)+lsqrt(10)*(8*x^3*y+8*x*y^3-6*xy)) + (msqrt(5)*(6*x^4+12*x^2*y^2+6*y^4-6*x^2-6*y^2+1)) + (nsqrt(10)(4*x^4+4*x^2*y^2-3*x^2-4*x^2*y^2-4*y^4+3*y^2)) + (osqrt(10)(x^4-6*x^2*y^2+y^4)) + (psqrt(12)(5*x^4*y-10*x^2*y^3+y^5)) + (qsqrt(12)(15*x^4*y-12*x^2*y-5*y^5+4*y^3+10*x^2*y^3)) + (rsqrt(12)(10*x^4*y+20*x^2*y^3+10*y^5-12*x^2*y-12*y^3+3*y)) + (ssqrt(12)(10*x^5+20*x^3*y^2+10*x*y^4-12*x^3-12*x*y^2+3*x)) + (tsqrt(12)(5*x^5-10*x^3*y^2-4*x^3-15*x*y^4+12*xy^2)) + (usqrt(12)*(x^5-10*x^3*y^2+5*x*y^4))',... 'independent',{'x'},'dependent',{'y'},...
'coefficients',{'a','b','c','d','e','f','g','h','ip','jp','k','l','m','n','o','p','q','r','s','t','u'})
Here is the code formatted with line breaks (...) so that you can read it:
myfittype = fittype('a + (b*2*y) + (c*2*x+d*sqrt(6)*(2*x*y)) + ...
(e*sqrt(3)*(2*x^2+2*y^2-1)) + (f*sqrt(6)*(x^2-y^2)) + ...
(g*sqrt(8)*(3*x^2*y-y^3)) + (h*sqrt(8)*(3*x^2*y+3*y^3-2*y)) + ...
(ip*sqrt(8)*(x^3+3*x*y^2-2*x)) + (jp*sqrt(8)*(x^3-3*x*y^2)) + ...
(k*sqrt(10)*(4*x^3*y-4*x*y^3)+l*sqrt(10)*(8*x^3*y+8*x*y^3-6*x*y)) + ...
(m*sqrt(5)*(6*x^4+12*x^2*y^2+6*y^4-6*x^2-6*y^2+1)) + ...
(n*sqrt(10)*(4*x^4+4*x^2*y^2-3*x^2-4*x^2*y^2-4*y^4+3*y^2)) + ...
(o*sqrt(10)*(x^4-6*x^2*y^2+y^4)) + (p*sqrt(12)*(5*x^4*y-10*x^2*y^3+y^5)) + ...
(q*sqrt(12)*(15*x^4*y-12*x^2*y-5*y^5+4*y^3+10*x^2*y^3)) + ...
(r*sqrt(12)*(10*x^4*y+20*x^2*y^3+10*y^5-12*x^2*y-12*y^3+3*y)) + ...
(s*sqrt(12)*(10*x^5+20*x^3*y^2+10*x*y^4-12*x^3-12*x*y^2+3*x)) + ...
(t*sqrt(12)*(5*x^5-10*x^3*y^2-4*x^3-15*x*y^4+12*x*y^2)) + ...
(u*sqrt(12)*(x^5-10*x^3*y^2+5*x*y^4))', ...
'independent',{'x'},'dependent',{'y'}, ...
'coefficients', ...
{'a','b','c','d','e','f','g','h','ip','jp','k','l','m','n','o','p','q','r','s','t','u'})
The error says this expression is not a valid matlab expression
Hope you can help me, thanks.
I run your code :
The problem of your code is that
Coefficient d does not appear in the equation expression.

Bug in 2D Fourier Transform implementation

I am trying to implement a 2D DFT using a combination of 1D DFT in Matlab. When comparing my results against Matlab's inbuilt function (fft2) I realized that I have the following issues:
The sign of the imaginary part is being inverted. i.e + changed to - and vice versa.
The rows are being ordered in descending order except for the first one.
This image shows the comparison between the two results. The red numbers on the side are there to indicate the reordering issue.
My code is as follows:
x = imread('img.png');
x = double(x);
x = x(1:12,1:5)
% FFT
Xw = complex(zeros(size(x)));
for row = 1:size(x,1)
Xw(row,:) = fft(x(row,:));
end
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col)');
end
Could someone kindly indicate where my problem is please? Thanks
The ' operator is for the complex transpose, which means that the matrix is transposed and the conjugate of the values is taken. This means that the signs of the complex values are reversed. You don't notice this with real numbers because technically, the imaginary component is zero.
You want to use .' instead to preserve the sign of the imaginary component as performing the intermediate FFT per row will result in complex values. Using just ' will change the imaginary components of the intermediate results, which will give you the wrong results:
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col).');
end
BTW, as a minor note, there is no need to transpose the intermediate columns of your result at all. If you provide a single vector, fft will operate along the first non-singleton dimension, and so using a transpose is superfluous. It would actually help if you didn't transpose your result at all:
for col = 1:size(x,2)
Xw(:,col) = fft(Xw(:,col));
end
Here's an example. I've generated a random 10 x 10 matrix:
rng(123);
x = rand(10);
Using your code with correcting the transpose (and without the indexing at the beginning), we get:
>> Xw
Xw =
Columns 1 through 5
50.1429 + 0.0000i -0.4266 - 0.2624i 0.8803 + 0.9311i -0.0526 + 1.7067i 0.7187 + 0.7161i
0.5066 - 2.4421i 2.7551 - 1.7421i -1.9994 + 0.6052i 0.2891 + 3.4182i 0.5300 + 2.4417i
0.1956 + 0.1790i 4.1461 + 1.9648i -1.3781 - 1.0303i -0.6872 - 1.0103i -1.2184 - 0.5783i
-0.3645 - 1.6193i -1.8470 - 1.3445i 4.1555 + 0.7432i 2.3707 + 3.8265i -1.9526 + 1.9464i
-3.1136 - 0.3704i 2.4132 - 1.0795i -0.2255 + 1.3062i 0.8436 - 0.5157i -0.3493 - 0.9994i
-1.5962 + 0.0000i -0.3780 - 1.4055i 1.6242 - 0.4842i 0.4457 + 0.4718i -0.1794 - 2.0014i
-3.1136 + 0.3704i 0.0134 + 0.1267i 1.0630 + 1.4563i -0.8864 - 0.3174i -0.5720 + 1.3041i
-0.3645 + 1.6193i 0.7028 + 0.2797i 0.1064 + 2.0705i 2.1644 + 0.1685i 0.3095 + 0.7426i
0.1956 - 0.1790i 2.3511 + 2.1440i 0.7301 - 0.8264i -1.1974 - 0.3794i -2.4981 + 1.2363i
0.5066 + 2.4421i -3.5897 + 0.7444i 1.2191 - 3.6386i -2.9659 - 1.6626i -2.0339 + 0.0880i
Columns 6 through 10
2.0373 + 0.0000i 0.7187 - 0.7161i -0.0526 - 1.7067i 0.8803 - 0.9311i -0.4266 + 0.2624i
-1.8782 - 0.9047i -2.0339 - 0.0880i -2.9659 + 1.6626i 1.2191 + 3.6386i -3.5897 - 0.7444i
2.3752 + 1.8811i -2.4981 - 1.2363i -1.1974 + 0.3794i 0.7301 + 0.8264i 2.3511 - 2.1440i
4.5213 + 0.9237i 0.3095 - 0.7426i 2.1644 - 0.1685i 0.1064 - 2.0705i 0.7028 - 0.2797i
-1.2259 + 2.1690i -0.5720 - 1.3041i -0.8864 + 0.3174i 1.0630 - 1.4563i 0.0134 - 0.1267i
6.2411 + 0.0000i -0.1794 + 2.0014i 0.4457 - 0.4718i 1.6242 + 0.4842i -0.3780 + 1.4055i
-1.2259 - 2.1690i -0.3493 + 0.9994i 0.8436 + 0.5157i -0.2255 - 1.3062i 2.4132 + 1.0795i
4.5213 - 0.9237i -1.9526 - 1.9464i 2.3707 - 3.8265i 4.1555 - 0.7432i -1.8470 + 1.3445i
2.3752 - 1.8811i -1.2184 + 0.5783i -0.6872 + 1.0103i -1.3781 + 1.0303i 4.1461 - 1.9648i
-1.8782 + 0.9047i 0.5300 - 2.4417i 0.2891 - 3.4182i -1.9994 - 0.6052i 2.7551 + 1.7421i
I've also verified that this works without transposing. You'll get the same thing as if you were to perform .'. Now, using fft2, we get:
>> Xw2 = fft2(x)
Xw2 =
Columns 1 through 5
50.1429 + 0.0000i -0.4266 - 0.2624i 0.8803 + 0.9311i -0.0526 + 1.7067i 0.7187 + 0.7161i
0.5066 - 2.4421i 2.7551 - 1.7421i -1.9994 + 0.6052i 0.2891 + 3.4182i 0.5300 + 2.4417i
0.1956 + 0.1790i 4.1461 + 1.9648i -1.3781 - 1.0303i -0.6872 - 1.0103i -1.2184 - 0.5783i
-0.3645 - 1.6193i -1.8470 - 1.3445i 4.1555 + 0.7432i 2.3707 + 3.8265i -1.9526 + 1.9464i
-3.1136 - 0.3704i 2.4132 - 1.0795i -0.2255 + 1.3062i 0.8436 - 0.5157i -0.3493 - 0.9994i
-1.5962 + 0.0000i -0.3780 - 1.4055i 1.6242 - 0.4842i 0.4457 + 0.4718i -0.1794 - 2.0014i
-3.1136 + 0.3704i 0.0134 + 0.1267i 1.0630 + 1.4563i -0.8864 - 0.3174i -0.5720 + 1.3041i
-0.3645 + 1.6193i 0.7028 + 0.2797i 0.1064 + 2.0705i 2.1644 + 0.1685i 0.3095 + 0.7426i
0.1956 - 0.1790i 2.3511 + 2.1440i 0.7301 - 0.8264i -1.1974 - 0.3794i -2.4981 + 1.2363i
0.5066 + 2.4421i -3.5897 + 0.7444i 1.2191 - 3.6386i -2.9659 - 1.6626i -2.0339 + 0.0880i
Columns 6 through 10
2.0373 + 0.0000i 0.7187 - 0.7161i -0.0526 - 1.7067i 0.8803 - 0.9311i -0.4266 + 0.2624i
-1.8782 - 0.9047i -2.0339 - 0.0880i -2.9659 + 1.6626i 1.2191 + 3.6386i -3.5897 - 0.7444i
2.3752 + 1.8811i -2.4981 - 1.2363i -1.1974 + 0.3794i 0.7301 + 0.8264i 2.3511 - 2.1440i
4.5213 + 0.9237i 0.3095 - 0.7426i 2.1644 - 0.1685i 0.1064 - 2.0705i 0.7028 - 0.2797i
-1.2259 + 2.1690i -0.5720 - 1.3041i -0.8864 + 0.3174i 1.0630 - 1.4563i 0.0134 - 0.1267i
6.2411 + 0.0000i -0.1794 + 2.0014i 0.4457 - 0.4718i 1.6242 + 0.4842i -0.3780 + 1.4055i
-1.2259 - 2.1690i -0.3493 + 0.9994i 0.8436 + 0.5157i -0.2255 - 1.3062i 2.4132 + 1.0795i
4.5213 - 0.9237i -1.9526 - 1.9464i 2.3707 - 3.8265i 4.1555 - 0.7432i -1.8470 + 1.3445i
2.3752 - 1.8811i -1.2184 + 0.5783i -0.6872 + 1.0103i -1.3781 + 1.0303i 4.1461 - 1.9648i
-1.8782 + 0.9047i 0.5300 - 2.4417i 0.2891 - 3.4182i -1.9994 - 0.6052i 2.7551 + 1.7421i
We can show these two are equal by ensuring that all of the element-wise differences between the two matrices is less than a small threshold... say 1e-10:
>> all(abs(Xw(:)-Xw2(:)) <= 1e-10)
ans =
1
Take away message
Never use ' for the transpose.... ever. Luis Mendo is a strong advocate of this very fact.

Simplifying Boolean Expression (A'BC) + (A'B'C) + (A'BC) + (AB'C)

please help me with simplifying this one. I am a bit new to these..
(A'BC') + (A'B'C) + (A'BC) + (AB'C)
the book i use shows and answer, which is,
Answer = A'B + B'C
I tried simplifying, but I get stucked with two eXors, my simplification so far goes like this...
(A'BC') + (A'B'C) + (A'BC) + (AB'C)
A (BC' + B'C) + C (A'B + AB')
This doesn't seem to be a write way, Please someone help me simplify this, and please show step by step, as I am sort of new..
Also I don't get how to simplify eXor further..
You have the Rule X' + X = True. SO
(A'BC') + (A'B'C) + (A'BC) + (AB'C) =
(A'BC') + (A'BC) + (A'B'C) + (AB'C) = // just permuting the terms
A'B(C' + C) + (A' + A)B'C = // factoring
A'B + B'C
I'll assume that multiplcation is AND, addition is OR and prime is negation.
Here's what I'd do:
(A'BC') + (A'B'C) + (A'BC) + (AB'C)
A'B(C'+C) + B'C(A'+A)
(C'+C) = 1 and (A'+A) = 1
A'B + B'C
Q.E.D.
for simplifying boolean expressions use karnaugh maps. i think it is very much useful if we less number of variables. but if we have more variables then we can follow methods because this method is not that preferable.
(A'BC') + (A'B'C) + (A'BC) + (AB'C)
answer just arrange the terms like this
step 1:A'BC'+A'BC+AB'C+A'B'C
now get common terms out
step 2 : A'B(C'+C)+B'C(A+A')
step 3 : A'B.1+B'C.1
step 4 : A'B+B'C

How to figure out eigenvalues of a matrix in matlab when all entries of matrix are variables?

I have a matrix with a bunch of unknown constants such as the one below:
a*b -c -d 0
-c e -a -b-d
-d -a d -e
0 -b-d -e a
As you may realize it is symmetric about the diagonal and therefore, the diagonal values are all positive. All constants are greater than 0.
I would like to solve this for the eigenvalues in matlab. How would I go about doing this? I do not know the values a,b,c,d, and e. I would like to do something like this:
d = eig(#getMatrix)
but the eig function does not accept function handles.
No problem in MATLAB.
>> syms a b c d e
>> M = [a*b -c -d 0
-c e -a -b-d
-d -a d -e
0 -b-d -e a];
>> eig(M)
ans =
a/4 + d/4 + e/4 + (a*b)/4 - ((51*a*d^3)/16 - (117*a^4*b)/16 + (27*a^3*d)/16 + (27*a*e^3)/16 + (57*b*d^3)/2 + (27*a^3*e)/16 + (27*d*e^3)/16 + (51*d^3*e)/16 + 6*((4*(2*b*d - (a*e)/4 - (a*d)/4 - (d*e)/4 - (a^2*b)/4 + (11*a^2)/8 + b^2 + c^2 + (19*d^2)/8 + (11*e^2)/8 + (3*a^2*b^2)/8 - (a*b*d)/4 - (a*b*e)/4)*((17*a*d^3)/64 - (39*a^4*b)/64 + (9*a^3*d)/64 + (9*a*e^3)/64 + (19*b*d^3)/8 + (9*a^3*e)/64 + (9*d*e^3)/64 + (17*d^3*e)/64 + (45*a^4)/256 + (285*d^4)/256 + (45*e^4)/256 - (a^2*b^2)/16 + (a^2*b^3)/8 + (3*a^2*b^4)/16 + (31*a^4*b^2)/128 + (a^4*b^3)/64 - (3*a^4*b^4)/256 + (3*a^2*c^2)/16 + (15*a^2*d^2)/128 - (9*a^2*e^2)/128 + (19*b^2*d^2)/16 - (b^2*e^2)/16 + (3*c^2*d^2)/16 + (15*c^2*e^2)/16 +
...
(a*b*c^2*e)/8 + (3*a*b*d*e^2)/64 + (11*a*b*d^2*e)/64 + (a*b^2*d*e)/4 - (33*a^2*b*d*e)/32 - (5*a^2*b^2*d*e)/64 + (a*b*d*e)/4 + (a*c*d*e)/2 - 2*b*c*d*e) - 256*((17*a*d^3)/64 - (39*a^4*b)/64 + (9*a^3*d)/64 + (9*a*e^3)/64 + (19*b*d^3)/8 + (9*a^3*e)/64 + (9*d*e^3)/64 + (17*d^3*e)/64 + (45*a^4)/256 + (285*d^4)/256 + (45*e^4)/256 - (a^2*b^2)/16 + (a^2*b^3)/8 + (3*a^2*b^4)/16 + (31*a^4*b^2)/128 + (a^4*b^3)/64 - (3*a^4*b^4)/256 + (3*a^2*c^2)/16 + (15*a^2*d^2)/128 - (9*a^2*e^2)/128 + (19*b^2*d^2)/16 - (b^2*e^2)/16 + (3*c^2*d^2)/16 + (15*c^2*e^2)/16 + (15*d^2*e^2)/1...
Output truncated. Text exceeds maximum line length of 25,000 characters for Command Window display.
I deleted a lot there. Admittedly, its rather messy and lengthy, but can you really expect better?
Edit: I should comment that such a long extended formula may be dangerous in terms of computational accuracy. I've seen people blindly use such a mess of an expression, evaluating it in Fortran or MATLAB. They think that because it is "symbolic" that it is also exact. This is a total fallacy when numerical computations are done.
There may well be immense subtractive cancellation in those terms, with huge positive and negative terms almost canceling each other out, leaving a tiny result that is essentially worthless because of the limited dynamic range of floating point computations. BEWARE. At the very least, compare single and double precision computations done with the same expression. If they differ by any significant amount, try an extended precision version to verify there is not a problem for the doubles. If you have not tested such an expression and verified it extensively, don't trust it.