Author Topic: The Julia thread  (Read 5641 times)

0 Members and 1 Guest are viewing this topic.

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: The Julia thread
« Reply #25 on: January 10, 2022, 09:11:56 pm »
Julia likes matrices and it just so happens I have a small Linear Algebra example written for MATLAB.  So, I transmogrified it to run in Julia.  There are a bunch of syntactic differences...

When I wrote the code for MATLAB, I chose to start with a 6x7 matrix where the 7th column was the value vector for the simultaneous equations.  Hence the bit where I have to extract the 7th column.


Code: [Select]

using Printf

# A football stadium has a capacity of 100,000 attendees
# Ticket prices:
# Student  = $25
# Alumni   = $40
# Faculty  = $60
# Public   = $70
# Veterans = $32
# Guests   = $ 0
# A full capacity game netted $4,897,000
# Let S = number of students, A = number of alumni,   F = number of faculty
#     P = number of public,   V = number of veterans, G = number of guests

#      S  A  F  P   V  G =   value
M = [  1  1  1  1   1  1    100000  # total number of attendees
      25 40 60 70  32  0   4897000  # total revenue
       0  1 -1  0   0  0     11000  # 11000 more alumni than faculty
       0  1  0  1 -10  0         0  # public +  alumni = 10 * veterans
      -1  1  1  0   0  0         0  # alumni + faculty = students
       1  0  1  0  -4 -4         0] # faculty + students = 4 (guests + veterans)
A = M[:,1:6]    # extract 6x6 matrix
B = M[:,7]      # extract value column vector
P = (M[2,1:6])' # ticket price by attendee type
R = inv(A)*B    # compute number of attendees by type
T = sum(R)      # check total attendees = 100,000 CHECK
U = P.*R        # total revenue = 4,897,000 CHECK
V = R'.*P       # revenue by attendee type - transpose R from 6x1 to 1x6
                # then do element by element multiplication

labels = ["Students", "Alumni", "Faculty", "Public", "Veterans", "Guests"]
for i in 1:6
    @printf("%-8s %7d @ %2d %7d\n",labels[i],
                                    round(R[i]),
                                    M[2,i],
                                    round(V[i]))
end
@printf("\nTotals   %7d     %8d\n",round(T), round(sum(V)))               


[/font]

Not that it will be efficient on such a small problem but the next step is to shove the computing off to the GPU - just for a drill.
« Last Edit: January 10, 2022, 09:13:43 pm by rstofer »
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14431
  • Country: fr
Re: The Julia thread
« Reply #26 on: January 10, 2022, 09:14:46 pm »
I suggest reading "Chapter 38 - Noteworthy Differences from other Languages" of Julia's documentation.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: The Julia thread
« Reply #27 on: January 10, 2022, 11:07:01 pm »
I suggest reading "Chapter 38 - Noteworthy Differences from other Languages" of Julia's documentation.

That's up next!  I had a heck of a time learning the ins and outs - Google is my friend!  I am certain Julia has an easier way.  MATLAB probably has an easier way as well.  I wrote that code a few years back as a tutorial with all the steps commented and such.  It's a start!  Kind of the "Hello World" of Linear Algebra.

I'll get to that reference in the next day or two.  I just wanted some output.

FWIW, I wrote the code using VS Code with the Julia plug-in.  Among other things VS Code provides a terminal for the REPL functionality.  Very handy for checking things like matrix size and values.

« Last Edit: January 10, 2022, 11:11:47 pm by rstofer »
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14431
  • Country: fr
Re: The Julia thread
« Reply #28 on: January 10, 2022, 11:35:50 pm »
Oh sure, there's a myriad ways of achieving the same, some more or less optimized and more or less "idiomatic". The doc is 1300+ pages. But I find it quite readable so far.
Just for fun, a small example of defining a type, with an associated iterator, custom indexing, and showing multiple dispatch.

Code: [Select]
using Plots, Statistics

struct DiscreteFunc
func::Function
interval::Tuple{Number, Number}
n::Int
end

