formatting of prime factorization algorithm - matlab

suppose we have following script for prime factorization
z=input('enter your number : ');
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
str = [num2str(ii) '^' num2str(s) ];
disp(str) ;
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits
if z == 1
break
end
end
end
but output of this code is not formatted well,for instance
>> integer_factorization
enter your number : 30
2^1
3^1
5^1
how can i do so that i got
30=2^1*3^1*5^1?
thanks in advance

This is fairly straightforward: Use fprintf(''); instead to print/display the factors.
z=input('enter your number : ');
ans='' %the final answer string
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
str = [num2str(ii) '^' num2str(s) ];
%disp(str) ;
strcat(ans,'*',str); %concats the * str as per requirement.
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits
if z == 1
break
end
end
end
ans=ans(2:end); % to remove the first *
fprintf(ans); % can even use the disp() function.
So, basically, added a string to append the factors into it and display at the end, outside of the loops.

You can simply create a string and add your numbers to the string and finally print the string. something as follow:
z=input('enter your number : ');
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
str = str + [num2str(ii) '^' num2str(s) '*' ];%only update
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits
if z == 1
break
end
end
str = str(0,str.size -1) %use proper command to remove the last * from your string result
disp(str) ; %display the str at the end in one line
end

Litle modification of your code.
z=input('enter your number : ');
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
str += [num2str(ii) '^' num2str(s) ];
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits
if z == 1
break
else
str+='*';
end
end
end
disp(str);

This could work! Just with a few changes to your code
z=input('enter your number : ');
str=[num2str(z) '='];
first=0;
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
if first==0
str=[str num2str(ii) '^' num2str(s)];
first=1;
else
str=[str '*' num2str(ii) '^' num2str(s)];
if z == 1
break
end
end
end
end

first of all thanks everyone for your afford, here is my final solution
z=input('enter your number : ');
string='';
for ii=2:z
s=0;
while z/ii==floor(z/ii) % check if z is divisible by ii
z=z/ii;
s=s+1;
end
if s>0
str =[num2str(ii) '^' num2str(s) ];
string=strcat(string,str);
string= strcat(string,'*');
% If z = 1, no more divisions are necessary,
% thus breaks the loop and quits
if z == 1
break
end
end
end
string=string(1:end-1);% remove last sign of multiplicaiton
fprintf('prime factorization is %s\n',string);
here is several examples
>> integer_factorization
enter your number : 30
prime factorization is 2^1*3^1*5^1
another
>> integer_factorization
enter your number : 35
prime factorization is 5^1*7^1
and last one
>> integer_factorization
enter your number : 100
prime factorization is 2^2*5^2

Related

Deflation in eigenvalue and eigenvector computation

Using this method, I should be able to get eigenvalues by getting the greatest value in each iteration.
But, what my code enables to get is only the first eingenvalue (and not necessarily the greatest) and I don't know where is the problem.
function [Vect,Vp]=PID(A,precision)
nbVal= 50;
[n,m]=size(A);
X=zeros(n,1);
X(1,1)=1;
Vect=zeros(n,min(n,nbVal));
Vp=zeros(1,min(n,nbVal));
XG=zeros(1,n);
j=1;
for i=1:min(nbVal,n)
Y = rand(n,1);
while (max(abs(Y/norm(Y)-X/norm(X))>=precision))
X=Y/norm(Y);
Y=A*X;
end
Vect(:,i)=X;
% To prevent a division by 0
while (X(j,1)==0 && j<=n)
j = j + 1;
end
if X(j,1)~=0
Vp(1,i) =Y(j,1)/X(j,1);
end
% Wielandt Deflation
YG= rand(1,n);
while (max(abs(YG/norm(YG)-XG/norm(XG)))>=precision )
XG=YG/norm(YG);
YG=XG*A;
end
A2=A-Vp(1,i)*(X*XG)/(XG*X);
A=A2;
end
end

Implementing finding alghoritm with for loops and fmincon function

