-
Notifications
You must be signed in to change notification settings - Fork 5
/
radical.go
150 lines (125 loc) · 4.45 KB
/
radical.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package mlpack
/*
#cgo CFLAGS: -I./capi -Wall
#cgo LDFLAGS: -L. -lmlpack_go_radical
#include <capi/radical.h>
#include <stdlib.h>
*/
import "C"
import "gonum.org/v1/gonum/mat"
type RadicalOptionalParam struct {
Angles int
NoiseStdDev float64
Objective bool
Replicates int
Seed int
Sweeps int
Verbose bool
}
func RadicalOptions() *RadicalOptionalParam {
return &RadicalOptionalParam{
Angles: 150,
NoiseStdDev: 0.175,
Objective: false,
Replicates: 30,
Seed: 0,
Sweeps: 0,
Verbose: false,
}
}
/*
An implementation of RADICAL, a method for independent component analysis
(ICA). Assuming that we have an input matrix X, the goal is to find a square
unmixing matrix W such that Y = W * X and the dimensions of Y are independent
components. If the algorithm is running particularly slowly, try reducing the
number of replicates.
The input matrix to perform ICA on should be specified with the "Input"
parameter. The output matrix Y may be saved with the "OutputIc" output
parameter, and the output unmixing matrix W may be saved with the
"OutputUnmixing" output parameter.
For example, to perform ICA on the matrix X with 40 replicates, saving the
independent components to ic, the following command may be used:
// Initialize optional parameters for Radical().
param := mlpack.RadicalOptions()
param.Replicates = 40
ic, _ := mlpack.Radical(X, param)
Input parameters:
- input (mat.Dense): Input dataset for ICA.
- Angles (int): Number of angles to consider in brute-force search
during Radical2D. Default value 150.
- NoiseStdDev (float64): Standard deviation of Gaussian noise. Default
value 0.175.
- Objective (bool): If set, an estimate of the final objective function
is printed.
- Replicates (int): Number of Gaussian-perturbed replicates to use (per
point) in Radical2D. Default value 30.
- Seed (int): Random seed. If 0, 'std::time(NULL)' is used. Default
value 0.
- Sweeps (int): Number of sweeps; each sweep calls Radical2D once for
each pair of dimensions. Default value 0.
- Verbose (bool): Display informational messages and the full list of
parameters and timers at the end of execution.
Output parameters:
- outputIc (mat.Dense): Matrix to save independent components to.
- outputUnmixing (mat.Dense): Matrix to save unmixing matrix to.
*/
func Radical(input *mat.Dense, param *RadicalOptionalParam) (*mat.Dense, *mat.Dense) {
params := getParams("radical")
timers := getTimers()
disableBacktrace()
disableVerbose()
// Detect if the parameter was passed; set if so.
gonumToArmaMat(params, "input", input, false)
setPassed(params, "input")
// Detect if the parameter was passed; set if so.
if param.Angles != 150 {
setParamInt(params, "angles", param.Angles)
setPassed(params, "angles")
}
// Detect if the parameter was passed; set if so.
if param.NoiseStdDev != 0.175 {
setParamDouble(params, "noise_std_dev", param.NoiseStdDev)
setPassed(params, "noise_std_dev")
}
// Detect if the parameter was passed; set if so.
if param.Objective != false {
setParamBool(params, "objective", param.Objective)
setPassed(params, "objective")
}
// Detect if the parameter was passed; set if so.
if param.Replicates != 30 {
setParamInt(params, "replicates", param.Replicates)
setPassed(params, "replicates")
}
// Detect if the parameter was passed; set if so.
if param.Seed != 0 {
setParamInt(params, "seed", param.Seed)
setPassed(params, "seed")
}
// Detect if the parameter was passed; set if so.
if param.Sweeps != 0 {
setParamInt(params, "sweeps", param.Sweeps)
setPassed(params, "sweeps")
}
// Detect if the parameter was passed; set if so.
if param.Verbose != false {
setParamBool(params, "verbose", param.Verbose)
setPassed(params, "verbose")
enableVerbose()
}
// Mark all output options as passed.
setPassed(params, "output_ic")
setPassed(params, "output_unmixing")
// Call the mlpack program.
C.mlpackRadical(params.mem, timers.mem)
// Initialize result variable and get output.
var outputIcPtr mlpackArma
outputIc := outputIcPtr.armaToGonumMat(params, "output_ic")
var outputUnmixingPtr mlpackArma
outputUnmixing := outputUnmixingPtr.armaToGonumMat(params, "output_unmixing")
// Clean memory.
cleanParams(params)
cleanTimers(timers)
// Return output(s).
return outputIc, outputUnmixing
}