StepX(df::DiscreteFunc) = (df.interval[2] - df.interval[1]) / df.n

Base.iterate(df::DiscreteFunc, state = 0) = state >= df.n ? nothing : ((x = df.interval[1] + state*StepX(df); (x, df.func(x))), state + 1)

Base.length(df::DiscreteFunc) = df.n

function Base.getindex(df::DiscreteFunc, i::Int)
1 <= i <= df.n || throw(BoundsError(df, i))
x = df.interval[1] + (i - 1)*StepX(df)
return (x, df.func(x))
end

Base.firstindex(df::DiscreteFunc) = 1
Base.lastindex(df::DiscreteFunc) = df.n

VectX(df::DiscreteFunc) = [P[1] for P in df]
VectY(df::DiscreteFunc) = [P[2] for P in df]

mean(df::DiscreteFunc) = Statistics.mean(VectY(df))

# Examples.
df1 = DiscreteFunc(cos, (0, 2π), 100)

mean(df1)

plot(VectX(df1), VectY(df1))

df2 = DiscreteFunc(x -> x != 0 ? sin(x)/x : 1, (-50, 50), 500)

plot(VectX(df2), VectY(df2))
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: The Julia thread
« Reply #29 on: January 11, 2022, 12:36:13 am »
Some of the differences from MATLAB are profound and likely will lead to much teeth gnashing.  Consider:

Quote
Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well.

I REALLY need to digest these differences!



 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14431
  • Country: fr
Re: The Julia thread
« Reply #30 on: January 11, 2022, 12:56:42 am »
Some of the differences from MATLAB are profound and likely will lead to much teeth gnashing.  Consider:

Quote
Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well.

I REALLY need to digest these differences!

That's a bit like Lua tables.
You can use the copy() function to make a copy: A = copy(B)
(of course, probably not to be abused - in general there may be other ways to achieve the same than having copies of arrays, depends!)

Of course, you'll get a completely new vector if you add elements, for instance:
Code: [Select]
A = [1, 2]
B = [A; 3] # one short way of adding an element to a vector, you get [1, 2, 3], while if using:
B = [A, 3] # you get [[1,2], 3] as expected
# in both cases, of course, A is unmodified if you further modify B
 

Online magic

  • Super Contributor
  • ***
  • Posts: 6748
  • Country: pl
Re: The Julia thread
« Reply #31 on: January 11, 2022, 09:30:32 am »
Some of the differences from MATLAB are profound and likely will lead to much teeth gnashing.  Consider:

Quote
Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well.

I REALLY need to digest these differences!
Yeah, that's not looking good for a dummy-friendly language.
Computer scientists will get it, but mathematicians and physicists not so fast :P
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4026
  • Country: nz
Re: The Julia thread
« Reply #32 on: January 11, 2022, 09:45:04 am »
Some of the differences from MATLAB are profound and likely will lead to much teeth gnashing.  Consider:

Quote
Julia arrays are not copied when assigned to another variable. After A = B, changing elements of B will modify A as well.

I REALLY need to digest these differences!
Yeah, that's not looking good for a dummy-friendly language.
Computer scientists will get it, but mathematicians and physicists not so fast :P

It's no different to C. Or Java. Or Python.

Code: [Select]
$ python -c 'a=[1,2,3,4];b=a;b[2]=42;print a'
[1, 2, 42, 4]

In almost all languages "assigning" an object is actually copying a reference to the object, not the object itself. C++ is one of the few exceptions to this.
 

Online magic

  • Super Contributor
  • ***
  • Posts: 6748
  • Country: pl
Re: The Julia thread
« Reply #33 on: January 11, 2022, 10:12:44 am »
Clearly they are buggy languages, then. Why would assigning something to b have anything to do with my a?

Code: [Select]
> a=[1,2,3,4]; b=a; b(2)=42; a
a =

   1   2   3   4
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4026
  • Country: nz
