Carl Love

Carl Love

28095 Reputation

25 Badges

13 years, 100 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are answers submitted by Carl Love

Looks like you have some hybrid Mathematica/Maple syntax. Maple uses round parentheses instead of square brackets. The command for extracting the real part of an expression is a combination of evalc and Re:

evalc(Re(sqrt(x+I*y)));

The evalc tells Maple to assume that all variables are real. The Re alone wouldn't return the above answer because that assumption wouldn't have yet been made.

Here is the algorithm coded in Maple and a test instance. Any advice on how I can do more of the Matrix operations inplace would be much appreciated.

 

Fuzzy C-Means Clustering

restart:

FuzzyCMeans:= proc(
     X::Matrix,   #The rows of X are the data points.
     #number of clusters and number of means:
     {clusters::And(posint, satisfies(x-> x > 1)):= 2},
     {fuzziness::satisfies(x-> x > 1):= 2},   #fuzziness factor
     {epsilon::positive:= 1e-4},   #convergence criterion
     {max_iters::posint:= 999},   #max number of iterations
     {Norm::procedure:= (x-> LinearAlgebra:-Norm(x,2))}
)
option `Written by Carl J Love, 2016-Apr-11`;
description
    "Fuzzy C-Means clustering algorithm.
     see http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/cmeans.html
     and https://en.wikipedia.org/wiki/Fuzzy_clustering
    "
;
uses LA= LinearAlgebra;
local
     c:= clusters,     #number of clusrters and number of menas
     m:= fuzziness,    #fuzziness factor
     n:= op([1,1], X), #number of points
     d:= op([1,2], X), #dimension
     N:= Norm,
     #U[i,j] is the degree (on a 0..1 scale) to which point i belongs to cluster j.
     U:= Matrix((n,c), datatype= float[8]),
     #U1 is just an update copy of U.
     U1:= LA:-RandomMatrix((n,c), generator= 0..1, datatype= float[8]),
     C:= Matrix((c,d), datatype= float[8]), #The rows of C are the cluster centers.
     e:= 2/(m-1),
     i, j, k, jj, #loop indices
     UM # U^~m
;
     for jj to max_iters while LA:-Norm(U-U1, infinity) >= epsilon do
          U:= copy(U1);
          UM:= U^~m;
          for j to c do
               C[j,..]:= add(UM[i,j].X[i,..], i= 1..n) / add(UM[i,j], i= 1..n)
          end do;
          U1:= Matrix(
               (n,c),
               (i,j)-> 1/add((N(X[i,..]-C[j,..])/N(X[i,..]-C[k,..]))^e, k= 1..c),
               datatype= float[8]
          )
     end do;
     if jj > max_iters then error "Didn't converge" end if;
     userinfo(1, FuzzyCMeans, "Used", jj, "iterations.");
     (C,U1)                
end proc:

#Test data:
X:=
     [[5.37,19.50],[5.73,19.44],[4.66,20.03],[5.66,20.38],[4.22,21.97],
      [5.08,20.67],[5.08,19.08],[4.54,20.06],[4.35,19.82],[5.19,20.72],
      [4.48,19.95],[5.76,19.81],[4.15,18.68],[6.37,20.60],[5.58,21.13],
      [5.76,19.91],[5.85,19.02],[5.00,19.71],[5.42,20.31],[4.77,21.45],
      [8.61,19.48],[10.70,20.31],[10.99,20.28],[11.68,21.28],[9.12,20.77],
      [10.30,20.07],[10.40,21.62],[10.95,20.34],[9.79,20.29],[9.69,20.86],
      [10.02,21.45],[11.05,20.19],[9.20,17.96],[10.49,19.88],[9.61,19.49],
      [10.33,19.59],[9.29,20.94],[10.17,19.64],[10.97,20.32],[10.08,19.16]
     ]
:
XM:= Matrix(X, datatype= float[8]):


infolevel[FuzzyCMeans]:= 1:

(C,U):= FuzzyCMeans(
     XM,
     #All options are set to their default values here:
     clusters= 2, fuzziness= 2, epsilon= 1e-4, max_iters= 999,
     Norm= (x-> LinearAlgebra:-Norm(x,2))
);

FuzzyCMeans: Used 9 iterations.

 

