Zack Fair
Zack Fair

Reputation: 239

Cannot use instance member within property initializer

I have checked the other case on this but lazy var doesn't seem to fix my problem here.

I have this code I am using to solve a certain equation and, once it's solved, I want to return the 2 arrays I get as answers back to my original code in ViewController.swift. The code is given below but, at the line where I try to actually solve the problem with let (dollars1, dollars2) = prob.solveUsingSolver(solver:solveEuler) line. I was initially testing it in the playground with just prob.solveUsingSolver(solver:solveEuler), which solved the problem. But, in the main application, it's giving an "Expected declaration" error. And if I try to assign the outputs to dollars1 and dollars2, I get the

Cannot use instance member 'prob' within property initializer; property initializers run before 'self' is available

import Charts
class ViewController: UIViewController, ChartViewDelegate {
    @IBOutlet weak var lineChartView: LineChartView!
    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Solving the problem
        let wholearray = HE(Th1: 100.0, Tc2: 25.0, deltaZ: 0.1).solveUsingSolver(solver:solveEuler)
        let temp_hot = wholearray.xarray
        let temp_cold = wholearray.varray
        // 1
        self.lineChartView.delegate = self
        // 2
        self.lineChartView.chartDescription?.text = "Tap node for details"
        // 3
        self.lineChartView.descriptionTextColor = UIColor.white
        self.lineChartView.gridBackgroundColor = UIColor.darkGray
        // 4
        self.lineChartView.noDataText = "No data provided"
        // 5
        setChartData(space_dimensionless: space_dimensionless)
    }
    let space_dimensionless = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    typealias Solver = (Double, Double, Double) -> (Array<Double>, Array<Double>)
    struct HE {
        var Th1 = 0.0
        var Tc2 = 0.0
        var deltaZ = 0.0
        init(Th1: Double, Tc2: Double, deltaZ: Double) {
            self.Th1 = Th1
            self.Tc2 = Tc2
            self.deltaZ = deltaZ
        }
        func solveUsingSolver(solver: Solver) {
            solver(Th1, Tc2, deltaZ)
        }
    }
    func solveEuler(Th1: Double, Tc2: Double, z : Double) -> (xarray:Array<Double>, varray:Array<Double>)
    {
        var x = Th1
        var i = 0.0
        var upper = Th1
        var lower = Tc2
        var vold = (lower + upper) / 2
        var v = vold
        var xold = x
        let epsilon = 0.05
        var err = 1.0
        var xarray: [Double] = [0,1,2,3,4,5,6,7,8,9,10]
        var varray: [Double] = [0,1,2,3,4,5,6,7,8,9,10]
        var j=0
        while (err > epsilon) {
            while i < 1 {
                v -= 4*z*i*(xold-vold)
                x -= z*i*(xold-vold)
                xold = x
                vold = v
                i+=z
                xarray[j]=x
                varray[j]=v
                j += 1
            }
            err = abs(varray[10] - Tc2)
            if varray[10] > Tc2 {
                upper = varray[0]
            }
            else {
                lower = varray[0]
            }
            x = Th1
            xold = x
            vold = (lower + upper) / 2
            v = vold
            i=0.0
            j=0
        }
        return (xarray,varray)
    }
    func setChartData(space_dimensionless : [Double]) {
        // 1 - creating an array of data entries
        var yVals1 : [ChartDataEntry] = [ChartDataEntry]()
        for i in 0 ..< space_dimensionless.count {
            yVals1.append(ChartDataEntry(x: space_dimensionless[i], y: temp_hot[i]))
        }
        // 2 - create a data set with our array
        let set1: LineChartDataSet = LineChartDataSet(values: yVals1, label: "Hot Fluid")
        set1.axisDependency = .left // Line will correlate with left axis values
        set1.setColor(UIColor.red.withAlphaComponent(0.5)) // our line's opacity is 50%
        set1.setCircleColor(UIColor.red) // our circle will be dark red
        set1.lineWidth = 2.0
        set1.circleRadius = 0.0 // the radius of the node circle
        set1.fillAlpha = 65 / 255.0
        set1.fillColor = UIColor.red
        set1.highlightColor = UIColor.white
        set1.drawCircleHoleEnabled = false
        // 3 - creating an array of data entries
        var yVals2 : [ChartDataEntry] = [ChartDataEntry]()
        for i in 0 ..< space_dimensionless.count {
            yVals2.append(ChartDataEntry(x: space_dimensionless[i], y: temp_cold[i]))
        }
        // 4 - create a data set with our array
        let set2: LineChartDataSet = LineChartDataSet(values: yVals2, label: "Cold Fluid")
        set2.axisDependency = .left // Line will correlate with left axis values
        set2.setColor(UIColor.blue.withAlphaComponent(0.5)) // our line's opacity is 50%
        set2.setCircleColor(UIColor.blue) // our circle will be dark red
        set2.lineWidth = 2.0
        set2.circleRadius = 0.0 // the radius of the node circle
        set2.fillAlpha = 65 / 255.0
        set2.fillColor = UIColor.blue
        set2.highlightColor = UIColor.white
        set2.drawCircleHoleEnabled = true
        //5 - create an array to store our LineChartDataSets
        var dataSets = [IChartDataSet]()
        dataSets.append(set1)
        dataSets.append(set2)
        let lineChartData = LineChartData(dataSets: dataSets)
        //6 - set our data
        lineChartView.data = lineChartData
        //7 Format chart more
        self.lineChartView.xAxis.drawGridLinesEnabled = false
        self.lineChartView.xAxis.labelPosition = XAxis.LabelPosition.bottom
        self.lineChartView.xAxis.labelFont = UIFont(name: "HelveticaNeue-Light", size: 10.0)!
        self.lineChartView.xAxis.labelTextColor = UIColor.black
        self.lineChartView.xAxis.drawAxisLineEnabled=true
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Upvotes: 0

Views: 2511

Answers (1)

Paulw11
Paulw11

Reputation: 115076

You are declaring two properties, prob and the (dollars1, dollars2) tuple

let prob = HE(Th1: 100.0, Tc2: 25.0, deltaZ: 0.1)
let (dollars1, dollars2) = prob.solveUsingSolver(solver:solveEuler)

but you cannot use a member of prob (the solveUsingSolver function) at this point because self.prob won't have been initialised yet.

You probably want the tuple assignment to be performed in some function.

UPDATE

Your solveUsingSolver function invokes the solver but doesn't return the value from the solver. It should be:

func solveUsingSolver(solver: Solver) -> (Array<Double>, Array<Double>) {
    return solver(Th1, Tc2, deltaZ)
}

Upvotes: 1

Related Questions