I am trying to implement this alghoritm for finding a new constraint:
In my case we take only 3 natural numbers i.e 1,2, 3.
The sets associated with those natural numbers are M1, M2 and M3. Instead of the Newton Method in II(2), I chose a solver provided by Matlab fmincon.
Here is my code that is not working!
function[s_new]= checking2(M1,M2,M3,x)
M1=linspace(0,1,10)';
M2=linspace(0,1,100)';
M3=linspace(0,1,1000)';
bool1=0;
eta = 10^-8;
pocz=[];
max=-100;
x = [0.1,0.1]'; % warunek poczÄ…tkowy
A = [];
b = [];
Aeq = [];
beq = [];
Set=[0,1];
g = #(x,s) 5*x(1).^2.*sin(pi.*sqrt(s))./(1+s.^2) - x(2);
g_new = #(s) -g(x,s);
for i=1:length(M1)
if g(x,M1(i,:))>eta
s_new=M1(i,:);
bool1=1;
end
end
if ~bool1
for i=1:length(M1)
if g(x,M1(i,:))>max
pocz=M1(i,:);
max=g(x,M1(i,:));
end
end
if max<-eta
bool1=1;
end
end
if ~bool1
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,min(Set),max(Set));
if g(x,s_maybe)>eta
s_new=s_maybe;
bool1=1;
end
end
if ~bool1
for i=1:length(M2)
if g(x,M2(i,:))>eta
s_new=M2(i,:);
bool1=1;
end
end
end
if ~bool1
for i=1:length(M2)
if g(x,M2(i,:))>max
pocz=M2(i,:);
max=g(x,M2(i,:));
end
end
if max<-eta
bool1=1;
end
end
if ~bool1
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,min(Set),max(Set));
if g(x,s_maybe)>eta
s_new=s_maybe;
bool1=1;
end
end
if ~bool1
for i=1:length(M3)
if g(x,M3(i,:))>eta
s_new=M3(i,:);
bool1=1;
end
end
end
if ~bool1
s_new = 1;
end
disp(s_new);
The problem is:
Undefined function or variable 's_new'.
Error in checking2 (line 70)
disp(s_new);
So basically everything might be wrong, but I suppose it is something with fmincon.
EDIT:
The purpose of the alghoritm is to find a minimum of an objective function f(x), satisfying all the constraints g(x,s)<=0 for all s in S, where S is an infinite set (some interval in our case).
What my alghoritm does, at first it takes some finite subset of S and calculates the minimum of f on this set, then I am trying to update S with some s_new. This alghoritm that I am trying to implement is exactly the procedure for creating s_new. Then if it works properly, I will add s_new to my subset and calculate the minimum on the new set, and so on until g(x,s)<=eta, where eta is a small number.
I rewrite the algorithm, read through the comments
clc
clear
lb = 0;
ub = 1;
% Given
l = 3;
M1=linspace(lb,ub,10)';
M2=linspace(lb,ub,100)';
M3=linspace(lb,ub,1000)';
% one boolean value for each Matrix
bool = zeros(1,3);
eta = 10^-8;
% Used as fmincon initial starting guess
pocz = nan;
% Used to store the new finding s that fits all the conditions
s_new = nan;
% Fixed x
x = [0.1,0]';
% fmincon linear constraints
A = [];
b = [];
Aeq = [];
beq = [];
% Main function
g = #(x,s) 5*x(1).^2*sin(pi*sqrt(s))/(1+s.^2) - x(2);
% Optimization concerns s only, don't include x as x is fixed
g_new = #(s) -g(x,s);
% Assuming the maximum is reached at the upper bound, used in(II)(2)
max_s = ub;
maxfun = g(x, max_s);
% Use a cell, for each iteration use a specific matrix M
M = {M1, M2, M3};
for j = 1: length(M)
% used in (II)(1)
check = 0;
step = 1;
% (I) step 1
for i = 1:length(M{j})
% Stopping criteria
if g(x, M{j}(i)) > eta
s_new = M{j}(i);
bool(j) = 1;
break;
else
% Function maximum value for next step (II)
if maxfun < g(x, M{j}(i))
maxfun = g(x, M{j}(i));
% To be used in fmincon as pocz
max_s = M{j}(i);
end
end
% To be used in (II)(1)
if maxfun < -eta
check = 1;
end
end
% End of (I)
% Put (II)(1) here step 2
if ~bool(j) && check
step = step + 1;
% Stopping criteria
if step >= l
disp('S_new not defined');
break;
end
% otherwise go to the next M
end
% (II)(2) step 3
if ~bool(j)
step = step + 1;
if maxfun >= -eta && maxfun <= eta
pocz = max_s;
bool(j) = 1;
end
end
%% EDIT: if bool(j) changed to if ~bool(j)
% (II)(2) Continue
if ~bool(j)
s_maybe = fmincon(g_new,pocz,A,b,Aeq,beq,lb,ub);
% End of (II)(2)
% (II)(2)-1 step 4
step = step + 1;
if g(x, s_maybe) > eta
s_new = s_maybe;
bool(j) = 1;
end
% End of (II)(2)-1
end
% Put (II)(2) here step 5
if ~bool(j)
step = step + 1;
% Stopping criteria
if step >= l
disp('S_new not defined');
break;
end
% otherwise go to the next M
end
end

Swapping rows in a row echelon