C, U := Matrix(2, 2, {(1, 1) = 5.17624062133678, (1, 2) = 20.0938323603206, (2, 1) = 10.2161889439051, (2, 2) = 20.2331395528376}), Vector(4, {(1) = ` 40 x 2 `*Matrix, (2) = `Data Type: `*float[8], (3) = `Storage: `*rectangular, (4) = `Order: `*Fortran_order})

(1)

#Plot. First separate points into clusters:
(CL1,CL2):= selectremove(i-> U[i,1] > U[i,2], [$1..nops(X)]):
plots:-display(
     [plot(
          map(CL-> XM[CL,..], [CL1,CL2]), color= [red, green],
          style= point, symbol= diagonalcross, symbolsize= 16
      ),
      plot(
          `[]`~(convert(C, listlist)), color= [red, green],
          style= point, symbol= circle, symbolsize= 32
      )
     ], gridlines= false
 );

 

 

 

Download Fuzzy_clusters.mw

You want

plot(eval(C, k= k/K), k= 0*K..4*K, labels= ['K', 'C']);

 

You can't have more than one independent variable in an ODE system that is solved by dsolve. You have x and y as independent variables.

Use the bits option of Bits:-Split. For example,

mb:= Bits:-Split~(convert(message, bytes), bits= 8);

You need a multiplication sign:

g:= x-> exp(x^2*(x-a));

This is done by computing the exclusive-or (xor) of the two bit strings and counting the ones in the result.

CountOnes:= proc(n::nonnegint)
local q:= n, c:= 0;
     while q > 0 do  c:= c+irem(q,2,'q') end do;
     c
end proc:
 
CountFlips:= (X::{list, Matrix, Vector}, Y::{list, Matrix, Vector})->
     CountOnes(Bits:-Xor((Bits:-Join@convert)~([X,Y], list)[]))
:

CountFlips(<1,0,0,0,0,0,0,0>, <1,1,1,1,0,0,1,1>);

     5

Change your definition of B_interp to

B_interp:= (sr, e_g)->
     CurveFitting:-ArrayInterpolation(
          [SR, E_G], Vert_Coef, [[sr], [e_g]], method= linear
     )[1,1]
:

 

You want to use Matrices instead of subscripted names. It'll be much faster. Then your code will look like this:

restart:
dellT:= 0:  h:= 1:
tile:= Matrix(150$2, datatype= float[8]):
#You'll need to fill the above matrix with initial values.
tile2:= Matrix(tile):
to 20 do    
     for j from 2 to 149 do
          for k from 2 to 149 do  
               tile2[j,k]:= dellT/h^2*(tile[j+1,k]-4*tile[j,k]+tile[j-1,k]+tile[j,k-1])+tile[j,k]  
          end do
     end do;  
     tile:= copy(tile2)
end do:

Assuming that you'll be generating a lot of these pairs, you'll want to avoid regenerating the generating procedure, which is inefficient. This can be done with a module.

GenXY:= module()
local
     R:= RandomTools:-Generate(list(integer(range= 1..7), 2), makeproc),
     ModuleApply:= proc()
     local x:= 0, y:= 0;
          while x=y do  (x,y):= R()[]  end do;
          (min(x,y), max(x,y))
     end proc
;
end module:
     
(x,y):= GenXY();

                           
   2, 7


This Answer is essentially the same as John's, but uses a Vector of lists instead of a list of lists. You could also use a Vector of Vectors or a Matrix. The best format to store the data should be determined by how many times you do these shifting operations. Shifting operations on lists are inefficient.

block:= < [0,0,1,1,0,0,1],[0,0,1,1,1,0,0],[0,1,0,1,0,1,0],[1,0,0,1,1,1,0]>;

block:= ArrayTools:-CircularShift(block, 1);

plots:-display(
     plots:-pointplot3d([[0,0,12]], color= red, symbolsize= 24),
     plots:-spacecurve([4*t,-2*t,2*t], t= 0..10, thickness= 4),
     axes= boxed
);

So, is f3 the result (or one of the results) of a dsolve(..., numeric) computation? And you want to compute the integrals a31 and a32 after doing the dsolve, right? Shouldn't that f3(x) be f3(theta)?

Assuming that the answers to those questions are yes and that you've correctly extracted the f3 from the dsolve solution, then you compute the second integral with

a32:= evalf(Int(unapply(chi*g3/(1-f3(theta)*g3)^4, theta), a..1));

And likewise for the first integral.

@mskalsi

[Edit: This is an Answer to the OP's followup question posted as a Reply to my first Answer below.]

Yes, that can be done in a loop, like this:

 

M := Matrix([[v[1], v[2], v[3], -epsilon*v[1]+v[4]], [v[1], v[2], -epsilon*v[1]+v[3], -3*epsilon*v[2]+v[4]], [v[1], epsilon*v[1]+v[2], v[3], 2*epsilon*v[3]+v[4]], [exp(epsilon)*v[1], exp(3*epsilon)*v[2], exp(-2*epsilon)*v[3], v[4]]])

M := Matrix(4, 4, {(1, 1) = v[1], (1, 2) = v[2], (1, 3) = v[3], (1, 4) = -epsilon*v[1]+v[4], (2, 1) = v[1], (2, 2) = v[2], (2, 3) = -epsilon*v[1]+v[3], (2, 4) = -3*epsilon*v[2]+v[4], (3, 1) = v[1], (3, 2) = epsilon*v[1]+v[2], (3, 3) = v[3], (3, 4) = 2*epsilon*v[3]+v[4], (4, 1) = exp(epsilon)*v[1], (4, 2) = exp(3*epsilon)*v[2], (4, 3) = exp(-2*epsilon)*v[3], (4, 4) = v[4]})

(1)

J:= [0,4,1,2,3]:

G[0]:= add(a[k]*v[k], k= 1..4);

a[1]*v[1]+a[2]*v[2]+a[3]*v[3]+a[4]*v[4]

(2)

for j from 2 to nops(J) do
     k:= J[j];
     F[k]:= expand(t[k]*G[J[j-1]]);
     for ii to 4 do for jj to 4 do
          F[k]:= expand(algsubs(t[ii]*v[jj]= M[ii,jj], F[k]))
     od od;
     G[k]:= expand(subs(epsilon= E[k], F[k]))
od;

4

 

t[4]*a[1]*v[1]+t[4]*a[2]*v[2]+t[4]*a[3]*v[3]+t[4]*a[4]*v[4]

 

a[4]*v[4]+a[3]*v[3]/(exp(E[4]))^2+a[2]*(exp(E[4]))^3*v[2]+a[1]*exp(E[4])*v[1]

 

1

 

t[1]*a[4]*v[4]+t[1]*a[3]*v[3]/(exp(E[4]))^2+t[1]*a[2]*(exp(E[4]))^3*v[2]+t[1]*a[1]*exp(E[4])*v[1]

 

a[4]*v[4]+a[1]*exp(E[4])*v[1]-a[4]*E[1]*v[1]+a[3]*v[3]/(exp(E[4]))^2+a[2]*(exp(E[4]))^3*v[2]

 

2

 

t[2]*a[4]*v[4]+t[2]*a[1]*exp(E[4])*v[1]-t[2]*a[4]*E[1]*v[1]+t[2]*a[3]*v[3]/(exp(E[4]))^2+t[2]*a[2]*(exp(E[4]))^3*v[2]

 

a[4]*v[4]-a[4]*E[1]*v[1]-3*a[4]*E[2]*v[2]+a[1]*exp(E[4])*v[1]+a[2]*(exp(E[4]))^3*v[2]+a[3]*v[3]/(exp(E[4]))^2-a[3]*E[2]*v[1]/(exp(E[4]))^2

 

3

 

t[3]*a[4]*v[4]-t[3]*a[4]*E[1]*v[1]-3*t[3]*a[4]*E[2]*v[2]+t[3]*a[1]*exp(E[4])*v[1]+t[3]*a[2]*(exp(E[4]))^3*v[2]+t[3]*a[3]*v[3]/(exp(E[4]))^2-t[3]*a[3]*E[2]*v[1]/(exp(E[4]))^2

 

a[4]*v[4]+a[2]*(exp(E[4]))^3*v[2]+2*a[4]*E[3]*v[3]-3*a[4]*E[2]*v[2]+a[1]*exp(E[4])*v[1]+a[3]*v[3]/(exp(E[4]))^2+(exp(E[4]))^3*v[1]*a[2]*E[3]-3*a[4]*E[2]*E[3]*v[1]-a[4]*E[1]*v[1]-a[3]*E[2]*v[1]/(exp(E[4]))^2

(3)

 

Download Loopwise.mw

 

You need to add the word identity:

solve(identity(f(t), t), {a,b});

First 231 232 233 234 235 236 237 Last Page 233 of 395