Carl Love

Carl Love

28095 Reputation

25 Badges

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

MaplePrimes Activity


These are answers submitted by Carl Love

Here's your program translated into Maple. You'll notice that it's much shorter than the Matlab version.



restart:

line:= proc(Pt1::[realcons,realcons], Pt2::[realcons,realcons])
global Lines;
     Lines[Pt1,Pt2]:= ()
end proc:

Point:= proc(x::realcons, y::realcons)
global Points;
     Points[x,y]:= ()
end proc:

Rand:= RandomTools:-Generate(float(range= 0..1, method= uniform), makeproc):

# Firstly, set the size limit for the grid, which shall define how many

# points there are in both the vertical and horizontal direction

size:= 40;


# Iteration through x, using the line function to create a number of

# horizontal lines up to the limit point

 

for x to size do  line([0, size], [x, x])  end do:

 

# Now iterating through the diagonals, using two sets of

# lines, both starting from the line going through the origin. The first

# iterates through the lines that pass through positive x values at y=0,

# the second iterates through the lines passing through negative x values

# at y=0

# d must be increased by 2 each time to ensure that equilateral triangles

# are formed.

 

for d from 0 by 2 to size do
     #Upward diagonals

     line([d, size], [0, size-d]); line([0, size-d], [d, size]);

     #Downward diagonals:

     line([d, 0], [0, d]); line([size, d], [d, size])

end do:

 

# The program now iterates through potential y values for the potential

# points. Then it tests the value of y to see what orientation the lattice

# is at that point, then randomly selects x values to enter, iterating

# between all the possible x values in the orientation before moving on to

# the next y value.

 

for y from 0.5 by 0.5 while y<size do
     (i,s):= `if`(frem(y,1)=.5, [0,1], `if`(frem(y,2)=1, [0,2], [1,2]))[];
     seq(`if`(Rand() > 0.5, Point(x,y), [][]), x= i..size-1, s)

end do:

40

(1)

plots:-display(
     [plot([indices(Lines)], thickness= 0, color= gray),
      plot(
          [indices(Points)],
          style= point, symbol= soliddiamond, symbolsize= 1, color= red
      )], gridlines= false
);

 

 

NULL


Download Lattice.mw

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

 

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