I'm trying to make a program that computes, given any matrix A, its echelon form. Here is my code:
function A = myrref(A)
[m,n]=size(A);
for j=1:min(m,n)
A(j,:) = A(j,:)/A(j,j);
for i = j+1:m
A(i,:)= A(i,:)- A(j,:)*A(i,j);
if A(i,i) == 0
row1=A(i,:);
A(i,:)=A(i+1,:);
A(i+1,:)=row1;
end
end
end
It seems to work almost fine, but I still have a problem when swapping rows. For instance, when trying to get echelon form of matrix A=[1 1 1; 2 2 1; 1 2 2], I obtain [1 1 1; 0.5 1 1; 0 0 -1] which is not what I want. Do I need to add another loop that takes care of the 0.5 in the second row first column?
Firstly, it is simplier to use while loop for j because j is not necessarily growing on each iteration. The leading coefficient is not necessarily located on the main diagonal; when all the elements below the leading 0 are zeros, the leading coefficient position shifts to the right.
Secondly, the leading coefficient should be checked before A(j,:)/A(j,j) (to prevent division by 0)
Thirdly, the temporary is not needed to swap the rows as A([i j],:)= A([j i],:)
swaps the ith and jth rows of A.
Here is my version of myrref:
function A = myrref(A)
[m,n]=size(A);
j= 1; % the row index of the leading coefficient position
k= 1; % the column index of the leading coefficient position
while j<m && k<=n
if A(j,k)==0 % we need to change the row order
zeroindex= find(A(j+1:end,k)~=0); % find nonzero elements below A(j,k)
if isempty(zeroindex)
k= k+1; % there is no such elements; shift to the right
else
% swap the rows
A([j zeroindex(1)+j],:)= A([zeroindex(1)+j j],:);
end
else
A(j,:) = A(j,:)/A(j,k);
for i= j+1:m
A(i,:)= A(i,:)- A(j,:)*A(i,k);
end
j= j+1; k= k+1;
end
end
Just as #percusse said you need to finish the loop also your pivot should only go to m-1
Edit: Added an initial pivot based on #AVK's comment
function A = myrref(A)
[m,n]=size(A);
for i = 1:m-1
if A(i,i) == 0
row1=A(i,:);
A(i,:)=A(i+1,:);
A(i+1,:)=row1;
end
end
for j=1:min(m,n)
A(j,:) = A(j,:)/A(j,j);
for i = j+1:m
A(i,:)= A(i,:)- A(j,:)*A(i,j);
end
for i = j+1:m-1
if A(i,i) == 0
row1=A(i,:);
A(i,:)=A(i+1,:);
A(i+1,:)=row1;
end
end
end

MATLAB displaying a table [duplicate]

I want to use MATLAB's printmat do display a matrix with labels. But this doesn't work for complex numbers:
N = 5;
x = rand(N,1);
y = rand(N,1);
z = x + 1i*y;
printmat([x,y,z],'fftdemo','N=1 2 3 4 5','x y x+iy');
Output:
fftdemo =
x y x+iy
N=1 0.84072 0.34998 0.84072
2 0.25428 0.19660 0.25428
3 0.81428 0.25108 0.81428
4 0.24352 0.61604 0.24352
5 0.92926 0.47329 0.92926
As you can see the imaginary part of z isn't printed.
Is there a way to get Matlab to display complex numbers or another way to achieve this?
Any print function in matlab will only print real value of imaginary number. TO get both the parts you must call them explicitly.So correct usage would be
printmat([x,y,real(z),imag(z)],'fftdemo','N=1 2 3 4 5','x y x iy');
But this wont be of any use now since both are parts are getting printed twice.
Here is a slightly altered version of printmat that will print complex numbers. Feel free to fiddle around a bit more with it for better looks :)
function [] = printmat2(a,name,rlab,clab)
%PRINTMAT Print matrix with labels.
% PRINTMAT(A,NAME,RLAB,CLAB) prints the matrix A with the row labels
% RLAB and column labels CLAB. NAME is a string used to name the
% matrix. RLAB and CLAB are string variables that contain the row
% and column labels delimited by spaces. For example, the string
%
% RLAB = 'alpha beta gamma';
%
% defines 'alpha' as the label for the first row, 'beta' for the
% second row and 'gamma' for the third row. RLAB and CLAB must
% contain the same number of space delimited labels as there are
% rows and columns respectively.
%
% PRINTMAT(A,NAME) prints the matrix A with numerical row and column
% labels. PRINTMAT(A) prints the matrix A without a name.
%
% See also: PRINTSYS.
% Clay M. Thompson 9-24-90
% Copyright 1986-2002 The MathWorks, Inc.
% $Revision: 1.10 $ $Date: 2002/04/10 06:32:35 $
error(nargchk(1,4,nargin));
space = ' ';
[nrows,ncols] = size(a);
if nargin<2, name = []; end
if nargin==3, error('Wrong number of input arguments.'); end
if nargin<4,
rlab = []; clab = [];
for i=1:nrows, rlab = [rlab, sprintf('--%d--> ',i)]; end
for i=1:ncols, clab = [clab, sprintf('--%d--> ',i)]; end
rlab=rlab(1:length(rlab)-1);
clab=clab(1:length(clab)-1);
end
col_per_scrn=5;
len=12;
if (nrows==0)|(ncols==0),
if ~isempty(name), disp(' '), disp(sprintf('%s = ',name)), end
disp(' ')
disp(' []')
disp(' ')
return
end
% Remove extra spaces (delimiters)
ndx1 = find(clab==' ');
ndx2 = find([ndx1,0]==[-1,ndx1+1]);
if ~isempty(clab), clab(ndx1(ndx2))=[]; end
ndx1 = find(rlab==' ');
ndx2 = find([ndx1,0]==[-1,ndx1+1]);
if ~isempty(rlab), rlab(ndx1(ndx2))=[]; end
% Determine position of delimiters
cpos = find(clab==' ');
if length(cpos)<ncols-1, error('Not enough column labels.'); end
cpos = [0,cpos,length(clab)+1];
rpos = find(rlab==' ');
if length(rpos)<nrows-1, error('Not enough row labels.'); end
rpos = [0,rpos,length(rlab)+1];
col=1;
n = min(col_per_scrn-1,ncols-1);
disp(' ')
if ~isempty(name), disp(sprintf('%s = ',name)), end % Print name
while col<=ncols
% Print labels
s = space(ones(1,len+1));
for j=0:n,
lab = clab(cpos(col+j)+1:cpos(col+j+1)-1);
if length(lab)>len,
lab=lab(1:len);
else
lab=[space(ones(1,len-length(lab))),lab]; end
s= [s,' ',lab];
end
disp(setstr(s))
for i=1:nrows,
s = rlab(rpos(i)+1:rpos(i+1)-1);
if length(s)>len, s=s(1:len); else s=[space(ones(1,len-length(s))),s]; end
s = [' ',s];
for j=0:n,
element = a(i,col+j);
if imag(element) ~= 0
s=[s,sprintf('%12.5f + %12.5fi',[real(element) imag(element)])];
else
if element==0,
s=[s,' 0'];
elseif (element>=1.e6)|(element<=-1.e5)|(abs(element)<.0001)
s=[s,sprintf(' %12.5e',element)];
else
s=[s,sprintf(' %12.5f',element)];
end
end
end
disp(s)
end % for
col = col+col_per_scrn;
disp(' ')
if (ncols-col<n), n=ncols-col; end
end % while
% end printmat

Break a given MATLAB string into array of sections

Suppose I have the following string:
%%
a = 2
%%
a =3
%%
t = 0:.1:pi*4;
y = sin(t);
for k = 3:2:9
%%
y = y + sin(k*t)/k;
if ~mod(k,3)
%%
display(sprintf('When k = %.1f',k));
plot(t,y)
end
end
If you notice the third section has nested sections.
I want the output to be
[ 'a = 2', 'a=3' , 't = 0:.1:pi*4; y = sin(t); for k = 3:2:9 %% y = y + sin(k*t)/k; if ~mod(k,3) %% display(sprintf('When k = %.1f',k)); plot(t,y) end end']
How can achieve this using string manipulation?
The problem is using normal regex with '%%' will break the 3rd section into 3 sections.
Assuming the logic behind this is that you want to keep any loops or conditional statements (for, while, and if) together, then you can check for '%%' but also track the number of loops/conditionals you enter and exit.
If you are going through this line by line, then the code would look like this (where the variable tline is the line of text):
% initialize counters
str_count = 0;
in_loop = 0;
% iterate through text lines
while (tline ~= -1)
% check for the %% marker but only increment string counter if not in a loop
if ~isempty(strfind(tline,'%%')) && (in_loop == 0);
str_count = str_count + 1;
else
% if no %% or in a loop, add the current line to the current string
str_set{str_count} = [str_set{str_count} tline];
% check for "for", "if", or "while" and increment the loop counter if found
if ~isempty(strfind(tline,'for ')) || ~isempty(strfind(tline,'if ')) || ~isempty(strfind(tline,'while '))
in_loop = in_loop + 1;
end
% check for "end" and decrement the loop counter if found
if ~isempty(strfind(tline,'end'));
in_loop = in_loop - 1;
end
end
end
Keep in mind that this uses strfind to look for the for, while, if, and end commands (with spaces after the first three). However, it would also pick up words that had those strings at the end (for example, the line xfor = 1; would be picked up). So you either have to add some extra checks or be careful about how you name the variables -- perhaps a better way of looking for those strings is the best. You should see spaces before the words unless they are the first words, and could add conditions to that effect.