Re: The Julia thread
« Reply #34 on: January 11, 2022, 11:32:48 am »
Clearly they are buggy languages, then. Why would assigning something to b have anything to do with my a?

Code: [Select]
> a=[1,2,3,4]; b=a; b(2)=42; a
a =

   1   2   3   4

Languages aren't buggy. Programs are.
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4026
  • Country: nz
Re: The Julia thread
« Reply #35 on: January 11, 2022, 11:53:50 am »
Oh, and JavaScript too:

Code: [Select]
$ node -e 'a=[1,2,3,4];b=a;b[2]=42;console.log(a)'
[ 1, 2, 42, 4 ]

And Ruby:

Code: [Select]
$ ruby -e 'a=[1,2,3,4];b=a;b[2]=42;print a,"\n"'
[1, 2, 42, 4]

But you'd like Perl. Maybe it's the true beginner's language?

Code: [Select]
$ perl -e '@a=(1,2,3,4);@b=@a;$b[2]=42;print "@a\n";print "@b\n"'
1 2 3 4
1 2 42 4

 

Offline DiTBho

  • Super Contributor
  • ***
  • Posts: 3894
  • Country: gb
Re: The Julia thread
« Reply #36 on: January 11, 2022, 01:58:31 pm »
Perhaps we should use two different operators
"A ==> B" to assign the object pointer (B points to the same content of A)
"A = B" to allocate a new content area, copy the content from A, and assign the pointer to B
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: The Julia thread
« Reply #37 on: January 11, 2022, 04:06:40 pm »
By itself, it's not a problem.  Most languages try to avoid the copy including Fortran.  Certainly, the copy is wasteful of time and memory if it isn't truly needed.  Where it can become an issue is for those familiar with MATLAB.  Even in MATLAB, the copy operation is controllable with care:

https://www.mathworks.com/help/matlab/matlab_prog/avoid-unnecessary-copies-of-data.html

Pass by value versus pass by reference has been a debate for 70+ years.  By default, Fortran passes by reference and in modern incantations, this can be overridden.  C is pass by value and pointers are explicit.  Clearly, both schemes work and we use both in our daily lives.  We just need to keep it straight.

https://docs.oracle.com/cd/E19957-01/805-4940/z400091044b8

In the end, it's just something to be aware of.  This topic is of great importance in machine learning where the matrices are HUGE.  Copying is to be avoided both in terms of time and space.  We already have to copy the data from CPU memory to GPU memory and bring the results back.  12 GB on a graphics card seems a lot but it's only 1.5 giga qwords.  Start throwing some 10,000x10,000 matrices of qwords around and it fills up fast.  Yet the idea is to keep as much of the math inside GPU space as possible to avoid copying.

« Last Edit: January 11, 2022, 04:08:17 pm by rstofer »
 

Offline SiliconWizardTopic starter

  • Super Contributor
  • ***
  • Posts: 14431
  • Country: fr
Re: The Julia thread
« Reply #38 on: January 11, 2022, 07:14:02 pm »
This is a sane choice indeed.
But it's interesting to see how something that may look as mundane as an "assignment" can mean different things to different people, and in turn to different languages.

And it comes with the now old question of whether using the equal sign for assignments even makes sense.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: The Julia thread
« Reply #39 on: January 11, 2022, 08:10:34 pm »
This is a sane choice indeed.
But it's interesting to see how something that may look as mundane as an "assignment" can mean different things to different people, and in turn to different languages.

And it comes with the now old question of whether using the equal sign for assignments even makes sense.

Niklaus Wirth thought it made no sense and used := for assignment in Pascal as did the authors of Algol.  It makes sense because the operator was described as 'becomes' rather then 'equal'.  Equality is an entirely different concept and symbol '='.  Other languages use '=' and '=='.

Wirth shows up as one of the designers of Algol W in 1966 and later Pascal, Modula, Modula 2, Oberon, Oberon 2 and Oberon-07.   A true luminary!
« Last Edit: January 11, 2022, 08:13:26 pm by rstofer »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf